Re: BUG #19547: libpqrcv_create_slot dereferences NULL on a malformed CREATE_REPLICATION_SLOT reply

Started by Kenny Chen1 day ago8 messagesbugs
Jump to latest
#1Kenny Chen
kennychen851228@gmail.com

Hi,

Thanks for the detailed report and analysis. Here is a patch.

libpqrcv_create_slot() only checked PGRES_TUPLES_OK before reading the
consistent-point LSN and snapshot name from the first row, so a reply with
zero rows made PQgetvalue(res, 0, 1) return NULL, which pg_lsn_in() then
dereferenced -> crash in the tablesync worker.

The patch validates the result shape (>= 3 fields, exactly 1 row) before
reading those fields and raises a protocol-violation error otherwise,
mirroring what libpqrcv_identify_system() and the other result-consuming
paths in this file already do. I used "< 3" rather than "< 4" because the
function only reads fields 1 and 2.

Builds cleanly and "meson test --suite subscription" passes. I could not
find a good way to add a regression test, since it needs a rogue server
that returns a malformed reply; suggestions welcome.

Regards,
Kenny

Attachments:

v1-0001-Avoid-crash-on-malformed-CREATE_REPLICATION_SLOT-.patchapplication/octet-stream; name=v1-0001-Avoid-crash-on-malformed-CREATE_REPLICATION_SLOT-.patchDownload+13-1
#2Hayato Kuroda (Fujitsu)
kuroda.hayato@fujitsu.com
In reply to: Kenny Chen (#1)
RE: BUG #19547: libpqrcv_create_slot dereferences NULL on a malformed CREATE_REPLICATION_SLOT reply

Hi Kenny,

The patch validates the result shape (>= 3 fields, exactly 1 row) before
reading those fields and raises a protocol-violation error otherwise,
mirroring what libpqrcv_identify_system() and the other result-consuming
paths in this file already do. I used "< 3" rather than "< 4" because the
function only reads fields 1 and 2.

Hmm, but IDENTIFY_SYSTEM requires that number returned attributes should be 3 or
4, nevertheless first and second columns are checked. If we follow, isn't it
better to require that there are 4 attributes? I checked old versions and the
command has returned 4 attributes from the beginning [1]https://github.com/postgres/postgres/blob/b1b8b8e6f141e378db21c609d8ee74d9125a4aca/src/backend/replication/walsender.c#L853.

[1]: https://github.com/postgres/postgres/blob/b1b8b8e6f141e378db21c609d8ee74d9125a4aca/src/backend/replication/walsender.c#L853

Best regards,
Hayato Kuroda
FUJITSU LIMITED

#3Kenny Chen
kennychen851228@gmail.com
In reply to: Hayato Kuroda (Fujitsu) (#2)

Hi Hayato,

Thanks for looking at this.

Hmm, but IDENTIFY_SYSTEM requires that number returned attributes should be 3 or
4, nevertheless first and second columns are checked. If we follow, isn't it
better to require that there are 4 attributes? I checked old versions and the
command has returned 4 attributes from the beginning [1].

Agreed. IDENTIFY_SYSTEM tolerates 3 columns only because older servers (9.3
and earlier) actually returned 3, whereas CREATE_REPLICATION_SLOT has always
returned 4, so there is no reason to be lenient here. v2 attached requires 4
fields, and updates the comment and errdetail accordingly.

Best regards,
Kenny Chen

Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> 於 2026年7月15日週三 下午12:33寫道:

Show quoted text

Hi Kenny,

The patch validates the result shape (>= 3 fields, exactly 1 row) before
reading those fields and raises a protocol-violation error otherwise,
mirroring what libpqrcv_identify_system() and the other result-consuming
paths in this file already do. I used "< 3" rather than "< 4" because the
function only reads fields 1 and 2.

Hmm, but IDENTIFY_SYSTEM requires that number returned attributes should be 3 or
4, nevertheless first and second columns are checked. If we follow, isn't it
better to require that there are 4 attributes? I checked old versions and the
command has returned 4 attributes from the beginning [1].

[1]: https://github.com/postgres/postgres/blob/b1b8b8e6f141e378db21c609d8ee74d9125a4aca/src/backend/replication/walsender.c#L853

Best regards,
Hayato Kuroda
FUJITSU LIMITED

Attachments:

v2-0001-Avoid-crash-on-malformed-CREATE_REPLICATION_SLOT-.patchapplication/octet-stream; name=v2-0001-Avoid-crash-on-malformed-CREATE_REPLICATION_SLOT-.patchDownload+13-1
#4Fujii Masao
masao.fujii@gmail.com
In reply to: Kenny Chen (#3)

On Wed, Jul 15, 2026 at 8:51 PM Kenny Chen <kennychen851228@gmail.com> wrote:

Agreed. IDENTIFY_SYSTEM tolerates 3 columns only because older servers (9.3
and earlier) actually returned 3, whereas CREATE_REPLICATION_SLOT has always
returned 4, so there is no reason to be lenient here. v2 attached requires 4
fields, and updates the comment and errdetail accordingly.

Agreed. So,

+       if (PQnfields(res) < 4 || PQntuples(res) != 1)
+               ereport(ERROR,
+                               (errcode(ERRCODE_PROTOCOL_VIOLATION),
+                                errmsg("invalid response from primary server"),
+                                errdetail("Could not create
replication slot \"%s\": got %d rows and %d fields, expected %d rows
and %d or more fields.",
+                                                  slotname,
PQntuples(res), PQnfields(res), 1, 4)));

"PQnfields(res) < 4" should be "PQnfields(res) != 4"?
If so, "or more" in the detail message should be removed as well.

Regards,

--
Fujii Masao

#5Kenny Chen
kennychen851228@gmail.com
In reply to: Fujii Masao (#4)

Hi Fujii,

"PQnfields(res) < 4" should be "PQnfields(res) != 4"?
If so, "or more" in the detail message should be removed as well.

Right, CREATE_REPLICATION_SLOT always returns exactly 4 columns, so != 4 is
more accurate. v3 attached uses != 4 and drops "or more" from the errdetail.

Regards,
Kenny

Fujii Masao <masao.fujii@gmail.com> 於 2026年7月15日週三 下午10:10寫道:

Show quoted text

On Wed, Jul 15, 2026 at 8:51 PM Kenny Chen <kennychen851228@gmail.com> wrote:

Agreed. IDENTIFY_SYSTEM tolerates 3 columns only because older servers (9.3
and earlier) actually returned 3, whereas CREATE_REPLICATION_SLOT has always
returned 4, so there is no reason to be lenient here. v2 attached requires 4
fields, and updates the comment and errdetail accordingly.

Agreed. So,

+       if (PQnfields(res) < 4 || PQntuples(res) != 1)
+               ereport(ERROR,
+                               (errcode(ERRCODE_PROTOCOL_VIOLATION),
+                                errmsg("invalid response from primary server"),
+                                errdetail("Could not create
replication slot \"%s\": got %d rows and %d fields, expected %d rows
and %d or more fields.",
+                                                  slotname,
PQntuples(res), PQnfields(res), 1, 4)));

"PQnfields(res) < 4" should be "PQnfields(res) != 4"?
If so, "or more" in the detail message should be removed as well.

Regards,

--
Fujii Masao

Attachments:

v3-0001-Avoid-crash-on-malformed-CREATE_REPLICATION_SLOT-.patchapplication/octet-stream; name=v3-0001-Avoid-crash-on-malformed-CREATE_REPLICATION_SLOT-.patchDownload+13-1
#6Hayato Kuroda (Fujitsu)
kuroda.hayato@fujitsu.com
In reply to: Kenny Chen (#5)
RE: BUG #19547: libpqrcv_create_slot dereferences NULL on a malformed CREATE_REPLICATION_SLOT reply

Dear Kenny,

Right, CREATE_REPLICATION_SLOT always returns exactly 4 columns, so != 4 is
more accurate. v3 attached uses != 4 and drops "or more" from the errdetail.

Basically LGTM. From my perspective the code comment might be too detail:
"CREATE_REPLICATION_SLOT has always returned a single row with four columns"
might be enough. But it's not the strong opinion - let's confirm the Fujii-san's idea.

Best regards,
Hayato Kuroda
FUJITSU LIMITED

#7Fujii Masao
masao.fujii@gmail.com
In reply to: Hayato Kuroda (Fujitsu) (#6)

On Thu, Jul 16, 2026 at 9:36 AM Hayato Kuroda (Fujitsu)
<kuroda.hayato@fujitsu.com> wrote:

Dear Kenny,

Right, CREATE_REPLICATION_SLOT always returns exactly 4 columns, so != 4 is
more accurate. v3 attached uses != 4 and drops "or more" from the errdetail.

Basically LGTM. From my perspective the code comment might be too detail:
"CREATE_REPLICATION_SLOT has always returned a single row with four columns"
might be enough.

+1

So I've updated the comment to a simpler version and pushed the patch. Thanks!

Regards,

--
Fujii Masao

#8Hayato Kuroda (Fujitsu)
kuroda.hayato@fujitsu.com
In reply to: Fujii Masao (#7)
RE: BUG #19547: libpqrcv_create_slot dereferences NULL on a malformed CREATE_REPLICATION_SLOT reply

Dear Fujii-san,

Confirmed that no BF animals reported any issues due to the commit.
Thanks!

Best regards,
Hayato Kuroda
FUJITSU LIMITED