mirror of
https://github.com/mirror/make.git
synced 2024-12-29 14:30:42 +08:00
* src/arscan.c (ar_scan): [SV 54395] Allow long names in archives.
Commit bc9d72beb0
"Resolve issues discovered by static code
analysis." added range checks on archive member name length. However,
on non-AIX systems it also checked BSD-style long names against the
short name limits and and checked the *offset* for GNU-style long
names against the short name limits. This caused valid long names to
be rejected.
* Record the size of the GNU name map and validate offsets against it
* Ensure that the last entry in the name map is null-terminated
* Apply a maximum length of INT_MAX for element sizes
Reported-by: Philipp Wolski <philipp.wolski@kisters.de>
This commit is contained in:
parent
9ff4d6af92
commit
a37fa47e32
17
src/arscan.c
17
src/arscan.c
@ -416,6 +416,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
# endif
|
||||
#endif
|
||||
char *namemap = 0;
|
||||
int namemap_size = 0;
|
||||
int desc = open (archive, O_RDONLY, 0);
|
||||
if (desc < 0)
|
||||
return -1;
|
||||
@ -669,10 +670,15 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
&& namemap != 0)
|
||||
{
|
||||
int name_off = atoi (name + 1);
|
||||
if (name_off < 1 || name_off > ARNAME_MAX)
|
||||
int name_len;
|
||||
|
||||
if (name_off < 0 || name_off >= namemap_size)
|
||||
goto invalid;
|
||||
|
||||
name = namemap + name_off;
|
||||
name_len = strlen (name);
|
||||
if (name_len < 1)
|
||||
goto invalid;
|
||||
long_name = 1;
|
||||
}
|
||||
else if (name[0] == '#'
|
||||
@ -680,7 +686,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
&& name[2] == '/')
|
||||
{
|
||||
int name_len = atoi (name + 3);
|
||||
if (name_len < 1 || name_len > ARNAME_MAX)
|
||||
|
||||
if (name_len < 1)
|
||||
goto invalid;
|
||||
|
||||
name = alloca (name_len + 1);
|
||||
@ -749,10 +756,13 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
char *clear;
|
||||
char *limit;
|
||||
|
||||
namemap = alloca (eltsize);
|
||||
if (eltsize > INT_MAX)
|
||||
goto invalid;
|
||||
namemap = alloca (eltsize + 1);
|
||||
EINTRLOOP (nread, read (desc, namemap, eltsize));
|
||||
if (nread != eltsize)
|
||||
goto invalid;
|
||||
namemap_size = eltsize;
|
||||
|
||||
/* The names are separated by newlines. Some formats have
|
||||
a trailing slash. Null terminate the strings for
|
||||
@ -767,6 +777,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
clear[-1] = '\0';
|
||||
}
|
||||
}
|
||||
*limit = '\0';
|
||||
|
||||
is_namemap = 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user