Skip to content

Commit 35977c7

Browse files
authored
YQL-17388: fix use-after-free bug in TPgResolvedMultiCall::TListValue::TIterator (#955)
* Fix use-after-free bug in TPgResolvedMultiCall::TListValue::TIterator * Updated PG's regression tests' status
1 parent 57677f2 commit 35977c7

24 files changed

+239
-288
lines changed

ydb/library/yql/parser/pg_wrapper/comp_factory.cpp

+35-5
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,14 @@ class TReturnSetInfo {
462462
}
463463

464464
~TReturnSetInfo() {
465+
Free();
466+
}
467+
468+
void Free() {
469+
if (!Ptr) {
470+
return;
471+
}
472+
465473
if (Ref().expectedDesc) {
466474
FreeTupleDesc(Ref().expectedDesc);
467475
}
@@ -471,9 +479,12 @@ class TReturnSetInfo {
471479
}
472480

473481
TWithDefaultMiniKQLAlloc::FreeWithSize(Ptr, sizeof(ReturnSetInfo));
482+
Ptr = nullptr;
474483
}
475484

476485
ReturnSetInfo& Ref() {
486+
Y_ENSURE(Ptr, "ReturnSetInfo is dead");
487+
477488
return *static_cast<ReturnSetInfo*>(Ptr);
478489
}
479490

@@ -488,11 +499,21 @@ class TExprContextHolder {
488499
}
489500

490501
ExprContext& Ref() {
502+
Y_ENSURE(Ptr, "TExprContextHolder is dead");
503+
491504
return *Ptr;
492505
}
493506

494507
~TExprContextHolder() {
508+
Free();
509+
}
510+
511+
void Free() {
512+
if (!Ptr) {
513+
return;
514+
}
495515
FreeExprContext(Ptr, true);
516+
Ptr = nullptr;
496517
}
497518

498519
private:
@@ -739,9 +760,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {
739760
}
740761

741762
~TIterator() {
742-
if (TupleSlot) {
743-
ExecDropSingleTupleTableSlot(TupleSlot);
744-
}
763+
FinishAndFree();
745764
}
746765

747766
private:
@@ -766,7 +785,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {
766785
} else {
767786
YQL_ENSURE(!StructType);
768787
if (RSInfo.Ref().isDone == ExprEndResult) {
769-
IsFinished = true;
788+
FinishAndFree();
770789
return false;
771790
}
772791

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

783802
bool CopyTuple(NUdf::TUnboxedValue& value) {
784803
if (!tuplestore_gettupleslot(RSInfo.Ref().setResult, true, false, TupleSlot)) {
785-
IsFinished = true;
804+
FinishAndFree();
786805
return false;
787806
}
788807

@@ -835,6 +854,17 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase<TPgResolvedMultiCall> {
835854
}
836855
}
837856

857+
void FinishAndFree() {
858+
if (TupleSlot) {
859+
ExecDropSingleTupleTableSlot(TupleSlot);
860+
TupleSlot = nullptr;
861+
}
862+
RSInfo.Free();
863+
ExprContextHolder.Free();
864+
865+
IsFinished = true;
866+
}
867+
838868
const std::string_view Name;
839869
TUnboxedValueVector Args;
840870
const TVector<NPg::TTypeDesc>& ArgDesc;

ydb/library/yql/tests/postgresql/cases/aggregates.err

+3-13
Original file line numberDiff line numberDiff line change
@@ -654,12 +654,7 @@ COPY bitwise_test FROM STDIN NULL 'null';
654654
7 7 7 3 4 B1100
655655
\.
656656
</sql-statement>
657-
-stdin-:<main>: Error: Parse Sql
658-
659-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "1"
660-
661-
1 1 1 1 1 B0101
662-
^
657+
Metacommand \. is not supported
663658
<sql-statement>
664659
SELECT
665660
BIT_AND(i2) AS "1",
@@ -769,12 +764,7 @@ FALSE TRUE null null
769764
null TRUE FALSE null
770765
\.
771766
</sql-statement>
772-
-stdin-:<main>: Error: Parse Sql
773-
774-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "TRUE"
775-
776-
TRUE null FALSE null
777-
^
767+
Metacommand \. is not supported
778768
<sql-statement>
779769
SELECT
780770
BOOL_AND(b1) AS "f",
@@ -1354,4 +1344,4 @@ drop table p_t1;
13541344
--
13551345
create temp table t1(f1 int, f2 bigint);
13561346
</sql-statement>
1357-
(TFileError) (File exists) util/system/file.cpp:857: can't open "/tmp/tmpbbmu_5di/t1" with mode CreateNew (0x00000003)
1347+
(TFileError) (File exists) util/system/file.cpp:918: can't open "/tmp/tmpjl487dvf/t1" with mode CreateNew (0x00000003)

ydb/library/yql/tests/postgresql/cases/aggregates.out

+61
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,67 @@ SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric);
5353
NaN |
5454
(1 row)
5555

56+
-- verify correct results for null and NaN inputs
57+
select sum(null::int4) from generate_series(1,3);
58+
sum
59+
-----
60+
61+
(1 row)
62+
63+
select sum(null::int8) from generate_series(1,3);
64+
sum
65+
-----
66+
67+
(1 row)
68+
69+
select sum(null::numeric) from generate_series(1,3);
70+
sum
71+
-----
72+
73+
(1 row)
74+
75+
select sum(null::float8) from generate_series(1,3);
76+
sum
77+
-----
78+
79+
(1 row)
80+
81+
select avg(null::int4) from generate_series(1,3);
82+
avg
83+
-----
84+
85+
(1 row)
86+
87+
select avg(null::int8) from generate_series(1,3);
88+
avg
89+
-----
90+
91+
(1 row)
92+
93+
select avg(null::numeric) from generate_series(1,3);
94+
avg
95+
-----
96+
97+
(1 row)
98+
99+
select avg(null::float8) from generate_series(1,3);
100+
avg
101+
-----
102+
103+
(1 row)
104+
105+
select sum('NaN'::numeric) from generate_series(1,3);
106+
sum
107+
-----
108+
NaN
109+
(1 row)
110+
111+
select avg('NaN'::numeric) from generate_series(1,3);
112+
avg
113+
-----
114+
NaN
115+
(1 row)
116+
56117
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
57118
FROM (VALUES ('1'), ('infinity')) v(x);
58119
sum | avg | var_pop

ydb/library/yql/tests/postgresql/cases/aggregates.sql

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ SELECT var_pop('inf'::numeric), var_samp('inf'::numeric);
1313
SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric);
1414
SELECT var_pop('nan'::numeric), var_samp('nan'::numeric);
1515
SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric);
16+
-- verify correct results for null and NaN inputs
17+
select sum(null::int4) from generate_series(1,3);
18+
select sum(null::int8) from generate_series(1,3);
19+
select sum(null::numeric) from generate_series(1,3);
20+
select sum(null::float8) from generate_series(1,3);
21+
select avg(null::int4) from generate_series(1,3);
22+
select avg(null::int8) from generate_series(1,3);
23+
select avg(null::numeric) from generate_series(1,3);
24+
select avg(null::float8) from generate_series(1,3);
25+
select sum('NaN'::numeric) from generate_series(1,3);
26+
select avg('NaN'::numeric) from generate_series(1,3);
1627
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)
1728
FROM (VALUES ('1'), ('infinity')) v(x);
1829
SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric)

