BUG #19092: scram_free() will free on address which was not malloc()-ed in pg_scram_mech
The following bug has been logged on the website:
Bug reference: 19092
Logged by: NJUEEXRM
Email address: 13952878799@163.com
PostgreSQL version: 17.0
Operating system: MacOS 12.7.6
Description:
The issue is about the only implementation of pg_fe_sasl_mech interface:
pg_scram_mech. In the init func of pg_scram_mech, the variable
state->password is assigned by variable prep_password, which is prepared in
function pg_saslprep(). However, pg_saslprep() will use palloc/pfree or
malloc/free determined by FRONTEND marco。If we are in backend env,the
prep_password will be palloc-ed in CurrentMemoryContext. The problem is
state->password will be released by free() in the free func of
pg_scram_mech: scram_free, and will cause 'free on address which was not
malloc()-ed' error.
This issue occurred when I was attempting to make a connection to Backend
via libpq interfaces in Backend itself.
On 21 Oct 2025, at 09:43, PG Bug reporting form <noreply@postgresql.org> wrote:
The issue is about the only implementation of pg_fe_sasl_mech interface:
pg_scram_mech. In the init func of pg_scram_mech, the variable
state->password is assigned by variable prep_password, which is prepared in
function pg_saslprep(). However, pg_saslprep() will use palloc/pfree or
malloc/free determined by FRONTEND marco。If we are in backend env,the
prep_password will be palloc-ed in CurrentMemoryContext. The problem is
state->password will be released by free() in the free func of
pg_scram_mech: scram_free, and will cause 'free on address which was not
malloc()-ed' error.
Mixing frontend and backend code like that seems to register somewhere on the
"break it and you get to keep both pieces" scale.
This issue occurred when I was attempting to make a connection to Backend
via libpq interfaces in Backend itself.
You tried to open a new database connection from a backend by embedding a libpq
client into the backend? Which problem are you trying to solve, maybe there is
an easier way?
--
Daniel Gustafsson
Daniel Gustafsson <daniel@yesql.se> writes:
On 21 Oct 2025, at 09:43, PG Bug reporting form <noreply@postgresql.org> wrote:
The issue is about the only implementation of pg_fe_sasl_mech interface:
pg_scram_mech. In the init func of pg_scram_mech, the variable
state->password is assigned by variable prep_password, which is prepared in
function pg_saslprep(). However, pg_saslprep() will use palloc/pfree or
malloc/free determined by FRONTEND
Mixing frontend and backend code like that seems to register somewhere on the
"break it and you get to keep both pieces" scale.
We'd really need to see a concrete example to decide whether this is
a PG bug or user error. I think the SASL stuff is sufficiently poorly
tested that it could be a previously-unknown PG bug, but it's not clear.
So: test case, please.
This issue occurred when I was attempting to make a connection to Backend
via libpq interfaces in Backend itself.
You tried to open a new database connection from a backend by embedding a libpq
client into the backend?
postgres_fdw and dblink both do that. The operation is ticklish
enough that we've developed some common infrastructure, which
maybe you should be using: see src/include/libpq/libpq-be-fe.h
and src/include/libpq/libpq-be-fe-helpers.h.
regards, tom lane
On Tue, Oct 21, 2025 at 11:06:19AM -0400, Tom Lane wrote:
We'd really need to see a concrete example to decide whether this is
a PG bug or user error. I think the SASL stuff is sufficiently poorly
tested that it could be a previously-unknown PG bug, but it's not clear.
[ .. double-checking the code .. ]
FWIW, I doubt that this is something we need to worry about and I
suspect that there is no action item here. dblink and WAL receivers
do their stuff so as the main backend code does not link with libpq,
and I doubt that we'd ever want to enter in the territory where
FRONTEND becomes a thing in libpq.
Of course, I may prove wrong.
So: test case, please.
Yes.
--
Michael
On Wed, Oct 22, 2025 at 5:29 PM Michael Paquier <michael@paquier.xyz> wrote:
So: test case, please.
Yes.
Thirded.
The only thing I can think of at the moment -- which a test case would
quickly prove or disprove -- is that the symbol visibility is messed
up for this particular build in some way, and libpq's pg_saslprep has
been incorrectly preempted by postgres' pg_saslprep. But I can't
reproduce anything like that with my local macOS build.
--Jacob