mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-08-16 22:36:05 +00:00
Check if the dumpdir read from the archive is well-formed before using it.
* src/common.h (dumpdir_ok): New proto. * src/incremen.c (dumpdir_ok): Take size as the second argument. Verify if the last byte is 0 and the dumpdir contains 0 or more nul-terminated strings. (get_gnu_dumpdir): Check if the obtained dumpdir is ok. Clear the is_dumpdir flag if it is not. * src/xheader.c (dumpdir_decoder) Verify if the obtained dumpdir is ok.
This commit is contained in:
@@ -589,6 +589,7 @@ void purge_directory (char const *directory_name);
|
||||
void list_dumpdir (char *buffer, idx_t size);
|
||||
void update_parent_directory (struct tar_stat_info *st);
|
||||
|
||||
bool dumpdir_ok (char const *dumpdir, idx_t size);
|
||||
idx_t dumpdir_size (const char *p);
|
||||
bool is_dumpdir (struct tar_stat_info *stat_info);
|
||||
void clear_directory_table (void);
|
||||
|
||||
+17
-7
@@ -123,6 +123,7 @@ dir_set_flag (struct directory *d, int f)
|
||||
{
|
||||
d->flags |= f;
|
||||
}
|
||||
|
||||
static void
|
||||
dir_clear_flag (struct directory *d, int f)
|
||||
{
|
||||
@@ -1525,6 +1526,12 @@ get_gnu_dumpdir (struct tar_stat_info *stat_info)
|
||||
|
||||
mv_end ();
|
||||
|
||||
if (!dumpdir_ok (archive_dir, stat_info->stat.st_size))
|
||||
{
|
||||
stat_info->is_dumpdir = false;
|
||||
free (archive_dir);
|
||||
archive_dir = NULL;
|
||||
}
|
||||
stat_info->dumpdir = archive_dir;
|
||||
stat_info->skipped = true; /* For skip_member() and friends
|
||||
to work correctly */
|
||||
@@ -1541,13 +1548,20 @@ is_dumpdir (struct tar_stat_info *stat_info)
|
||||
return stat_info->is_dumpdir;
|
||||
}
|
||||
|
||||
static bool
|
||||
dumpdir_ok (char *dumpdir)
|
||||
bool
|
||||
dumpdir_ok (char const *dumpdir, idx_t size)
|
||||
{
|
||||
char *p;
|
||||
char const *p;
|
||||
bool has_tempdir = false;
|
||||
char expect = '\0';
|
||||
|
||||
if (!(size > 0 &&
|
||||
dumpdir[size-1] == 0 && (size == 1 || dumpdir[size-2] == 0)))
|
||||
{
|
||||
paxerror (0, _("Malformed dumpdir: missing terminator"));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (p = dumpdir; *p; p += strlen (p) + 1)
|
||||
{
|
||||
if (expect && *p != expect)
|
||||
@@ -1640,10 +1654,6 @@ purge_directory (char const *directory_name)
|
||||
case, we don't have to delete any files out of it. */
|
||||
return;
|
||||
|
||||
/* Verify if dump directory is sane */
|
||||
if (!dumpdir_ok (current_stat_info.dumpdir))
|
||||
return;
|
||||
|
||||
/* Process renames */
|
||||
for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
|
||||
{
|
||||
|
||||
+7
-2
@@ -1483,8 +1483,13 @@ dumpdir_decoder (struct tar_stat_info *st,
|
||||
char const *arg,
|
||||
idx_t size)
|
||||
{
|
||||
st->dumpdir = ximalloc (size);
|
||||
memcpy (st->dumpdir, arg, size);
|
||||
if (dumpdir_ok (arg, size))
|
||||
{
|
||||
st->dumpdir = ximalloc (size);
|
||||
memcpy (st->dumpdir, arg, size);
|
||||
}
|
||||
else
|
||||
paxerror (0, _("Malformed dumpdir: missing terminator"));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user