From 3e55c9671c44e79ff0f1974f34a5db51896c09f1 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 28 Jun 2021 20:45:30 +0200
Subject: [PATCH v4 1/2] 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.

Discussion: https://postgr.es/m/B14D3D7B-F98C-4E20-9459-C122C67647FB@yesql.se
---
 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 f5b3b476e5..e18d852ff2 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -310,7 +310,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)
 	{
 		pg_log_error("WAL segment size could not be parsed");
 		PQclear(res);
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
index fb8c7713a5..57243c5971 100644
--- a/src/bin/pg_dump/pg_backup_directory.c
+++ b/src/bin/pg_dump/pg_backup_directory.c
@@ -449,11 +449,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)
 			fatal("invalid line in large object TOC file \"%s\": \"%s\"",
 				  fname, line);
 
-- 
2.30.1 (Apple Git-130)

