From 505537d0435c7ba97917a084f184079a95058871 Mon Sep 17 00:00:00 2001 From: Shihao Date: Thu, 1 Oct 2026 22:03:02 -0600 Subject: [PATCH v1] Reject CR and LF in backup labels The label is written as one line of the backup_label file. A label with a newline added extra lines to the file, and recovery could read those as other fields or fail on them. Reject such labels in do_pg_backup_start(), which covers both pg_backup_start() and BASE_BACKUP. Bug: #19730 Reported-by: Shallow Discussion: https://postgr.es/m/19730-85a6044c9e72774a@postgresql.org --- src/backend/access/transam/xlog.c | 6 ++++++ src/test/recovery/t/020_archive_status.pl | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 9ec0be77ca0..b90ce916457 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -9995,6 +9995,12 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces, errmsg("backup label too long (max %d bytes)", MAXPGPATH))); + /* The label is stored as a single line of the backup_label file. */ + if (strpbrk(backupidstr, "\n\r")) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("backup label contains a newline or carriage return character"))); + strlcpy(state->name, backupidstr, sizeof(state->name)); /* diff --git a/src/test/recovery/t/020_archive_status.pl b/src/test/recovery/t/020_archive_status.pl index 5bb8aa9ec17..94d49751f7c 100644 --- a/src/test/recovery/t/020_archive_status.pl +++ b/src/test/recovery/t/020_archive_status.pl @@ -260,6 +260,19 @@ $cmdret = $primary->psql( stderr => \$stderr); is($cmdret, 3, "psql fails correctly"); like($stderr, qr/backup label too long/, "pg_backup_start fails gracefully"); + +# Newlines and carriage returns are not allowed in backup labels +foreach my $label ("E'one\\nbackup'", "E'one\\rbackup'") +{ + $primary->psql( + 'postgres', + "SELECT pg_backup_start($label)", + stderr => \$stderr); + like( + $stderr, + qr/backup label contains a newline or carriage return character/, + "pg_backup_start rejects label $label"); +} $primary->safe_psql('postgres', "SELECT pg_backup_start('onebackup'); SELECT pg_backup_stop();"); $primary->safe_psql('postgres', "SELECT pg_backup_start('twobackup')"); -- 2.37.1 (Apple Git-137.1)