Thread: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
PG Bug reporting form
Date:
The following bug has been logged on the website: Bug reference: 18276 Logged by: Zuming Jiang Email address: zuming.jiang@inf.ethz.ch PostgreSQL version: 16.1 Operating system: Ubuntu 20.04 Description: My fuzzer finds a heap-buffer-overflow bug in PostgreSQL 17devel, which makes PostgreSQL crash. --- Compile Postgres with ASan --- ./configure CC=clang CFLAGS="-fsanitize=address -fno-omit-frame-pointer -g" LDFLAGS="-fsanitize=address" make -j make install --- Set up database --- --- Note: you need to replace '/home/zuming/postgres/src/test/regress/regress.so' with the your source code path --- create table exeet_t228 (vkey int4); CREATE FUNCTION widget_in(cstring) RETURNS widget AS '/home/zuming/postgres/src/test/regress/regress.so' LANGUAGE C STRICT IMMUTABLE; CREATE FUNCTION widget_out(widget) RETURNS cstring AS '/home/zuming/postgres/src/test/regress/regress.so' LANGUAGE C STRICT IMMUTABLE; CREATE TYPE widget ( input = widget_in, output = widget_out, alignment = double ); CREATE FUNCTION pt_in_widget(point, widget) RETURNS bool AS '/home/zuming/postgres/src/test/regress/regress.so' LANGUAGE C STRICT; CREATE OPERATOR <% ( leftarg = point, rightarg = widget, procedure = pt_in_widget, negator = >=% ); My fuzzer generates a test case: --- Test case --- select 1 from exeet_t228 as ref_0 where (ref_0.vkey >= (case when ('false' <> (select c1 from ( select cast(subq_c0 as text) as c0, cast(subq_c1 as text) as c1 from ( SELECT point '(1,2)' <% widget '(0,0,3)' AS t, point '(1,2)' <% widget '(0,0,1)' AS f ) as subq(subq_c0, subq_c1) ) order by c0 asc, c1 asc limit 1 offset 0)) then 0 else ref_0.vkey end)) and (not ('2147483648' = ( select c0 from ( select cast(subq_c0 as text) as c0 from (SELECT 0o20000000000) as subq(subq_c0)) order by c0 asc limit 1 offset 0))); --- Expected behavior --- PostgreSQL server should not crash. --- Actual behavior --- PostgreSQL server crashes. --- Postgres version --- Github commit: 2a67b5a60ee68892bb028587ddc6de7650822480 Version: PostgreSQL 17devel on x86_64-pc-linux-gnu, compiled by clang version 10.0.0-4ubuntu1 , 64-bit --- Platform information --- Platform: Ubuntu 20.04 Kernel: Linux 5.4.0-147-generic --- Bug report from from ASan --- ================================================================= ==90==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62d000102400 at pc 0x00000051ea5a bp 0x7ffe8eaab580 sp 0x7ffe8eaaad48 READ of size 800042927 at 0x62d000102400 thread T0 #0 0x51ea59 in __asan_memcpy (/usr/local/pgsql/bin/postgres+0x51ea59) #1 0x1acceb2 in datumCopy /home/zuming/postgres/src/backend/utils/adt/datum.c:163:4 #2 0x1153f0d in _copyConst /home/zuming/postgres/src/backend/nodes/copyfuncs.c:95:25 #3 0x11503a2 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/./copyfuncs.switch.c:34:13 #4 0x1205b8d in list_copy_deep /home/zuming/postgres/src/backend/nodes/list.c:1651:4 #5 0x1151ca7 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/copyfuncs.c:192:13 #6 0x1157494 in _copyOpExpr /home/zuming/postgres/src/backend/nodes/./copyfuncs.funcs.c:263:2 #7 0x115044a in copyObjectImpl /home/zuming/postgres/src/backend/nodes/./copyfuncs.switch.c:58:13 #8 0x115fddb in _copyTargetEntry /home/zuming/postgres/src/backend/nodes/./copyfuncs.funcs.c:810:2 #9 0x115077d in copyObjectImpl /home/zuming/postgres/src/backend/nodes/./copyfuncs.switch.c:175:13 #10 0x1205b8d in list_copy_deep /home/zuming/postgres/src/backend/nodes/list.c:1651:4 #11 0x1151ca7 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/copyfuncs.c:192:13 #12 0x1161f7b in _copyQuery /home/zuming/postgres/src/backend/nodes/./copyfuncs.funcs.c:904:2 #13 0x11507e6 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/./copyfuncs.switch.c:190:13 #14 0x116a27f in _copyRangeTblEntry /home/zuming/postgres/src/backend/nodes/./copyfuncs.funcs.c:1384:2 #15 0x1150ab0 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/./copyfuncs.switch.c:292:13 #16 0x1205b8d in list_copy_deep /home/zuming/postgres/src/backend/nodes/list.c:1651:4 #17 0x1151ca7 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/copyfuncs.c:192:13 #18 0x1161c72 in _copyQuery /home/zuming/postgres/src/backend/nodes/./copyfuncs.funcs.c:899:2 #19 0x11507e6 in copyObjectImpl /home/zuming/postgres/src/backend/nodes/./copyfuncs.switch.c:190:13 #20 0x14fe377 in pull_up_simple_subquery /home/zuming/postgres/src/backend/optimizer/prep/prepjointree.c:974:13 #21 0x14f16c9 in pull_up_subqueries_recurse /home/zuming/postgres/src/backend/optimizer/prep/prepjointree.c:838:11 #22 0x14f1da9 in pull_up_subqueries_recurse /home/zuming/postgres/src/backend/optimizer/prep/prepjointree.c:885:16 #23 0x14f11c4 in pull_up_subqueries /home/zuming/postgres/src/backend/optimizer/prep/prepjointree.c:774:3 #24 0x14729ef in subquery_planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:723:2 #25 0x14dfa67 in make_subplan /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:221:12 #26 0x14d4b6b in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:1949:10 #27 0x12248ba in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:3384:12 #28 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #29 0x122121b in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:2972:5 #30 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #31 0x1222681 in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:3147:5 #32 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #33 0x12248ba in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:3384:12 #34 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #35 0x12224d7 in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:3136:5 #36 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #37 0x12248ba in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:3384:12 #38 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #39 0x122121b in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:2972:5 #40 0x14d5a41 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2051:9 #41 0x14d5318 in process_sublinks_mutator /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:2015:13 #42 0x14d45dd in SS_process_sublinks /home/zuming/postgres/src/backend/optimizer/plan/subselect.c:1922:9 #43 0x14797a3 in preprocess_expression /home/zuming/postgres/src/backend/optimizer/plan/planner.c:1191:10 #44 0x1479eb0 in preprocess_qual_conditions /home/zuming/postgres/src/backend/optimizer/plan/planner.c:1236:14 #45 0x1474072 in subquery_planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:854:2 #46 0x146e7ab in standard_planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:413:9 #47 0x146dabb in planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:281:12 #48 0x19476f5 in pg_plan_query /home/zuming/postgres/src/backend/tcop/postgres.c:903:9 #49 0x1948151 in pg_plan_queries /home/zuming/postgres/src/backend/tcop/postgres.c:995:11 #50 0x194f70e in exec_simple_query /home/zuming/postgres/src/backend/tcop/postgres.c:1192:19 #51 0x194dcb9 in PostgresMain /home/zuming/postgres/src/backend/tcop/postgres.c:4653:7 #52 0x16526e7 in BackendRun /home/zuming/postgres/src/backend/postmaster/postmaster.c:4464:2 #53 0x164bd3c in BackendStartup /home/zuming/postgres/src/backend/postmaster/postmaster.c:4140:3 #54 0x1647253 in ServerLoop /home/zuming/postgres/src/backend/postmaster/postmaster.c:1776:6 #55 0x1644ce5 in PostmasterMain /home/zuming/postgres/src/backend/postmaster/postmaster.c:1475:11 #56 0x114acde in main /home/zuming/postgres/src/backend/main/main.c:198:3 #57 0x7f2c00a79082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) #58 0x4a6ecd in _start (/usr/local/pgsql/bin/postgres+0x4a6ecd) 0x62d000102400 is located 0 bytes to the right of 32768-byte region [0x62d0000fa400,0x62d000102400) allocated by thread T0 here: #0 0x51f60d in malloc (/usr/local/pgsql/bin/postgres+0x51f60d) #1 0x2080712 in AllocSetAlloc /home/zuming/postgres/src/backend/utils/mmgr/aset.c:928:24 #2 0x209ed66 in palloc /home/zuming/postgres/src/backend/utils/mmgr/mcxt.c:1202:8 #3 0x11f9d23 in new_list /home/zuming/postgres/src/backend/nodes/list.c:136:21 #4 0x11fac78 in lappend /home/zuming/postgres/src/backend/nodes/list.c:343:10 #5 0x12248c9 in expression_tree_mutator_impl /home/zuming/postgres/src/backend/nodes/nodeFuncs.c:3383:19 #6 0x15451ea in simplify_function /home/zuming/postgres/src/backend/optimizer/util/clauses.c:4061:19 #7 0x15347e0 in eval_const_expressions_mutator /home/zuming/postgres/src/backend/optimizer/util/clauses.c:2617:14 #8 0x15464e8 in simplify_and_arguments /home/zuming/postgres/src/backend/optimizer/util/clauses.c:3890:9 #9 0x1536ecf in eval_const_expressions_mutator /home/zuming/postgres/src/backend/optimizer/util/clauses.c:2849:18 #10 0x1531c1c in eval_const_expressions /home/zuming/postgres/src/backend/optimizer/util/clauses.c:2249:9 #11 0x14796c6 in preprocess_expression /home/zuming/postgres/src/backend/optimizer/plan/planner.c:1164:10 #12 0x1479eb0 in preprocess_qual_conditions /home/zuming/postgres/src/backend/optimizer/plan/planner.c:1236:14 #13 0x1474072 in subquery_planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:854:2 #14 0x146e7ab in standard_planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:413:9 #15 0x146dabb in planner /home/zuming/postgres/src/backend/optimizer/plan/planner.c:281:12 #16 0x19476f5 in pg_plan_query /home/zuming/postgres/src/backend/tcop/postgres.c:903:9 #17 0x1948151 in pg_plan_queries /home/zuming/postgres/src/backend/tcop/postgres.c:995:11 #18 0x194f70e in exec_simple_query /home/zuming/postgres/src/backend/tcop/postgres.c:1192:19 #19 0x194dcb9 in PostgresMain /home/zuming/postgres/src/backend/tcop/postgres.c:4653:7 #20 0x16526e7 in BackendRun /home/zuming/postgres/src/backend/postmaster/postmaster.c:4464:2 #21 0x164bd3c in BackendStartup /home/zuming/postgres/src/backend/postmaster/postmaster.c:4140:3 #22 0x1647253 in ServerLoop /home/zuming/postgres/src/backend/postmaster/postmaster.c:1776:6 #23 0x1644ce5 in PostmasterMain /home/zuming/postgres/src/backend/postmaster/postmaster.c:1475:11 #24 0x114acde in main /home/zuming/postgres/src/backend/main/main.c:198:3 #25 0x7f2c00a79082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/pgsql/bin/postgres+0x51ea59) in __asan_memcpy Shadow bytes around the buggy address: 0x0c5a80018430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a80018440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a80018450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a80018460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a80018470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c5a80018480:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a80018490: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a800184a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a800184b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a800184c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a800184d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==90==ABORTING
Re: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
"Andrey M. Borodin"
Date:
Hi Zuming! Thanks for reporting this suspicious ASan alarm. > On 7 Jan 2024, at 22:50, PG Bug reporting form <noreply@postgresql.org> wrote: > > --- Compile Postgres with ASan --- > ./configure CC=clang CFLAGS="-fsanitize=address -fno-omit-frame-pointer -g" > LDFLAGS="-fsanitize=address" > make -j > make install I've tried to reproduce the problem. And my system does not pass regressions tests at all with these flags. Maybe I'm doingsomething wrong. Does your system pass `make check`? Best regards, Andrey Borodin.
Re: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
Zu-Ming Jiang
Date:
Hi Andrey Borodin,
I've tried to reproduce the problem. And my system does not pass regressions tests at all with these flags. Maybe I'm doing something wrong. Does your system pass `make check`?My system pass the regression test with these flags. FYI, I used clang 10. Best wishes, Zuming
Re: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
Tom Lane
Date:
PG Bug reporting form <noreply@postgresql.org> writes: > My fuzzer finds a heap-buffer-overflow bug in PostgreSQL 17devel, which > makes PostgreSQL crash. All I see here is a datatype declaration that doesn't match what the C functions expect. You wrote: > CREATE TYPE widget ( > input = widget_in, > output = widget_out, > alignment = double > ); but the declaration that the regress.so functions expect is what's in src/test/regress/sql/create_type.sql: CREATE TYPE widget ( internallength = 24, input = widget_in, output = widget_out, typmod_in = numerictypmodin, typmod_out = numerictypmodout, alignment = double ); That is, widget_in expects it should produce a fixed-length Datum (24 bytes long, with no length word). But you declared the type as variable-length, meaning that datumCopy expects to find a length word. That discrepancy leads directly to the reported crash. regards, tom lane
Re: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
Zu-Ming Jiang
Date:
Thank you for figuring out the problem, Tom!
After using the correct type you mentioned, the test case does not trigger crash anymore.
But I am bit wondering whether it is a bug. I think PostgreSQL should not directly crash because of a incorrect datatype. Maybe PostgreSQL can return an error?
Best wishes,
Zuming
but the declaration that the regress.so functions expect is what's in src/test/regress/sql/create_type.sql: CREATE TYPE widget ( internallength = 24, input = widget_in, output = widget_out, typmod_in = numerictypmodin, typmod_out = numerictypmodout, alignment = double );
After using the correct type you mentioned, the test case does not trigger crash anymore.
But I am bit wondering whether it is a bug. I think PostgreSQL should not directly crash because of a incorrect datatype. Maybe PostgreSQL can return an error?
Best wishes,
Zuming
From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Sent: Sunday, January 7, 2024 at 8:16 PM
Subject: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
PG Bug reporting form <noreply@postgresql.org> writes:My fuzzer finds a heap-buffer-overflow bug in PostgreSQL 17devel, which makes PostgreSQL crash.All I see here is a datatype declaration that doesn't match what the C functions expect. You wrote:CREATE TYPE widget ( input = widget_in, output = widget_out, alignment = double );but the declaration that the regress.so functions expect is what's in src/test/regress/sql/create_type.sql: CREATE TYPE widget ( internallength = 24, input = widget_in, output = widget_out, typmod_in = numerictypmodin, typmod_out = numerictypmodout, alignment = double ); That is, widget_in expects it should produce a fixed-length Datum (24 bytes long, with no length word). But you declared the type as variable-length, meaning that datumCopy expects to find a length word. That discrepancy leads directly to the reported crash. regards, tom lane
Re: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
Tom Lane
Date:
Zu-Ming Jiang <zuming.jiang@inf.ethz.ch> writes: > But I am bit wondering whether it is a bug. I think PostgreSQL should > not directly crash because of a incorrect datatype. Maybe PostgreSQL can > return an error? It's not reasonable to expect the system to figure out the behavior of C functions (see: halting problem). In the end this is why creating base types is a superuser-only operation: it's possible to crash the server with a wrong definition. I don't see any prospect of making that meaningfully safer. regards, tom lane
Re: BUG #18276: Heap-buffer-overflow triggered in src/backend/utils/adt/datum.c:163
From
Zu-Ming Jiang
Date:
Thanks for the feedback!
I will adjust my fuzzer to avoid such issues.
Best wishes,
Zuming
It's not reasonable to expect the system to figure out the behavior of C functions (see: halting problem). In the end this is why creating base types is a superuser-only operation: it's possible to crash the server with a wrong definition. I don't see any prospect of making that meaningfully safer.
I will adjust my fuzzer to avoid such issues.
Best wishes,
Zuming