Partially revert previous delta - move limit testing code to first scan over symbol file.

PR gprof/20499
	* corefile.c (num_of_syms_in): Return an unsigned int.
	Fail if the count exceeds the maximum possible allocatable size.
	(core_create_syms_from): Exit early if num_of_syms_in returns a
	failure code.
This commit is contained in:
Nick Clifton 2016-08-30 13:51:43 +01:00
parent 0092723307
commit c616591359
2 changed files with 12 additions and 15 deletions

View File

@ -2,10 +2,9 @@
PR gprof/20499 PR gprof/20499
* corefile.c (num_of_syms_in): Return an unsigned int. * corefile.c (num_of_syms_in): Return an unsigned int.
(core_create_syms_from): Catch a possible integer overflow Fail if the count exceeds the maximum possible allocatable size.
computing the argument to xmalloc. Also allow for the possibility (core_create_syms_from): Exit early if num_of_syms_in returns a
that an integer overflow in num_of_syms_in means that less space failure code.
has been allocated than expected.
2016-08-23 Nick Clifton <nickc@redhat.com> 2016-08-23 Nick Clifton <nickc@redhat.com>

View File

@ -28,6 +28,7 @@
#include "hist.h" #include "hist.h"
#include "corefile.h" #include "corefile.h"
#include "safe-ctype.h" #include "safe-ctype.h"
#include <limits.h> /* For UINT_MAX. */
bfd *core_bfd; bfd *core_bfd;
static int core_num_syms; static int core_num_syms;
@ -500,7 +501,11 @@ num_of_syms_in (FILE * f)
{ {
if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) == 3) if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) == 3)
if (type == 't' || type == 'T') if (type == 't' || type == 'T')
++num; {
/* PR 20499 - prevent integer overflow computing argument to xmalloc. */
if (++num >= UINT_MAX / sizeof (Sym))
return -1U;
}
} }
return num; return num;
@ -531,11 +536,10 @@ core_create_syms_from (const char * sym_table_file)
fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file); fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, sym_table_file);
done (1); done (1);
} }
/* PR 20499 - prevent integer overflow computing argument to xmalloc. */ else if (symtab.len == -1U)
else if ((symtab.len * (unsigned) sizeof (Sym)) < symtab.len)
{ {
fprintf (stderr, _("%s: file `%s' has too many symbols: %u\n"), fprintf (stderr, _("%s: file `%s' has too many symbols\n"),
whoami, sym_table_file, symtab.len); whoami, sym_table_file);
done (1); done (1);
} }
@ -571,12 +575,6 @@ core_create_syms_from (const char * sym_table_file)
max_vma = MAX (symtab.limit->addr, max_vma); max_vma = MAX (symtab.limit->addr, max_vma);
++symtab.limit; ++symtab.limit;
/* PR 20499 - it is theoretically possible that there are so many
symbols in the file that the scan in num_of_syms_in() wrapped
around. So be paranoid here and exit the loop if we have
reached the end of our allocated table. */
if ((unsigned int)(symtab.limit - symtab.base) == symtab.len)
break;
} }
fclose (f); fclose (f);