v2-0003-Repair-various-defects-in-dc212340058b4e7ecfc5a7a.patch
application/octet-stream
Filename: v2-0003-Repair-various-defects-in-dc212340058b4e7ecfc5a7a.patch
Type: application/octet-stream
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0003
Subject: Repair various defects in dc212340058b4e7ecfc5a7a81ec50e7a207bf288.
| File | + | − |
|---|---|---|
| src/bin/pg_basebackup/pg_basebackup.c | 1 | 1 |
| src/bin/pg_combinebackup/pg_combinebackup.c | 9 | 6 |
| src/bin/pg_combinebackup/reconstruct.c | 2 | 3 |
| src/bin/pg_combinebackup/write_manifest.c | 5 | 5 |
| src/common/blkreftable.c | 1 | 1 |
From a866596debade4226ed8480838af124f262414fd Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 9 Jan 2024 13:12:43 -0500
Subject: [PATCH v2 3/3] Repair various defects in
dc212340058b4e7ecfc5a7a81ec50e7a207bf288.
pg_combinebackup had various problems:
* strncpy was used in various places where should be used instead,
to avoid any possibility of the result not being \0-terminated.
* scan_for_existing_tablespaces() failed to close the directory,
and an error when opening the directory was reported with the
wrong pathname.
* write_reconstructed_file() contained some redundant and therefore
dead code.
* flush_manifest() didn't check the result of pg_checksum_update()
as we do in other places, and misused a local pathname variable
that shouldn't exist at all.
In pg_basebackup, the wrong variable name was used in one place,
due to a copy and paste that was not properly adjusted.
In blkreftable.c, the loop incorrectly doubled chunkno instead of
max_chunks.
Per Coverity and subsequent code inspection by me and by Tom Lane.
---
src/bin/pg_basebackup/pg_basebackup.c | 2 +-
src/bin/pg_combinebackup/pg_combinebackup.c | 15 +++++++++------
src/bin/pg_combinebackup/reconstruct.c | 5 ++---
src/bin/pg_combinebackup/write_manifest.c | 10 +++++-----
src/common/blkreftable.c | 2 +-
5 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index b734cce5d4..3b3cc242e0 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -709,7 +709,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier,
PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
"pg_xlog" : "pg_wal");
- if (pg_mkdir_p(statusdir, pg_dir_create_mode) != 0 &&
+ if (pg_mkdir_p(summarydir, pg_dir_create_mode) != 0 &&
errno != EEXIST)
pg_fatal("could not create directory \"%s\": %m", summarydir);
}
diff --git a/src/bin/pg_combinebackup/pg_combinebackup.c b/src/bin/pg_combinebackup/pg_combinebackup.c
index 6027e241f3..31ead7f405 100644
--- a/src/bin/pg_combinebackup/pg_combinebackup.c
+++ b/src/bin/pg_combinebackup/pg_combinebackup.c
@@ -773,8 +773,8 @@ process_directory_recursively(Oid tsoid,
*/
if (relative_path == NULL)
{
- strncpy(ifulldir, input_directory, MAXPGPATH);
- strncpy(ofulldir, output_directory, MAXPGPATH);
+ strlcpy(ifulldir, input_directory, MAXPGPATH);
+ strlcpy(ofulldir, output_directory, MAXPGPATH);
if (OidIsValid(tsoid))
snprintf(manifest_prefix, MAXPGPATH, "pg_tblspc/%u/", tsoid);
else
@@ -855,7 +855,7 @@ process_directory_recursively(Oid tsoid,
/* Append new pathname component to relative path. */
if (relative_path == NULL)
- strncpy(new_relative_path, de->d_name, MAXPGPATH);
+ strlcpy(new_relative_path, de->d_name, MAXPGPATH);
else
snprintf(new_relative_path, MAXPGPATH, "%s/%s", relative_path,
de->d_name);
@@ -1131,7 +1131,7 @@ scan_for_existing_tablespaces(char *pathname, cb_options *opt)
pg_log_debug("scanning \"%s\"", pg_tblspc);
if ((dir = opendir(pg_tblspc)) == NULL)
- pg_fatal("could not open directory \"%s\": %m", pathname);
+ pg_fatal("could not open directory \"%s\": %m", pg_tblspc);
while (errno = 0, (de = readdir(dir)) != NULL)
{
@@ -1203,8 +1203,8 @@ scan_for_existing_tablespaces(char *pathname, cb_options *opt)
{
if (strcmp(tsmap->old_dir, link_target) == 0)
{
- strncpy(ts->old_dir, tsmap->old_dir, MAXPGPATH);
- strncpy(ts->new_dir, tsmap->new_dir, MAXPGPATH);
+ strlcpy(ts->old_dir, tsmap->old_dir, MAXPGPATH);
+ strlcpy(ts->new_dir, tsmap->new_dir, MAXPGPATH);
ts->in_place = false;
break;
}
@@ -1238,6 +1238,9 @@ scan_for_existing_tablespaces(char *pathname, cb_options *opt)
tslist = ts;
}
+ if (closedir(dir) != 0)
+ pg_fatal("could not close directory \"%s\": %m", pg_tblspc);
+
return tslist;
}
diff --git a/src/bin/pg_combinebackup/reconstruct.c b/src/bin/pg_combinebackup/reconstruct.c
index b835ec363e..873d307902 100644
--- a/src/bin/pg_combinebackup/reconstruct.c
+++ b/src/bin/pg_combinebackup/reconstruct.c
@@ -577,13 +577,12 @@ write_reconstructed_file(char *input_filename,
{
if (current_block == start_of_range)
appendStringInfo(&debug_buf, " %u:%s@" UINT64_FORMAT,
- current_block,
- s == NULL ? "ZERO" : s->filename,
+ current_block, s->filename,
(uint64) offsetmap[current_block]);
else
appendStringInfo(&debug_buf, " %u-%u:%s@" UINT64_FORMAT,
start_of_range, current_block,
- s == NULL ? "ZERO" : s->filename,
+ s->filename,
(uint64) offsetmap[current_block]);
}
diff --git a/src/bin/pg_combinebackup/write_manifest.c b/src/bin/pg_combinebackup/write_manifest.c
index 608e84f3b4..01deb82cc9 100644
--- a/src/bin/pg_combinebackup/write_manifest.c
+++ b/src/bin/pg_combinebackup/write_manifest.c
@@ -241,8 +241,6 @@ escape_json(StringInfo buf, const char *str)
static void
flush_manifest(manifest_writer *mwriter)
{
- char pathname[MAXPGPATH];
-
if (mwriter->fd == -1 &&
(mwriter->fd = open(mwriter->pathname,
O_WRONLY | O_CREAT | O_EXCL | PG_BINARY,
@@ -260,13 +258,15 @@ flush_manifest(manifest_writer *mwriter)
pg_fatal("could not write \"%s\": %m", mwriter->pathname);
else
pg_fatal("could not write file \"%s\": wrote only %d of %d bytes",
- pathname, (int) wb, mwriter->buf.len);
+ mwriter->pathname, (int) wb, mwriter->buf.len);
}
- if (mwriter->still_checksumming)
+ if (mwriter->still_checksumming &&
pg_checksum_update(&mwriter->manifest_ctx,
(uint8 *) mwriter->buf.data,
- mwriter->buf.len);
+ mwriter->buf.len) < 0)
+ pg_fatal("could not update checksum of file \"%s\"",
+ mwriter->pathname);
resetStringInfo(&mwriter->buf);
}
}
diff --git a/src/common/blkreftable.c b/src/common/blkreftable.c
index bf0b563a38..20c80c779e 100644
--- a/src/common/blkreftable.c
+++ b/src/common/blkreftable.c
@@ -988,7 +988,7 @@ BlockRefTableEntryMarkBlockModified(BlockRefTableEntry *entry,
*/
max_chunks = Max(16, entry->nchunks);
while (max_chunks < chunkno + 1)
- chunkno *= 2;
+ max_chunks *= 2;
Assert(max_chunks > chunkno);
extra_chunks = max_chunks - entry->nchunks;
--
2.39.3 (Apple Git-145)