ydb/library/yql/tests/postgresql/cases/bit.err

+2-12
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,7 @@ XFA50 X05AF
138138
X1234 XFFF5
139139
\.
140140
</sql-statement>
141-
-stdin-:<main>: Error: Parse Sql
142-
143-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "X0F"
144-
145-
X0F X10
146-
^
141+
Metacommand \. is not supported
147142
<sql-statement>
148143
SELECT a, b, ~a AS "~ a", a & b AS "a & b",
149144
a | b AS "a | b", a # b AS "a # b" FROM varbit_table;
@@ -179,12 +174,7 @@ XFA50 X05AF
179174
X1234 XFFF5
180175
\.
181176
</sql-statement>
182-
-stdin-:<main>: Error: Parse Sql
183-
184-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "X0F00"
185-
186-
X0F00 X1000
187-
^
177+
Metacommand \. is not supported
188178
<sql-statement>
189179
SELECT a,b,~a AS "~ a",a & b AS "a & b",
190180
a|b AS "a | b", a # b AS "a # b" FROM bit_table;

ydb/library/yql/tests/postgresql/cases/create_table.err

+8-48
Original file line numberDiff line numberDiff line change
@@ -434,23 +434,13 @@ DEALLOCATE select1;
434434
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
435435
\set ECHO none
436436
</sql-statement>
437-
-stdin-:<main>: Error: Parse Sql
438-
439-
-stdin-:<main>:3:1: Error: ERROR: syntax error at or near "\"
440-
441-
\set ECHO none
442-
^
437+
Metacommand \set ECHO none is not supported
443438
<sql-statement>
444439
SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);'
445440
FROM generate_series(1, 1100) g(i)
446441
\gexec
447442
</sql-statement>
448-
-stdin-:<main>: Error: Parse Sql
449-
450-
-stdin-:<main>:3:1: Error: ERROR: syntax error at or near "\"
451-
452-
\gexec
453-
^
443+
Metacommand \gexec is not supported
454444
<sql-statement>
455445
\set ECHO all
456446
</sql-statement>
@@ -978,12 +968,7 @@ CREATE TABLE fail () INHERITS (partitioned2);
978968
-- Partition key in describe output
979969
\d partitioned
980970
</sql-statement>
981-
-stdin-:<main>: Error: Parse Sql
982-
983-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"
984-
985-
\d partitioned
986-
^
971+
Metacommand \d partitioned is not supported
987972
<sql-statement>
988973
\d+ partitioned2
989974
</sql-statement>
@@ -2274,12 +2259,7 @@ insert into parted_notnull_inh_test (b) values (null);
22742259
-- note that while b's default is overriden, a's default is preserved
22752260
\d parted_notnull_inh_test1
22762261
</sql-statement>
2277-
-stdin-:<main>: Error: Parse Sql
2278-
2279-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"
2280-
2281-
\d parted_notnull_inh_test1
2282-
^
2262+
Metacommand \d parted_notnull_inh_test1 is not supported
22832263
<sql-statement>
22842264
drop table parted_notnull_inh_test;
22852265
</sql-statement>
@@ -2399,45 +2379,25 @@ drop table test_part_coll_posix;
23992379
-- Partition bound in describe output
24002380
\d+ part_b
24012381
</sql-statement>
2402-
-stdin-:<main>: Error: Parse Sql
2403-
2404-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"
2405-
2406-
\d+ part_b
2407-
^
2382+
Metacommand \d+ part_b is not supported
24082383
<sql-statement>
24092384
-- Both partition bound and partition key in describe output
24102385
\d+ part_c
24112386
</sql-statement>
2412-
-stdin-:<main>: Error: Parse Sql
2413-
2414-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"
2415-
2416-
\d+ part_c
2417-
^
2387+
Metacommand \d+ part_c is not supported
24182388
<sql-statement>
24192389
-- a level-2 partition's constraint will include the parent's expressions
24202390
\d+ part_c_1_10
24212391
</sql-statement>
2422-
-stdin-:<main>: Error: Parse Sql
2423-
2424-
-stdin-:<main>:2:1: Error: ERROR: syntax error at or near "\"
2425-
2426-
\d+ part_c_1_10
2427-
^
2392+
Metacommand \d+ part_c_1_10 is not supported
24282393
<sql-statement>
24292394
-- Show partition count in the parent's describe output
24302395
-- Tempted to include \d+ output listing partitions with bound info but
24312396
-- output could vary depending on the order in which partition oids are
24322397
-- returned.
24332398
\d parted
24342399
</sql-statement>
2435-
-stdin-:<main>: Error: Parse Sql
2436-
2437-
-stdin-:<main>:5:1: Error: ERROR: syntax error at or near "\"
2438-
2439-
\d parted
2440-
^
2400+
Metacommand \d parted is not supported
24412401
<sql-statement>
24422402
\d hash_parted
24432403
</sql-statement>

