Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit23a7835

Browse files
committed
Error when creating names too long for tar format
The tar format (at least the version we are using), does not supportfile names or symlink targets longer than 99 bytes. Until now, the tarcreation code would silently truncate any names that are too long. (Itsoriginal application was pg_dump, where this never happens.) Thiscreates problems when running base backups over the replicationprotocol.The most important problem is when a tablespace path is longer than 99bytes, which will result in a truncated tablespace path being backed up.Less importantly, the basebackup protocol also promises to back up anyother files it happens to find in the data directory, which would alsolead to file name truncation if someone put a file with a long name inthere.Now both of these cases result in an error during the backup.Add tests that fail when a too-long file name or symlink is attempted tobe backed up.Reviewed-by: Robert Hass <robertmhaas@gmail.com>
1 parent347c743 commit23a7835

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

‎src/backend/replication/basebackup.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1258,11 +1258,30 @@ _tarWriteHeader(const char *filename, const char *linktarget,
12581258
structstat*statbuf)
12591259
{
12601260
charh[512];
1261+
enumtarErrorrc;
12611262

1262-
tarCreateHeader(h,filename,linktarget,statbuf->st_size,
1263+
rc=tarCreateHeader(h,filename,linktarget,statbuf->st_size,
12631264
statbuf->st_mode,statbuf->st_uid,statbuf->st_gid,
12641265
statbuf->st_mtime);
12651266

1267+
switch (rc)
1268+
{
1269+
caseTAR_OK:
1270+
break;
1271+
caseTAR_NAME_TOO_LONG:
1272+
ereport(ERROR,
1273+
(errmsg("file name too long for tar format: \"%s\"",
1274+
filename)));
1275+
break;
1276+
caseTAR_SYMLINK_TOO_LONG:
1277+
ereport(ERROR,
1278+
(errmsg("symbolic link target too long for tar format: file name \"%s\", target \"%s\"",
1279+
filename,linktarget)));
1280+
break;
1281+
default:
1282+
elog(ERROR,"unrecognized tar error: %d",rc);
1283+
}
1284+
12661285
pq_putmessage('d',h,512);
12671286
}
12681287

‎src/bin/pg_basebackup/t/010_pg_basebackup.pl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use warnings;
33
use Cwd;
44
use TestLib;
5-
use Test::Moretests=>33;
5+
use Test::Moretests=>35;
66

77
program_help_ok('pg_basebackup');
88
program_version_ok('pg_basebackup');
@@ -49,6 +49,13 @@
4949
'tar format');
5050
ok(-f"$tempdir/tarbackup/base.tar",'backup tar was created');
5151

52+
my$superlongname ="superlongname_" . ("x"x100);
53+
54+
system_or_bail'touch',"$tempdir/pgdata/$superlongname";
55+
command_fails(['pg_basebackup','-D',"$tempdir/tarbackup_l1",'-Ft' ],
56+
'pg_basebackup tar with long name fails');
57+
unlink"$tempdir/pgdata/$superlongname";
58+
5259
# Create a temporary directory in the system location and symlink it
5360
# to our physical temp location. That way we can use shorter names
5461
# for the tablespace directories, which hopefully won't run afoul of
@@ -117,3 +124,9 @@
117124
command_fails(
118125
['pg_basebackup','-D',"$tempdir/backup_foo",'-Fp',"-Tfoo" ],
119126
'-T with invalid format fails');
127+
128+
mkdir"$tempdir/$superlongname";
129+
psql'postgres',"CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
130+
command_fails(['pg_basebackup','-D',"$tempdir/tarbackup_l3",'-Ft' ],
131+
'pg_basebackup tar with long symlink target fails');
132+
psql'postgres',"DROP TABLESPACE tblspc3;";

‎src/include/pgtar.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,13 @@
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
14-
externvoidtarCreateHeader(char*h,constchar*filename,constchar*linktarget,size_tsize,mode_tmode,uid_tuid,gid_tgid,time_tmtime);
14+
15+
enumtarError
16+
{
17+
TAR_OK=0,
18+
TAR_NAME_TOO_LONG,
19+
TAR_SYMLINK_TOO_LONG
20+
};
21+
22+
externenumtarErrortarCreateHeader(char*h,constchar*filename,constchar*linktarget,size_tsize,mode_tmode,uid_tuid,gid_tgid,time_tmtime);
1523
externinttarChecksum(char*header);

‎src/port/tar.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,16 @@ tarChecksum(char *header)
4949
* must always have space for 512 characters, which is a requirement by
5050
* the tar format.
5151
*/
52-
void
52+
enumtarError
5353
tarCreateHeader(char*h,constchar*filename,constchar*linktarget,
5454
size_tsize,mode_tmode,uid_tuid,gid_tgid,time_tmtime)
5555
{
56+
if (strlen(filename)>99)
57+
returnTAR_NAME_TOO_LONG;
58+
59+
if (linktarget&&strlen(linktarget)>99)
60+
returnTAR_SYMLINK_TOO_LONG;
61+
5662
/*
5763
* Note: most of the fields in a tar header are not supposed to be
5864
* null-terminated. We use sprintf, which will write a null after the
@@ -141,4 +147,6 @@ tarCreateHeader(char *h, const char *filename, const char *linktarget,
141147
* 6 digits, a space, and a null, which is legal per POSIX.
142148
*/
143149
sprintf(&h[148],"%06o ",tarChecksum(h));
150+
151+
returnTAR_OK;
144152
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp