Обсуждение: 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
От
PG Bug reporting form
Дата:
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
От
"Andrey M. Borodin"
Дата:
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
От
Zu-Ming Jiang
Дата:
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
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
От
Zu-Ming Jiang
Дата:
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
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
От
Zu-Ming Jiang
Дата:
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