Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YQL-17388: fix use-after-free bug in TPgResolvedMultiCall::TListValue::TIterator #955

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions ydb/library/yql/parser/pg_wrapper/comp_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,14 @@ class TReturnSetInfo {
}

~TReturnSetInfo() {
Free();
}

void Free() {
if (!Ptr) {
return;
}

if (Ref().expectedDesc) {
FreeTupleDesc(Ref().expectedDesc);
}
Expand All @@ -471,9 +479,12 @@ class TReturnSetInfo {
}

TWithDefaultMiniKQLAlloc::FreeWithSize(Ptr, sizeof(ReturnSetInfo));
Ptr = nullptr;
}

ReturnSetInfo& Ref() {
Y_ENSURE(Ptr, "ReturnSetInfo is dead");

return *static_cast<ReturnSetInfo*>(Ptr);
}

Expand All @@ -488,11 +499,21 @@ class TExprContextHolder {
}

ExprContext& Ref() {
Y_ENSURE(Ptr, "TExprContextHolder is dead");

return *Ptr;
}

~TExprContextHolder() {
Free();
}

void Free() {
if (!Ptr) {
return;
}
FreeExprContext(Ptr, true);
Ptr = nullptr;
}

private:
Expand Down Expand Up @@ -739,9 +760,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {
}

~TIterator() {
if (TupleSlot) {
ExecDropSingleTupleTableSlot(TupleSlot);
}
FinishAndFree();
}

private:
Expand All @@ -766,7 +785,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {
} else {
YQL_ENSURE(!StructType);
if (RSInfo.Ref().isDone == ExprEndResult) {
IsFinished = true;
FinishAndFree();
return false;
}

Expand All @@ -782,7 +801,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {

bool CopyTuple(NUdf::TUnboxedValue& value) {
if (!tuplestore_gettupleslot(RSInfo.Ref().setResult, true, false, TupleSlot)) {
IsFinished = true;
FinishAndFree();
return false;
}

Expand Down Expand Up @@ -835,6 +854,17 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {
}
}

void FinishAndFree() {
if (TupleSlot) {
ExecDropSingleTupleTableSlot(TupleSlot);
TupleSlot = nullptr;
}
RSInfo.Free();
ExprContextHolder.Free();

IsFinished = true;
}

const std::string_view Name;
TUnboxedValueVector Args;
const TVector<NPg::TTypeDesc>& ArgDesc;
Expand Down
16 changes: 3 additions & 13 deletions ydb/library/yql/tests/postgresql/cases/aggregates.err
Original file line number Diff line number Diff line change
Expand Up @@ -654,12 +654,7 @@ COPY bitwise_test FROM STDIN NULL 'null';
7 7 7 3 4 B1100
\.
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "1"

1 1 1 1 1 B0101
^
Metacommand \. is not supported
<sql-statement>
SELECT
BIT_AND(i2) AS "1",
Expand Down Expand Up @@ -769,12 +764,7 @@ FALSE TRUE null null
null TRUE FALSE null
\.
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "TRUE"

TRUE null FALSE null
^
Metacommand \. is not supported
<sql-statement>
SELECT
BOOL_AND(b1) AS "f",
Expand Down Expand Up @@ -1354,4 +1344,4 @@ drop table p_t1;
--
create temp table t1(f1 int, f2 bigint);
</sql-statement>
(TFileError) (File exists) util/system/file.cpp:857: can't open "/tmp/tmpbbmu_5di/t1" with mode CreateNew (0x00000003)
(TFileError) (File exists) util/system/file.cpp:918: can't open "/tmp/tmpjl487dvf/t1" with mode CreateNew (0x00000003)
61 changes: 61 additions & 0 deletions ydb/library/yql/tests/postgresql/cases/aggregates.out
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,67 @@ SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric);
NaN |
(1 row)

-- verify correct results for null and NaN inputs
select sum(null::int4) from generate_series(1,3);
sum
-----

(1 row)

select sum(null::int8) from generate_series(1,3);
sum
-----

(1 row)

select sum(null::numeric) from generate_series(1,3);
sum
-----

(1 row)

select sum(null::float8) from generate_series(1,3);
sum
-----

(1 row)

select avg(null::int4) from generate_series(1,3);
avg
-----

(1 row)

select avg(null::int8) from generate_series(1,3);
avg
-----

(1 row)

select avg(null::numeric) from generate_series(1,3);
avg
-----

(1 row)

select avg(null::float8) from generate_series(1,3);
avg
-----

(1 row)

select sum('NaN'::numeric) from generate_series(1,3);
sum
-----
NaN
(1 row)

select avg('NaN'::numeric) from generate_series(1,3);
avg
-----
NaN
(1 row)

SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('1'), ('infinity')) v(x);
sum | avg | var_pop
Expand Down
11 changes: 11 additions & 0 deletions ydb/library/yql/tests/postgresql/cases/aggregates.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ SELECT var_pop('inf'::numeric), var_samp('inf'::numeric);
SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric);
SELECT var_pop('nan'::numeric), var_samp('nan'::numeric);
SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric);
-- verify correct results for null and NaN inputs
select sum(null::int4) from generate_series(1,3);
select sum(null::int8) from generate_series(1,3);
select sum(null::numeric) from generate_series(1,3);
select sum(null::float8) from generate_series(1,3);
select avg(null::int4) from generate_series(1,3);
select avg(null::int8) from generate_series(1,3);
select avg(null::numeric) from generate_series(1,3);
select avg(null::float8) from generate_series(1,3);
select sum('NaN'::numeric) from generate_series(1,3);
select avg('NaN'::numeric) from generate_series(1,3);
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
FROM (VALUES ('1'), ('infinity')) v(x);
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
Expand Down
14 changes: 2 additions & 12 deletions ydb/library/yql/tests/postgresql/cases/bit.err
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,7 @@ XFA50 X05AF
X1234 XFFF5
\.
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "X0F"

