From d126ea36bddc19168b54c668a84c531f605f314d Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Fri, 3 Jul 2026 10:52:26 +0530 Subject: [PATCH v1] pg_dump: Validate archive entry filenames in directory format Filenames listed in directory-format TOC files (toc.dat and blobs_*.toc) are untrusted when reading an archive. If an archive entry filename contains path traversal elements such as ".." or directory separators, it could lead to reading files outside the intended archive directory. Add validation in setFilePath() to refuse empty filenames, filenames containing "..", or filenames with directory separators, raising a fatal error if any are found. In addition, update _LoadLOs() to construct large object file paths using setFilePath() rather than manual snprintf(), ensuring LO filenames read from blobs_*.toc undergo the same validation checks. --- src/bin/pg_dump/pg_backup_directory.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index c0b50223cec..2746c426462 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -434,7 +434,7 @@ _LoadLOs(ArchiveHandle *AH, TocEntry *te) tocfname, line); StartRestoreLO(AH, oid, AH->public.ropt->dropSchema); - snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, lofname); + setFilePath(AH, path, lofname); _PrintFileData(AH, path); EndRestoreLO(AH, oid); } @@ -686,6 +686,16 @@ setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename) dname = ctx->directory; + /* + * Per-entry filenames come from the (untrusted) toc.dat / blobs_*.toc. + * Refuse anything that is not a plain leaf name. + */ + if (relativeFilename[0] == '\0' || + strstr(relativeFilename, "..") != NULL || + first_dir_separator(relativeFilename) != NULL) + pg_fatal("invalid archive: entry filename \"%s\" is not a plain file name", + relativeFilename); + if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH) pg_fatal("file name too long: \"%s\"", dname); -- 2.49.0