NULL passed as an argument to memcmp() in parse_func.c - Mailing list pgsql-hackers

From Piotr Stefaniak
Subject NULL passed as an argument to memcmp() in parse_func.c
Date
Msg-id BLU437-SMTP48A5B2099E7134AC6BE7C7F2A10@phx.gbl
Whole thread Raw
Responses Re: NULL passed as an argument to memcmp() in parse_func.c  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Hello,

There are two places in parse_func.c where memcmp() conditionally gets a
NULL as its first argument, which invokes undefined behavior. I guess
gcc -O2 will make some assumptions based on memcpy's __nonnull attribute.

You can see when exactly that happens by applying the two trivial
patches below, running make check and printing backtrace in gdb. At
least one of these are triggered by a call to pg_get_triggerdef() in the
triggers test.

diff --git a/src/backend/parser/parse_func.c
b/src/backend/parser/parse_func.c
index fa9761b..5f37e25 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1438,6 +1438,7 @@ func_get_detail(List *funcname,
                  best_candidate != NULL;
                  best_candidate = best_candidate->next)
         {
+               Assert(argtypes != NULL);
                 if (memcmp(argtypes, best_candidate->args, nargs *
sizeof(Oid)) == 0)
                         break;
         }

#0  0x00007f02b668ca98 in raise () from /lib64/libc.so.6
#1  0x00007f02b668e72a in abort () from /lib64/libc.so.6
#2  0x00000000007c5774 in ExceptionalCondition ()
#3  0x000000000054f7d1 in func_get_detail ()
#4  0x000000000077cd02 in generate_function_name ()
#5  0x0000000000770ec5 in pg_get_triggerdef_worker ()
#6  0x00000000007711e8 in pg_get_triggerdef_ext ()
#7  0x00000000005d1f02 in ExecMakeFunctionResultNoSets ()
#8  0x00000000005d160c in ExecProject ()
#9  0x00000000005d22e2 in ExecScan ()
#10 0x00000000005cb644 in ExecProcNode ()
#11 0x00000000005c8a80 in standard_ExecutorRun ()
#12 0x00000000006d26c4 in PortalRunSelect ()
#13 0x00000000006d22ed in PortalRun ()
#14 0x00000000006d09ac in PostgresMain ()
#15 0x000000000066e09c in PostmasterMain ()
#16 0x0000000000600e9c in main ()


diff --git a/src/backend/parser/parse_func.c
b/src/backend/parser/parse_func.c
index fa9761b..e70d065 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -2047,6 +2047,7 @@ LookupFuncName(List *funcname, int nargs, const
Oid *argtypes, bool noError)

         while (clist)
         {
+               Assert(argtypes != NULL);
                 if (memcmp(argtypes, clist->args, nargs * sizeof(Oid))
== 0)
                         return clist->oid;
                 clist = clist->next;

#0  0x00007f59e8e81a98 in raise () from /lib64/libc.so.6
#1  0x00007f59e8e8372a in abort () from /lib64/libc.so.6
#2  0x00000000007c5774 in ExceptionalCondition ()
#3  0x00000000005508a9 in LookupFuncName ()
#4  0x0000000000577ec5 in CreateEventTrigger ()
#5  0x00000000006d3341 in PortalRunUtility ()
#6  0x00000000006d28f3 in PortalRunMulti ()
#7  0x00000000006d2338 in PortalRun ()
#8  0x00000000006d09ac in PostgresMain ()
#9  0x000000000066e09c in PostmasterMain ()
#10 0x0000000000600e9c in main ()


The least invasive patch I could come up with is attached to this email.

Attachment

pgsql-hackers by date:

Previous
From: Robert Haas
Date:
Subject: Re: [PATCH] pg_upgrade fails when postgres/template1 isn't in default tablespace
Next
From: Jim Nasby
Date:
Subject: Re: Further issues with jsonb semantics, documentation