BUG #19598: pg_waldump: -s/-e accept out-of-range WAL locations and silently use the low 32 bits
The following bug has been logged on the website:
Bug reference: 19598
Logged by: Michael Malis
Email address: malis@pgrust.com
PostgreSQL version: 18.3
Operating system: Debian
Description:
Both LSN-accepting options parse with sscanf(optarg, "%X/%X", &xlogid,
&xrecoff) into two uint32s, with no length or range check. %X converts via
strtoul: a component that overflows uint32 is truncated to its low 32 bits,
and one that overflows uint64 saturates and then truncates. In both cases
sscanf still returns 2, so the != 2 "invalid WAL location" guard never fires
and the tool proceeds with a value the user did not ask for. PostgreSQL's
own canonical LSN parser rejects the same input.
Reproducer (runnable against stock PostgreSQL 18.3)
---------------------------------------------------
$ pg_waldump -s 123456789/0 000000010000000000000040
pg_waldump: error: start WAL location 23456789/0 is not inside file
"000000010000000000000040"
Note the echoed value: the 9-hex-digit input 123456789 was silently reduced
to 23456789. The saturating case:
$ pg_waldump -s FFFFFFFFFFFFFFFFFFFF/0 000000010000000000000040
pg_waldump: error: start WAL location FFFFFFFF/0 is not inside file
"..."
Control — a genuinely malformed value is rejected, so the guard works, it
just never sees these inputs:
$ pg_waldump -s ZZZ/0 000000010000000000000040
pg_waldump: error: invalid WAL location: "ZZZ/0"
Contrast with the server's own parser on the identical string:
SELECT '123456789/0'::pg_lsn;
ERROR: invalid input syntax for type pg_lsn: "123456789/0"
Expected vs. actual
-------------------
- Expected: pg_waldump: error: invalid WAL location: "123456789/0", as for
any other unparseable value.
- Actual: the value is accepted, silently mangled to 23456789/0, and used.
The error text the user eventually sees reports the mangled location,
which actively misleads: it reads as "the location you asked for isn't in
this file" when the location asked for was never used.