postgres.git / summary / log / commit / refs

commit    d3a4c1eb3d2188e8df58b4f2837cd17acc8629e1
Author:   Daniel Gustafsson <dgustafsson@postgresql.org>
Date:     Tue Oct 19 10:59:50 2021 +0000
First released in: 15.0, 11.14, 12.9, 13.5, 14.1

    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 ad282ceb5dd..e2033b7e377 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -309,7 +309,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 cb0f7f31fd7..1e0aea4e254 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); [parent: 85dc4292a7a1]