From 4a842a1d6570b0875fb705e6335a16b525cbbd79 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 22 Oct 2026 16:45:06 +0900 Subject: [PATCH] Reject overlong LSN components in START_REPLICATION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The replication command scanner accepts arbitrarily long hexadecimal LSN components, but converts them with sscanf("%X/%08X") into uint32 values. An overlong high component can overflow, while an overlong low component is truncated to its first eight digits. This can cause START_REPLICATION to use a different WAL location from the one requested. Use pg_parse_lsn() to validate and convert the complete LSN token, requiring one to eight hexadecimal digits per component, as for pg_lsn input. This applies to both physical and logical replication. Reported-by: ♂π≌26218 <1991230470@qq.com> Author: Ayush Tiwari Reviewed-by: Hayato Kuroda Reviewed-by: Jan Nidzwetzki Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/tencent_C6ED19DF1759CDD37E786F7EE0B5207D0009@qq.com --- src/backend/replication/repl_scanner.l | 6 ++---- src/test/recovery/t/006_logical_decoding.pl | 12 ++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 70b137acedc..af1615f9dbf 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -15,6 +15,7 @@ */ #include "postgres.h" +#include "common/pg_parse_lsn.h" #include "nodes/parsenodes.h" #include "utils/builtins.h" #include "parser/scansup.h" @@ -153,11 +154,8 @@ UPLOAD_MANIFEST { return K_UPLOAD_MANIFEST; } } {hexdigit}+\/{hexdigit}+ { - uint32 hi, - lo; - if (sscanf(yytext, "%X/%08X", &hi, &lo) != 2) + if (!pg_parse_lsn(yytext, &yylval->recptr)) replication_yyerror(NULL, yyscanner, "invalid streaming start location"); - yylval->recptr = ((uint64) hi) << 32 | lo; return RECPTR; } diff --git a/src/test/recovery/t/006_logical_decoding.pl b/src/test/recovery/t/006_logical_decoding.pl index ab8364fee7a..d8adb4c3050 100644 --- a/src/test/recovery/t/006_logical_decoding.pl +++ b/src/test/recovery/t/006_logical_decoding.pl @@ -45,6 +45,18 @@ like( qr/replication slot "test_slot" was not created in this database/, "Logical decoding correctly fails to start"); +for my $lsn ('123456789/0', '0/123456789') +{ + ($result, $stdout, $stderr) = $node_primary->psql( + 'template1', + qq[START_REPLICATION $lsn], + replication => 'database'); + like( + $stderr, + qr/invalid streaming start location/, + "START_REPLICATION rejects overlong LSN $lsn"); +} + ($result, $stdout, $stderr) = $node_primary->psql( 'template1', qq[READ_REPLICATION_SLOT test_slot;],