X0F X10
^
Metacommand \. is not supported
<sql-statement>
SELECT a, b, ~a AS "~ a", a & b AS "a & b",
a | b AS "a | b", a # b AS "a # b" FROM varbit_table;
Expand Down Expand Up @@ -179,12 +174,7 @@ XFA50 X05AF
X1234 XFFF5
\.
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "X0F00"

X0F00 X1000
^
Metacommand \. is not supported
<sql-statement>
SELECT a,b,~a AS "~ a",a & b AS "a & b",
a|b AS "a | b", a # b AS "a # b" FROM bit_table;
Expand Down
56 changes: 8 additions & 48 deletions ydb/library/yql/tests/postgresql/cases/create_table.err
Original file line number Diff line number Diff line change
Expand Up @@ -434,23 +434,13 @@ DEALLOCATE select1;
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
\set ECHO none
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:3:1: Error: ERROR: syntax error at or near "\"

\set ECHO none
^
Metacommand \set ECHO none is not supported
<sql-statement>
SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);'
FROM generate_series(1, 1100) g(i)
\gexec
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:3:1: Error: ERROR: syntax error at or near "\"

\gexec
^
Metacommand \gexec is not supported
<sql-statement>
\set ECHO all
</sql-statement>
Expand Down Expand Up @@ -978,12 +968,7 @@ CREATE TABLE fail () INHERITS (partitioned2);
-- Partition key in describe output
\d partitioned
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"

\d partitioned
^
Metacommand \d partitioned is not supported
<sql-statement>
\d+ partitioned2
</sql-statement>
Expand Down Expand Up @@ -2274,12 +2259,7 @@ insert into parted_notnull_inh_test (b) values (null);
-- note that while b's default is overriden, a's default is preserved
\d parted_notnull_inh_test1
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"

\d parted_notnull_inh_test1
^
Metacommand \d parted_notnull_inh_test1 is not supported
<sql-statement>
drop table parted_notnull_inh_test;
</sql-statement>
Expand Down Expand Up @@ -2399,45 +2379,25 @@ drop table test_part_coll_posix;
-- Partition bound in describe output
\d+ part_b
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"

\d+ part_b
^
Metacommand \d+ part_b is not supported
<sql-statement>
-- Both partition bound and partition key in describe output
\d+ part_c
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"

\d+ part_c
^
Metacommand \d+ part_c is not supported
<sql-statement>
-- a level-2 partition's constraint will include the parent's expressions
\d+ part_c_1_10
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"

\d+ part_c_1_10
^
Metacommand \d+ part_c_1_10 is not supported
<sql-statement>
-- Show partition count in the parent's describe output
-- Tempted to include \d+ output listing partitions with bound info but
-- output could vary depending on the order in which partition oids are
-- returned.
\d parted
</sql-statement>
-stdin-:<main>: Error: Parse Sql

-stdin-:<main>:5:1: Error: ERROR: syntax error at or near "\"

\d parted
^
Metacommand \d parted is not supported
<sql-statement>
\d hash_parted
</sql-statement>
Expand Down
8 changes: 0 additions & 8 deletions ydb/library/yql/tests/postgresql/cases/functional_deps.err
Original file line number Diff line number Diff line change
Expand Up @@ -455,14 +455,6 @@ INNER JOIN users u ON u.uid = n.uid
WHERE n.type = 'blog' AND n.status = 1
GROUP BY u.uid, u.name;
</sql-statement>
-stdin-:<main>: Error: Type annotation

-stdin-:<main>:1:1: Error: At function: AssumeColumnOrder, At function: PgReplaceUnknown, At function: OrderedMap, At function: UnionAll, At function: Aggregate
-- OK
^
-stdin-:<main>:1:1: Error: Expected hashable and equatable type for key column: _alias_u.name, but got: pgvarchar
-- OK
^
<sql-statement>
-- OK
SELECT u.uid, u.name FROM node n
Expand Down
9 changes: 9 additions & 0 deletions ydb/library/yql/tests/postgresql/cases/functional_deps.out
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,12 @@ CREATE TEMP TABLE users (
PRIMARY KEY (uid),
UNIQUE (name)
);
-- OK
SELECT u.uid, u.name FROM node n
INNER JOIN users u ON u.uid = n.uid
WHERE n.type = 'blog' AND n.status = 1
GROUP BY u.uid, u.name;
uid | name
-----+------
(0 rows)

5 changes: 5 additions & 0 deletions ydb/library/yql/tests/postgresql/cases/functional_deps.sql
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ CREATE TEMP TABLE users (
PRIMARY KEY (uid),
UNIQUE (name)
);
-- OK
SELECT u.uid, u.name FROM node n
INNER JOIN users u ON u.uid = n.uid
WHERE n.type = 'blog' AND n.status = 1
GROUP BY u.uid, u.name;
Loading
Loading