.file file number checking

This adds another test for file numbers given in .file directives,
checking that the value can be represented as an unsigned int and that
a memory allocation expression doesn't overflow.  I removed a test
added recently since an earlier test (num < 1) already covers the
(num < 0) case.

	* dwarf2dbg.c: Whitespace fixes.
	(get_filenum): Don't strdup "file".  Adjust error message.
	(dwarf2_directive_filename): Use an unsigned type for "num".
	Catch truncation of file number and overflow of get_filenum
	XRESIZEVEC multiplication.  Delete dead code.
This commit is contained in:
Alan Modra
2019-05-15 11:24:09 +09:30
parent ded12894f5
commit 8f02ae5bac
2 changed files with 31 additions and 22 deletions

View File

@ -1,3 +1,11 @@
2019-05-15 Alan Modra <amodra@gmail.com>
* dwarf2dbg.c: Whitespace fixes.
(get_filenum): Don't strdup "file". Adjust error message.
(dwarf2_directive_filename): Use an unsigned type for "num".
Catch truncation of file number and overflow of get_filenum
XRESIZEVEC multiplication. Delete dead code.
2019-05-15 Alan Modra <amodra@gmail.com>
PR 24538

View File

@ -754,7 +754,7 @@ get_filenum (const char *filename, unsigned int num)
/* Catch wraparound. */
if (files_allocated <= old)
{
as_bad (_("file number %u is too big"), i);
as_bad (_("file number %lu is too big"), (unsigned long) i);
return 0;
}
@ -762,7 +762,7 @@ get_filenum (const char *filename, unsigned int num)
memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
}
files[i].filename = num ? file : xstrdup (file);
files[i].filename = file;
files[i].dir = dir;
if (files_in_use < i + 1)
files_in_use = i + 1;
@ -781,7 +781,7 @@ get_filenum (const char *filename, unsigned int num)
char *
dwarf2_directive_filename (void)
{
offsetT num;
valueT num;
char *filename;
int filename_len;
@ -799,7 +799,7 @@ dwarf2_directive_filename (void)
return NULL;
demand_empty_rest_of_line ();
if (num < 1)
if ((offsetT) num < 1)
{
as_bad (_("file number less than one"));
return NULL;
@ -809,14 +809,15 @@ dwarf2_directive_filename (void)
being supplied. Turn off gas generated debug info. */
debug_type = DEBUG_NONE;
if (num < (offsetT) files_in_use && files[num].filename != 0)
if (num != (unsigned int) num
|| num >= (size_t) -1 / sizeof (struct file_entry) - 32)
{
as_bad (_("file number %ld already allocated"), (long) num);
as_bad (_("file number %lu is too big"), (unsigned long) num);
return NULL;
}
else if (num < 0)
if (num < files_in_use && files[num].filename != 0)
{
as_bad (_("file number %ld is too small!"), (long) num);
as_bad (_("file number %u already allocated"), (unsigned int) num);
return NULL;
}