BUG #19092: scram_free() will free on address which was not malloc()-ed in pg_scram_mech

Started by PG Bug reporting form6 months ago5 messagesbugs
Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

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.

#2Daniel Gustafsson
daniel@yesql.se
In reply to: PG Bug reporting form (#1)
Re: BUG #19092: scram_free() will free on address which was not malloc()-ed in pg_scram_mech

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

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Gustafsson (#2)
Re: BUG #19092: scram_free() will free on address which was not malloc()-ed in pg_scram_mech

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

#4Michael Paquier
michael@paquier.xyz
In reply to: Tom Lane (#3)
Re: BUG #19092: scram_free() will free on address which was not malloc()-ed in pg_scram_mech

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

#5Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Michael Paquier (#4)
Re: BUG #19092: scram_free() will free on address which was not malloc()-ed in pg_scram_mech

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