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:
17
src/buffer.c
17
src/buffer.c
@@ -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 (¤t_stat_info.file_name,
|
||||
label->header.name);
|
||||
assign_string (¤t_stat_info.file_name, label->header.name);
|
||||
current_stat_info.had_trailing_slash =
|
||||
strip_trailing_slashes (current_stat_info.file_name);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
12
src/list.c
12
src/list.c
@@ -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,
|
||||
¤t_stat_info, ¤t_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)
|
||||
{
|
||||
|
||||
14
src/misc.c
14
src/misc.c
@@ -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? */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user