]> granicus.if.org Git - postgresql/commitdiff
Fix race condition in DELETE RETURNING.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 10 Mar 2013 23:18:53 +0000 (19:18 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 10 Mar 2013 23:18:53 +0000 (19:18 -0400)
When RETURNING is specified, ExecDelete would return a virtual-tuple slot
that could contain pointers into an already-unpinned disk buffer.  Another
process could change the buffer contents before we get around to using the
data, resulting in garbage results or even a crash.  This seems of fairly
low probability, which may explain why there are no known field reports of
the problem, but it's definitely possible.  Fix by forcing the result slot
to be "materialized" before we release pin on the disk buffer.

Back-patch to 9.0; in earlier branches there is no bug because
ExecProcessReturning sent the tuple to the destination immediately.  Also,
this is already fixed in HEAD as part of the writable-foreign-tables patch
(where the fix is necessary for DELETE RETURNING to work at all with
postgres_fdw).

src/backend/executor/nodeModifyTable.c

index ee6eef74f7a49fc1cc511bdeb02b4d1d78c9a1a4..d6429ded120d1a7b08659147808c0d8a4f035d26 100644 (file)
@@ -394,6 +394,12 @@ ldelete:;
                rslot = ExecProcessReturning(resultRelInfo->ri_projectReturning,
                                                                         slot, planSlot);
 
+               /*
+                * Before releasing the target tuple again, make sure rslot has a
+                * local copy of any pass-by-reference values.
+                */
+               ExecMaterializeSlot(rslot);
+
                ExecClearTuple(slot);
                ReleaseBuffer(delbuffer);