ydb/library/yql/tests/postgresql/cases/functional_deps.err

-8
Original file line numberDiff line numberDiff line change
@@ -455,14 +455,6 @@ INNER JOIN users u ON u.uid = n.uid
455455
WHERE n.type = 'blog' AND n.status = 1
456456
GROUP BY u.uid, u.name;
457457
</sql-statement>
458-
-stdin-:<main>: Error: Type annotation
459-
460-
-stdin-:<main>:1:1: Error: At function: AssumeColumnOrder, At function: PgReplaceUnknown, At function: OrderedMap, At function: UnionAll, At function: Aggregate
461-
-- OK
462-
^
463-
-stdin-:<main>:1:1: Error: Expected hashable and equatable type for key column: _alias_u.name, but got: pgvarchar
464-
-- OK
465-
^
466458
<sql-statement>
467459
-- OK
468460
SELECT u.uid, u.name FROM node n

ydb/library/yql/tests/postgresql/cases/functional_deps.out

+9
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,12 @@ CREATE TEMP TABLE users (
3535
PRIMARY KEY (uid),
3636
UNIQUE (name)
3737
);
38+
-- OK
39+
SELECT u.uid, u.name FROM node n
40+
INNER JOIN users u ON u.uid = n.uid
41+
WHERE n.type = 'blog' AND n.status = 1
42+
GROUP BY u.uid, u.name;
43+
uid | name
44+
-----+------
45+
(0 rows)
46+

ydb/library/yql/tests/postgresql/cases/functional_deps.sql

+5
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ CREATE TEMP TABLE users (
3535
PRIMARY KEY (uid),
3636
UNIQUE (name)
3737
);
38+
-- OK
39+
SELECT u.uid, u.name FROM node n
40+
INNER JOIN users u ON u.uid = n.uid
41+
WHERE n.type = 'blog' AND n.status = 1
42+
GROUP BY u.uid, u.name;

0 commit comments

Comments
 (0)