Add check to avoid corrupt input files whose section sizes are greater than

the size of the input file.
This commit is contained in:
Nick Clifton 2005-07-05 11:43:55 +00:00
parent 9e492e0549
commit 0680331375
2 changed files with 75 additions and 17 deletions

View File

@ -1,3 +1,12 @@
2005-07-05 Dmitry V. Levin <ldv@altlinux.org>
Nick Clifton <nickc@redhat.com>
* strings.c (filename_and_size_t): New typedef.
(strings_a_section): Skip sections with size greater or equal to
the file size. Cache the file size to avoid repeated stat()s.
(strings_object_file): Pass filename_and_size_t argument to
strings_a_section() via bfd_map_over_sections().
2005-07-04 Alan Modra <amodra@bigpond.net.au>
PR 1004

View File

@ -1,6 +1,6 @@
/* strings -- print the strings of printable characters in files
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 Free Software Foundation, Inc.
2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -151,6 +151,15 @@ static struct option long_options[] =
{NULL, 0, NULL, 0}
};
/* Records the size of a named file so that we
do not repeatedly run bfd_stat() on it. */
typedef struct
{
const char * filename;
bfd_size_type filesize;
} filename_and_size_t;
static void strings_a_section (bfd *, asection *, void *);
static bfd_boolean strings_object_file (const char *);
static bfd_boolean strings_file (char *file);
@ -314,27 +323,62 @@ main (int argc, char **argv)
return (exit_status);
}
/* Scan section SECT of the file ABFD, whose printable name is FILE.
If it contains initialized data,
set `got_a_section' and print the strings in it. */
/* Scan section SECT of the file ABFD, whose printable name is in
ARG->filename and whose size might be in ARG->filesize. If it
contains initialized data set `got_a_section' and print the
strings in it.
FIXME: We ought to be able to return error codes/messages for
certain conditions. */
static void
strings_a_section (bfd *abfd, asection *sect, void *filearg)
strings_a_section (bfd *abfd, asection *sect, void *arg)
{
const char *file = (const char *) filearg;
filename_and_size_t * filename_and_sizep;
bfd_size_type *filesizep;
bfd_size_type sectsize;
void *mem;
if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
return;
if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
sectsize = bfd_get_section_size (sect);
if (sectsize <= 0)
return;
/* Get the size of the file. This might have been cached for us. */
filename_and_sizep = (filename_and_size_t *) arg;
filesizep = & filename_and_sizep->filesize;
if (*filesizep == 0)
{
bfd_size_type sz = bfd_get_section_size (sect);
void *mem = xmalloc (sz);
struct stat st;
if (bfd_stat (abfd, &st))
return;
if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
{
got_a_section = TRUE;
print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
}
free (mem);
/* Cache the result so that we do not repeatedly stat this file. */
*filesizep = st.st_size;
}
/* Compare the size of the section against the size of the file.
If the section is bigger then the file must be corrupt and
we should not try dumping it. */
if (sectsize >= *filesizep)
return;
mem = xmalloc (sectsize);
if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
{
got_a_section = TRUE;
print_strings (filename_and_sizep->filename, NULL, sect->filepos,
0, sectsize, mem);
}
free (mem);
}
/* Scan all of the sections in FILE, and print the strings
@ -346,7 +390,10 @@ strings_a_section (bfd *abfd, asection *sect, void *filearg)
static bfd_boolean
strings_object_file (const char *file)
{
bfd *abfd = bfd_openr (file, target);
filename_and_size_t filename_and_size;
bfd *abfd;
abfd = bfd_openr (file, target);
if (abfd == NULL)
/* Treat the file as a non-object file. */
@ -362,7 +409,9 @@ strings_object_file (const char *file)
}
got_a_section = FALSE;
bfd_map_over_sections (abfd, strings_a_section, (void *) file);
filename_and_size.filename = file;
filename_and_size.filesize = 0;
bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
if (!bfd_close (abfd))
{