From 38334d6de448272c3bd831e3410dbc337fc2739d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 23 Aug 2016 15:41:01 +0100 Subject: [PATCH] Better fix for PR 20499, including preventing strlen from being called on an uninitialised name field. PR gprof/20499 * corefile.c (BUFSIZE): Define. (STR_BUFSIZE): Define. (read_function_mappings): Use BUFSIZE and STR)BUFSIZE. (num_of_syms_in): Move buf, address and name arrays out of function and declare as static BUFSIZE arrays. Use STR_BUFSIZE when scanning for name and address. (core_create_syms_from): Revert previous delta. Instead short circuit the parsing of a symbol if all three fields could not be found. --- gprof/ChangeLog | 13 +++++++++++++ gprof/corefile.c | 50 +++++++++++++++++------------------------------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/gprof/ChangeLog b/gprof/ChangeLog index eabc188ca3..1081e8fb19 100644 --- a/gprof/ChangeLog +++ b/gprof/ChangeLog @@ -1,3 +1,16 @@ +2016-08-23 Nick Clifton + + PR gprof/20499 + * corefile.c (BUFSIZE): Define. + (STR_BUFSIZE): Define. + (read_function_mappings): Use BUFSIZE and STR)BUFSIZE. + (num_of_syms_in): Move buf, address and name arrays out of + function and declare as static BUFSIZE arrays. + Use STR_BUFSIZE when scanning for name and address. + (core_create_syms_from): Revert previous delta. Instead + short circuit the parsing of a symbol if all three fields + could not be found. + 2016-08-22 Nick Clifton PR gprof/20499 diff --git a/gprof/corefile.c b/gprof/corefile.c index 93a0e94e55..2a433a6a3e 100644 --- a/gprof/corefile.c +++ b/gprof/corefile.c @@ -72,11 +72,15 @@ cmp_symbol_map (const void * l, const void * r) ((struct function_map *) r)->function_name); } +#define BUFSIZE (1024) +/* This is BUFSIZE - 1 as a string. Suitable for use in fprintf/sscanf format strings. */ +#define STR_BUFSIZE "1023" + static void read_function_mappings (const char *filename) { FILE * file = fopen (filename, "r"); - char dummy[1024]; + char dummy[BUFSIZE]; int count = 0; unsigned int i; @@ -93,7 +97,7 @@ read_function_mappings (const char *filename) { int matches; - matches = fscanf (file, "%[^\n:]", dummy); + matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy); if (!matches) parse_error (filename); @@ -107,7 +111,7 @@ read_function_mappings (const char *filename) } /* Don't care what else is on this line at this point. */ - matches = fscanf (file, "%[^\n]\n", dummy); + matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy); if (!matches) parse_error (filename); count++; @@ -127,7 +131,7 @@ read_function_mappings (const char *filename) int matches; char *tmp; - matches = fscanf (file, "%[^\n:]", dummy); + matches = fscanf (file, "%" STR_BUFSIZE "[^\n:]", dummy); if (!matches) parse_error (filename); @@ -145,7 +149,7 @@ read_function_mappings (const char *filename) strcpy (symbol_map[count].file_name, dummy); /* Now we need the function name. */ - matches = fscanf (file, "%[^\n]\n", dummy); + matches = fscanf (file, "%" STR_BUFSIZE "[^\n]\n", dummy); if (!matches) parse_error (filename); tmp = strrchr (dummy, ' ') + 1; @@ -480,29 +484,25 @@ get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_ } } +static char buf[BUFSIZE]; +static char address[BUFSIZE]; +static char name[BUFSIZE]; + /* Return number of symbols in a symbol-table file. */ static int num_of_syms_in (FILE * f) { - const int BUFSIZE = 1024; - char * buf = (char *) xmalloc (BUFSIZE); - char * address = (char *) xmalloc (BUFSIZE); char type; - char * name = (char *) xmalloc (BUFSIZE); int num = 0; while (!feof (f) && fgets (buf, BUFSIZE - 1, f)) { - if (sscanf (buf, "%s %c %s", address, &type, name) == 3) + if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) == 3) if (type == 't' || type == 'T') ++num; } - free (buf); - free (address); - free (name); - return num; } @@ -511,11 +511,7 @@ num_of_syms_in (FILE * f) void core_create_syms_from (const char * sym_table_file) { - const int BUFSIZE = 1024; - char * buf = (char *) xmalloc (BUFSIZE); - char * address = (char *) xmalloc (BUFSIZE); char type; - char * name = (char *) xmalloc (BUFSIZE); bfd_vma min_vma = ~(bfd_vma) 0; bfd_vma max_vma = 0; FILE * f; @@ -549,16 +545,10 @@ core_create_syms_from (const char * sym_table_file) while (!feof (f) && fgets (buf, BUFSIZE - 1, f)) { - if (sscanf (buf, "%s %c %s", address, &type, name) == 3) - if (type != 't' && type != 'T') - continue; - - /* PR 20499 */ - if ((symtab.limit - symtab.base) >= symtab.len) - { - fprintf (stderr, _("%s: too many symbols in file '%s'\n"), whoami, sym_table_file); - done (1); - } + if (sscanf (buf, "%" STR_BUFSIZE "s %c %" STR_BUFSIZE "s", address, &type, name) != 3) + continue; + if (type != 't' && type != 'T') + continue; sym_init (symtab.limit); @@ -579,10 +569,6 @@ core_create_syms_from (const char * sym_table_file) symtab.len = symtab.limit - symtab.base; symtab_finalize (&symtab); - - free (buf); - free (address); - free (name); } static int