mirror of
https://github.com/postgres/postgres.git
synced 2025-07-24 14:22:24 +03:00
pg_logicalinspect: Fix possible crash when passing a directory path.
Previously, pg_logicalinspect functions were too trusting of their input and blindly passed it to SnapBuildRestoreSnapshot(). If the input pointed to a directory, the server could a PANIC error while attempting to fsync_fname() with isdir=false on a directory. This commit adds validation checks for input filenames and passes the LSN extracted from the filename to SnapBuildRestoreSnapshot() instead of the filename itself. It also adds regression tests for various input patterns and permission checks. Bug: #18828 Reported-by: Robins Tharakan <tharakan@gmail.com> Co-authored-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Co-authored-by: Masahiko Sawada <sawada.mshk@gmail.com> Discussion: https://postgr.es/m/18828-0f4701c635064211@postgresql.org
This commit is contained in:
@ -1691,12 +1691,17 @@ out:
|
||||
* If 'missing_ok' is true, will not throw an error if the file is not found.
|
||||
*/
|
||||
bool
|
||||
SnapBuildRestoreSnapshot(SnapBuildOnDisk *ondisk, const char *path,
|
||||
SnapBuildRestoreSnapshot(SnapBuildOnDisk *ondisk, XLogRecPtr lsn,
|
||||
MemoryContext context, bool missing_ok)
|
||||
{
|
||||
int fd;
|
||||
pg_crc32c checksum;
|
||||
Size sz;
|
||||
char path[MAXPGPATH];
|
||||
|
||||
sprintf(path, "%s/%X-%X.snap",
|
||||
PG_LOGICAL_SNAPSHOTS_DIR,
|
||||
LSN_FORMAT_ARGS(lsn));
|
||||
|
||||
fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
|
||||
|
||||
@ -1788,18 +1793,13 @@ static bool
|
||||
SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
|
||||
{
|
||||
SnapBuildOnDisk ondisk;
|
||||
char path[MAXPGPATH];
|
||||
|
||||
/* no point in loading a snapshot if we're already there */
|
||||
if (builder->state == SNAPBUILD_CONSISTENT)
|
||||
return false;
|
||||
|
||||
sprintf(path, "%s/%X-%X.snap",
|
||||
PG_LOGICAL_SNAPSHOTS_DIR,
|
||||
LSN_FORMAT_ARGS(lsn));
|
||||
|
||||
/* validate and restore the snapshot to 'ondisk' */
|
||||
if (!SnapBuildRestoreSnapshot(&ondisk, path, builder->context, true))
|
||||
if (!SnapBuildRestoreSnapshot(&ondisk, lsn, builder->context, true))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user