Don't try to read past the end of header string fields

* src/common.h (assign_string_n): New proto.
(ASSIGN_STRING_N): New macro.
* src/misc.c (assign_string_n): New function.
* gnulib.modules: Add strnlen.
* src/buffer.c: Use assign_string_n where appropriate.
* src/list.c: Likewise.
This commit is contained in:
Sergey Poznyakoff
2018-11-24 17:49:25 +02:00
parent f6e2860e8a
commit ba472050da
5 changed files with 28 additions and 18 deletions

View File

@@ -1503,7 +1503,7 @@ try_new_volume (void)
if (!read_header0 (&dummy))
return false;
tar_stat_destroy (&dummy);
assign_string (&volume_label, current_header->header.name);
ASSIGN_STRING_N (&volume_label, current_header->header.name);
set_next_block_after (header);
header = find_next_block ();
if (header->header.typeflag != GNUTYPE_MULTIVOL)
@@ -1513,7 +1513,7 @@ try_new_volume (void)
if (!read_header0 (&dummy))
return false;
tar_stat_destroy (&dummy);
assign_string (&continued_file_name, current_header->header.name);
ASSIGN_STRING_N (&continued_file_name, current_header->header.name);
continued_file_size =
UINTMAX_FROM_HEADER (current_header->header.size);
continued_file_offset =
@@ -1656,15 +1656,7 @@ match_volume_label (void)
quote (volume_label_option)));
if (label->header.typeflag == GNUTYPE_VOLHDR)
{
if (memchr (label->header.name, '\0', sizeof label->header.name))
assign_string (&volume_label, label->header.name);
else
{
volume_label = xmalloc (sizeof (label->header.name) + 1);
memcpy (volume_label, label->header.name,
sizeof (label->header.name));
volume_label[sizeof (label->header.name)] = 0;
}
ASSIGN_STRING_N (&volume_label, label->header.name);
}
else if (label->header.typeflag == XGLTYPE)
{
@@ -1700,8 +1692,7 @@ _write_volume_label (const char *str)
memset (label, 0, BLOCKSIZE);
strcpy (label->header.name, str);
assign_string (&current_stat_info.file_name,
label->header.name);
assign_string (&current_stat_info.file_name, label->header.name);
current_stat_info.had_trailing_slash =
strip_trailing_slashes (current_stat_info.file_name);

View File

@@ -628,6 +628,8 @@ void skip_member (void);
char const *quote_n_colon (int n, char const *arg);
void assign_string (char **dest, const char *src);
void assign_string_n (char **string, const char *value, size_t n);
#define ASSIGN_STRING_N(s,v) assign_string_n (s, v, sizeof (v))
int unquote_string (char *str);
char *zap_slashes (char *name);
char *normalize_filename (int cdidx, const char *name);

View File

@@ -631,10 +631,12 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
stat_info->stat.st_mode = mode;
stat_info->mtime.tv_sec = TIME_FROM_HEADER (header->header.mtime);
stat_info->mtime.tv_nsec = 0;
assign_string (&stat_info->uname,
header->header.uname[0] ? header->header.uname : NULL);
assign_string (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL);
assign_string_n (&stat_info->uname,
header->header.uname[0] ? header->header.uname : NULL,
sizeof (header->header.uname));
assign_string_n (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL,
sizeof (header->header.gname));
xheader_xattr_init (stat_info);
@@ -1439,7 +1441,7 @@ test_archive_label (void)
decode_header (current_header,
&current_stat_info, &current_format, 0);
if (current_header->header.typeflag == GNUTYPE_VOLHDR)
assign_string (&volume_label, current_header->header.name);
ASSIGN_STRING_N (&volume_label, current_header->header.name);
if (volume_label)
{

View File

@@ -50,6 +50,20 @@ assign_string (char **string, const char *value)
*string = value ? xstrdup (value) : 0;
}
void
assign_string_n (char **string, const char *value, size_t n)
{
free (*string);
if (value)
{
size_t l = strnlen (value, n);
char *p = xmalloc (l + 1);
memcpy (p, value, l);
p[l] = 0;
*string = p;
}
}
#if 0
/* This function is currently unused; perhaps it should be removed? */