mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
Add check to avoid corrupt input files whose section sizes are greater than
the size of the input file.
This commit is contained in:
parent
9e492e0549
commit
0680331375
@ -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
|
||||
|
@ -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))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user