BUG #17792: MERGE uses uninitialized pointer and crashes when target tuple is updated concurrently - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #17792: MERGE uses uninitialized pointer and crashes when target tuple is updated concurrently
Date
Msg-id 17792-0f89452029662c36@postgresql.org
Whole thread Raw
Responses Re: BUG #17792: MERGE uses uninitialized pointer and crashes when target tuple is updated concurrently  (Alvaro Herrera <alvherre@alvh.no-ip.org>)
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      17792
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 15.2
Operating system:   Ubuntu 22.04
Description:

When executing the following queries with valgrind:
echo "
CREATE TABLE source (sid integer);
INSERT INTO source VALUES (1);
CREATE TABLE target (tid integer, tval integer);
INSERT INTO target VALUES (1, 1);
" | psql

for ((i=1;i<=50;i++)); do
  echo "iteration $i"
  echo "
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
UPDATE SET tval = 0;
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
UPDATE SET tval = 0;
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
UPDATE SET tval = 0;
  " | psql &
  echo "
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
DELETE;
INSERT INTO target VALUES (1, 1);
  " | psql &
  wait
  grep '_suppression_' server.log && break
  grep 'runtime error: ' server.log && break
done

I get:
...
iteration 15
MERGE 1
MERGE 1
MERGE 1
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
connection to server was lost
   <insert_a_suppression_name_here>

server.log contains:
==00:00:00:28.417 799644== Conditional jump or move depends on uninitialised
value(s)
==00:00:00:28.417 799644==    at 0x43C67B: ExecMergeMatched
(nodeModifyTable.c:2992)
==00:00:00:28.417 799644==    by 0x43CCB4: ExecMerge
(nodeModifyTable.c:2750)
==00:00:00:28.417 799644==    by 0x43D72B: ExecModifyTable
(nodeModifyTable.c:3867)
==00:00:00:28.417 799644==    by 0x40E7F1: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:28.417 799644==    by 0x406E19: ExecProcNode (executor.h:259)
==00:00:00:28.417 799644==    by 0x406E19: ExecutePlan (execMain.c:1636)
==00:00:00:28.417 799644==    by 0x406FF9: standard_ExecutorRun
(execMain.c:363)
==00:00:00:28.417 799644==    by 0x4070C5: ExecutorRun (execMain.c:307)
==00:00:00:28.417 799644==    by 0x5C5465: ProcessQuery (pquery.c:160)
==00:00:00:28.417 799644==    by 0x5C601A: PortalRunMulti (pquery.c:1277)
==00:00:00:28.417 799644==    by 0x5C65F3: PortalRun (pquery.c:791)
==00:00:00:28.417 799644==    by 0x5C27C3: exec_simple_query
(postgres.c:1250)
==00:00:00:28.417 799644==    by 0x5C465D: PostgresMain (postgres.c:4593)
==00:00:00:28.417 799644==  Uninitialised value was created by a stack
allocation
==00:00:00:28.417 799644==    at 0x43D189: ExecModifyTable
(nodeModifyTable.c:3572)
==00:00:00:28.417 799644==
{
   <insert_a_suppression_name_here>
...
==00:00:00:28.417 799644== Exit program on first error
(--exit-on-first-error=yes)
2023-02-14 08:43:28.826 MSK [799385] LOG:  server process (PID 799644)
exited with exit code 1
2023-02-14 08:43:28.826 MSK [799385] DETAIL:  Failed process was running:
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
DELETE;

(With asan I get "nodeModifyTable.c:2992:11: runtime error: member access
within misaligned address 0x561fcdc53231 for type 'struct TupleTableSlot',
which requires 8 byte alignment", without valgrind/sanitizer just
SIGSEGV.)

At nodeModifyTable.c:2992 I see:
                    if (!TupIsNull(context->cpUpdateRetrySlot))

It looks like cpUpdateRetrySlot was not initialized on the context creation
in ExecModifyTable(), and ExecCrossPartitionUpdate(), where it could get a
value, just not called for this case.

Observed since the MERGE introduction (7103ebb7a).


pgsql-bugs by date:

Previous
From: Kyotaro Horiguchi
Date:
Subject: Re: BUG #17789: process_pgfdw_appname() fails for autovacuum workers
Next
From: Masahiko Sawada
Date:
Subject: Re: BUG #17789: process_pgfdw_appname() fails for autovacuum workers