Backup manifests accept out-of-range LSNs

Started by Ayush Tiwari4 days ago2 messageshackers
Jump to latest
#1Ayush Tiwari
ayushtiwari.slg01@gmail.com

Hi,

355814931141 tightened the integer fields of a backup manifest, but
parse_xlogrecptr() in the same file still does:

if (sscanf(input, "%X/%08X", &hi, &lo) != 2)

"%X" stores into a uint32, so an oversized half is accepted with its
high bits dropped, and trailing text is ignored, since sscanf() still
returns 2. "123456789/0" is read as 23456789/0 and "1/2garbage" as
1/2, while "oops" is rejected as before.

That value validates the WAL ranges of a backup, in pg_verifybackup,
pg_combinebackup and the server's incremental backup path, so those
checks end up using a location the manifest doesn't contain.

The attached requires one to eight hex digits per half and the whole
string consumed, matching pg_lsn_in_safe(), and adds a few cases to
005_bad_manifest.pl. I stayed away from the strtoul()/endptr idiom the
neighbouring parsers use, since strtoul("-1", ..., 16) returns
ULONG_MAX without setting ERANGE, so "-1/0" would slip through as
FFFFFFFF/0.

Thoughts?

Regards,
Ayush

Attachments:

0001-Reject-out-of-range-LSNs-in-backup-manifests.patchapplication/octet-stream; name=0001-Reject-out-of-range-LSNs-in-backup-manifests.patchDownload+32-2
#2Yuefei Shi
shiyuefei1004@gmail.com
In reply to: Ayush Tiwari (#1)
Re: Backup manifests accept out-of-range LSNs

Reviewed this patch.

The issue seems valid. PostgreSQL-generated manifests should not normally
contain such LSNs, but a malformed or modified manifest could make the
parser operate on a different LSN than the one specified. The current
sscanf() based parser allows this through truncation of oversized
components and ignored trailing characters.

The proposed fix looks good and the tests cover the regression cases.

Show quoted text