Fix bad pointer usage in xsparse.c
* scripts/xsparse.c (read_xheader): Avoid undefined behavior by accessing via null pointer sparse_map or out of its bounds when the input is invalid. This means we no longer need the ‘expect’ local, so omit it for simplicity.
This commit is contained in:
@@ -168,7 +168,6 @@ read_xheader (char *name)
|
|||||||
{
|
{
|
||||||
char *kw, *val;
|
char *kw, *val;
|
||||||
FILE *fp = fopen (name, "r");
|
FILE *fp = fopen (name, "r");
|
||||||
char *expect = NULL;
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -179,10 +178,6 @@ read_xheader (char *name)
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("Found variable GNU.sparse.%s = %s\n", kw, val);
|
printf ("Found variable GNU.sparse.%s = %s\n", kw, val);
|
||||||
|
|
||||||
if (expect && strcmp (kw, expect))
|
|
||||||
die (1, "bad keyword sequence: expected '%s' but found '%s'",
|
|
||||||
expect, kw);
|
|
||||||
expect = NULL;
|
|
||||||
if (strcmp (kw, "name") == 0)
|
if (strcmp (kw, "name") == 0)
|
||||||
{
|
{
|
||||||
outname = emalloc (strlen (val) + 1);
|
outname = emalloc (strlen (val) + 1);
|
||||||
@@ -205,16 +200,25 @@ read_xheader (char *name)
|
|||||||
{
|
{
|
||||||
sparse_map_size = string_to_size (val, NULL,
|
sparse_map_size = string_to_size (val, NULL,
|
||||||
SIZE_MAX / sizeof *sparse_map);
|
SIZE_MAX / sizeof *sparse_map);
|
||||||
|
if (sparse_map_size)
|
||||||
|
{
|
||||||
sparse_map = emalloc (sparse_map_size * sizeof *sparse_map);
|
sparse_map = emalloc (sparse_map_size * sizeof *sparse_map);
|
||||||
|
sparse_map[0].offset = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp (kw, "offset") == 0)
|
else if (strcmp (kw, "offset") == 0)
|
||||||
{
|
{
|
||||||
|
if (sparse_map_size <= i)
|
||||||
|
die (1, "bad GNU.sparse.map: spurious offset");
|
||||||
sparse_map[i].offset = string_to_off (val, NULL);
|
sparse_map[i].offset = string_to_off (val, NULL);
|
||||||
expect = "numbytes";
|
|
||||||
}
|
}
|
||||||
else if (strcmp (kw, "numbytes") == 0)
|
else if (strcmp (kw, "numbytes") == 0)
|
||||||
{
|
{
|
||||||
|
if (sparse_map_size <= i || sparse_map[i].offset < 0)
|
||||||
|
die (1, "bad GNU.sparse.map: spurious numbytes");
|
||||||
sparse_map[i++].numbytes = string_to_off (val, NULL);
|
sparse_map[i++].numbytes = string_to_off (val, NULL);
|
||||||
|
if (i < sparse_map_size)
|
||||||
|
sparse_map[i].offset = -1;
|
||||||
}
|
}
|
||||||
else if (strcmp (kw, "map") == 0)
|
else if (strcmp (kw, "map") == 0)
|
||||||
{
|
{
|
||||||
@@ -238,8 +242,6 @@ read_xheader (char *name)
|
|||||||
die (1, "bad GNU.sparse.map: garbage at the end");
|
die (1, "bad GNU.sparse.map: garbage at the end");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expect)
|
|
||||||
die (1, "bad keyword sequence: expected '%s' not found", expect);
|
|
||||||
if (version_major == 0 && sparse_map_size == 0)
|
if (version_major == 0 && sparse_map_size == 0)
|
||||||
die (1, "size of the sparse map unknown");
|
die (1, "size of the sparse map unknown");
|
||||||
if (i != sparse_map_size)
|
if (i != sparse_map_size)
|
||||||
|
|||||||
Reference in New Issue
Block a user