From: Alexander Lakhin <exclusion@gmail.com>
To: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17798: Incorrect memory access occurs when using BEFORE ROW UPDATE trigger
Date: Tue, 7 Mar 2023 09:00:01 +0300
Message-ID: <87fe6c28-80b2-f709-a8db-d105e5240e39@gmail.com> (raw)
In-Reply-To: <17798-0907404928dcf0dd@postgresql.org>
References: <17798-0907404928dcf0dd@postgresql.org>
17.02.2023 13:00, PG Bug reporting form wrote:
> The following bug has been logged on the website:
> ...
>
> I've found the following explanation for the failure:
> 1) After the ExecGetUpdateNewTuple() call the newslot and the oldslot are
> linked together (their slot->tts_values[1] in this case point to the same
> memory address (inside the oldslot' buffer)).
> 2) Previously, GetTupleForTrigger() could get a tuple with a new buffer,
> so the oldslot would be the only user of the buffer at that moment.
> (The newslot doesn't become an official user of the buffer.)
> 3) Then, trigtuple = ExecFetchSlotHeapTuple(oldslot, ...) invokes
> tts_buffer_heap_materialize() where the oldslot->buffer is released.
> 4) Finally, newtuple = ExecFetchSlotHeapTuple(newslot, ...) invokes
> tts_buffer_heap_materialize() where an incorrect access to memory
> that became anonymous occurs, and that is detected by valgrind.
> If not detected, different consequences are possible (in the asan case
> it was memcpy with an incorrectly read extra large data_len).
I've tried to materialize newslot before the oldslot materialization
(in ExecFetchSlotHeapTuple(), where their common memory is released),
and it looks like it fixes the issue.
The similar thing done in 75e03eabe.
But I don't know the code good enough so maybe I'm missing something.
Best regards,
Alexander
Attachments:v1-01-Fix-memory-access-in-BRU-trigger-DRAFT.patch (text/x-patch, 469B) downloaddiff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.cindex 66401f2839..a409ff0be1 100644--- a/src/backend/commands/trigger.c+++ b/src/backend/commands/trigger.c@@ -2992,6 +2992,8 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
if (newslot != epqslot_clean)
ExecCopySlot(newslot, epqslot_clean);
+ else+ ExecMaterializeSlot(newslot);
}
trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig);
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: exclusion@gmail.com, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17798: Incorrect memory access occurs when using BEFORE ROW UPDATE trigger
In-Reply-To: <87fe6c28-80b2-f709-a8db-d105e5240e39@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox