From 0da940ea2d3cc40a634ad92e21ee8e8e6de3cbe8 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 2 Apr 2020 14:49:30 -0400 Subject: [PATCH v19 4/4] Recheck file size at checksum time. --- src/bin/pg_validatebackup/pg_validatebackup.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/bin/pg_validatebackup/pg_validatebackup.c b/src/bin/pg_validatebackup/pg_validatebackup.c index 5789b3f3a9..f274638500 100644 --- a/src/bin/pg_validatebackup/pg_validatebackup.c +++ b/src/bin/pg_validatebackup/pg_validatebackup.c @@ -714,6 +714,7 @@ validate_file_checksum(validator_context *context, manifest_file *m, char *relpath = m->pathname; int fd; int rc; + size_t bytes_read = 0; uint8 buffer[READ_CHUNK_SIZE]; uint8 checksumbuf[PG_CHECKSUM_MAX_LENGTH]; int checksumlen; @@ -731,7 +732,10 @@ validate_file_checksum(validator_context *context, manifest_file *m, /* Read the file chunk by chunk, updating the checksum as we go. */ while ((rc = read(fd, buffer, READ_CHUNK_SIZE)) > 0) + { + bytes_read += rc; pg_checksum_update(&checksum_ctx, buffer, rc); + } if (rc < 0) report_backup_error(context, "could not read file \"%s\": %m", relpath); @@ -748,6 +752,21 @@ validate_file_checksum(validator_context *context, manifest_file *m, if (rc < 0) return; + /* + * Double-check that we read the expected number of bytes from the file. + * Normally, a file size mismatch would be caught in validate_backup_file + * and this check would never be reached, but this provides additional + * safety and clarity in the event of concurrent modifications or + * filesystem misbehavior. + */ + if (bytes_read != m->size) + { + report_backup_error(context, + "file \"%s\" should contain %zu bytes, but read %zu bytes", + relpath, m->size, bytes_read); + return; + } + /* Get the final checksum. */ checksumlen = pg_checksum_final(&checksum_ctx, checksumbuf); -- 2.17.2 (Apple Git-113)