From 931f3926a9f69e8de4a673b05b8e7a1fffc1d0d9 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 19 Oct 2021 12:59:50 +0200 Subject: [PATCH] Fix sscanf limits in pg_basebackup and pg_dump Make sure that the string parsing is limited by the size of the destination buffer. In pg_basebackup the available values sent from the server is limited to two characters so there was no risk of overflow. In pg_dump the buffer is bounded by MAXPGPATH, and thus the limit must be inserted via preprocessor expansion and the buffer increased by one to account for the terminator. There is no risk of overflow here, since in this case, the buffer scanned is smaller than the destination buffer. Backpatch the pg_basebackup fix to 11 where it was introduced, and the pg_dump fix all the way down to 9.6. Reviewed-by: Tom Lane Discussion: https://postgr.es/m/B14D3D7B-F98C-4E20-9459-C122C67647FB@yesql.se Backpatch-through: 11 and 9.6 --- src/bin/pg_basebackup/streamutil.c | 2 +- src/bin/pg_dump/pg_backup_directory.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 9309a8de955..1510b7cc088 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -316,7 +316,7 @@ RetrieveWalSegSize(PGconn *conn) } /* fetch xlog value and unit from the result */ - if (sscanf(PQgetvalue(res, 0, 0), "%d%s", &xlog_val, xlog_unit) != 2) + if (sscanf(PQgetvalue(res, 0, 0), "%d%2s", &xlog_val, xlog_unit) != 2) { fprintf(stderr, _("%s: WAL segment size could not be parsed\n"), progname); diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index fe1f8e1e33f..2c75caec488 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -458,11 +458,11 @@ _LoadBlobs(ArchiveHandle *AH) /* Read the blobs TOC file line-by-line, and process each blob */ while ((cfgets(ctx->blobsTocFH, line, MAXPGPATH)) != NULL) { - char fname[MAXPGPATH]; + char fname[MAXPGPATH + 1]; char path[MAXPGPATH]; /* Can't overflow because line and fname are the same length. */ - if (sscanf(line, "%u %s\n", &oid, fname) != 2) + if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, fname) != 2) exit_horribly(modulename, "invalid line in large object TOC file \"%s\": \"%s\"\n", fname, line);