1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Reject CR and LF characters 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, failing on them.  Characters could also be
injected to make recovery behave in inconsistent ways.

Trying to use such characters in label names is now rejected, for both
pg_backup_start() and BASE_BACKUP.

As this is arguably a behavior change, no backpatch is done.  I also
seriously doubt that anybody is relying on the behavior of pushing some
arbitrary data to backup_label files, and even if they do, it would be a
very bad idea to contradict what the backend decides to generate.

Reported-by: Shallow <theshallow27@gmail.com>
Author: Shihao Zhong <zhong950419@gmail.com>
Discussion: https://postgr.es/m/19730-85a6044c9e72774a@postgresql.org
This commit is contained in:
Michael Paquier
2026-10-05 12:46:19 +09:00
parent a7f8cd811d
commit e624e1fd13
2 changed files with 18 additions and 0 deletions

View File

@@ -9995,6 +9995,11 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
errmsg("backup label too long (max %d bytes)",
MAXPGPATH)));
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));
/*

View File

@@ -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')");