diff options
author | Nick Clifton <nickc@redhat.com> | 2015-01-06 16:06:45 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-01-06 16:06:45 +0000 |
commit | 85880250e591a51624d24db653aaace0c5ce5943 (patch) | |
tree | 0319d173921cd8ec36f007e0270dc883a30e8336 /bfd | |
parent | fce10a8494efa8faec67b718f25e06d3d71694b3 (diff) | |
download | gdb-85880250e591a51624d24db653aaace0c5ce5943.zip gdb-85880250e591a51624d24db653aaace0c5ce5943.tar.gz gdb-85880250e591a51624d24db653aaace0c5ce5943.tar.bz2 |
Fixes for memory access violations in the coffdump program.
PR binutils/17512
* coffdump.c (dump_coff_section): Check for a symbol being
available before printing its name.
(main): Check the return value from coff_grok.
* coffgrok.c: Reformat and tidy.
Add range checks to most functions.
(coff_grok): Return NULL if the input bfd is not in a COFF
format.
* coffgrok.h: Reformat and tidy.
(struct coff_section): Change the nrelocs field to unsigned.
* srconv.c (main): Check the return value from coff_grok.
* coff-i860.c (CALC_ADDEND): Always set an addend value.
* tekhex.c (getvalue): Add an end pointer parameter. Use it to
avoid reading off the end of the buffer.
(getsym): Likewise.
(first_phase): Likewise.
(pass_over): Pass an end pointer to the invoked function.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/coff-i860.c | 5 | ||||
-rw-r--r-- | bfd/tekhex.c | 33 |
3 files changed, 30 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5215aa7..efcb63a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2015-01-06 Nick Clifton <nickc@redhat.com> + + PR binutils/17512 + * coff-i860.c (CALC_ADDEND): Always set an addend value. + * tekhex.c (getvalue): Add an end pointer parameter. Use it to + avoid reading off the end of the buffer. + (getsym): Likewise. + (first_phase): Likewise. + (pass_over): Pass an end pointer to the invoked function. + 2015-01-05 H.J. Lu <hongjiu.lu@intel.com> PR binutils/17512 diff --git a/bfd/coff-i860.c b/bfd/coff-i860.c index 2122c0d..8573a8d 100644 --- a/bfd/coff-i860.c +++ b/bfd/coff-i860.c @@ -467,7 +467,10 @@ static reloc_howto_type howto_table[] = FIXME: This macro refers to symbols and asect; these are from the calling function, not the macro arguments. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) +/* PR 17512: file: 0a38fb7c + Set an addend value, even if it is not going to be used. A tool + like coffdump might be used to print out the contents of the reloc. */ +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) (cache_ptr)->addend = 0 /* We use the special COFF backend linker. */ #define coff_relocate_section _bfd_coff_generic_relocate_section diff --git a/bfd/tekhex.c b/bfd/tekhex.c index 969b812..9444117 100644 --- a/bfd/tekhex.c +++ b/bfd/tekhex.c @@ -267,7 +267,7 @@ typedef struct tekhex_data_struct #define enda(x) (x->vma + x->size) static bfd_boolean -getvalue (char **srcp, bfd_vma *valuep) +getvalue (char **srcp, bfd_vma *valuep, char * endp) { char *src = *srcp; bfd_vma value = 0; @@ -279,7 +279,7 @@ getvalue (char **srcp, bfd_vma *valuep) len = hex_value (*src++); if (len == 0) len = 16; - while (len--) + while (len-- && src < endp) { if (!ISHEX (*src)) return FALSE; @@ -288,11 +288,11 @@ getvalue (char **srcp, bfd_vma *valuep) *srcp = src; *valuep = value; - return TRUE; + return len == 0; } static bfd_boolean -getsym (char *dstp, char **srcp, unsigned int *lenp) +getsym (char *dstp, char **srcp, unsigned int *lenp, char * endp) { char *src = *srcp; unsigned int i; @@ -304,7 +304,7 @@ getsym (char *dstp, char **srcp, unsigned int *lenp) len = hex_value (*src++); if (len == 0) len = 16; - for (i = 0; i < len; i++) + for (i = 0; i < len && src < endp; i++) dstp[i] = src[i]; dstp[i] = 0; *srcp = src + i; @@ -354,7 +354,7 @@ insert_byte (bfd *abfd, int value, bfd_vma addr) how big the data is. */ static bfd_boolean -first_phase (bfd *abfd, int type, char *src) +first_phase (bfd *abfd, int type, char *src, char * src_end) { asection *section, *alt_section; unsigned int len; @@ -368,21 +368,21 @@ first_phase (bfd *abfd, int type, char *src) { bfd_vma addr; - if (!getvalue (&src, &addr)) + if (!getvalue (&src, &addr, src_end)) return FALSE; - while (*src) + while (*src && src < src_end - 1) { insert_byte (abfd, HEX (src), addr); src += 2; addr++; } + return TRUE; } - return TRUE; case '3': /* Symbol record, read the segment. */ - if (!getsym (sym, &src, &len)) + if (!getsym (sym, &src, &len, src_end)) return FALSE; section = bfd_get_section_by_name (abfd, sym); if (section == NULL) @@ -403,9 +403,9 @@ first_phase (bfd *abfd, int type, char *src) { case '1': /* Section range. */ src++; - if (!getvalue (&src, §ion->vma)) + if (!getvalue (&src, §ion->vma, src_end)) return FALSE; - if (!getvalue (&src, &val)) + if (!getvalue (&src, &val, src_end)) return FALSE; section->size = val - section->vma; section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; @@ -432,7 +432,7 @@ first_phase (bfd *abfd, int type, char *src) abfd->flags |= HAS_SYMS; new_symbol->prev = abfd->tdata.tekhex_data->symbols; abfd->tdata.tekhex_data->symbols = new_symbol; - if (!getsym (sym, &src, &len)) + if (!getsym (sym, &src, &len, src_end)) return FALSE; new_symbol->symbol.name = (const char *) bfd_alloc (abfd, (bfd_size_type) len + 1); @@ -480,7 +480,7 @@ first_phase (bfd *abfd, int type, char *src) new_symbol->symbol.section = alt_section; } } - if (!getvalue (&src, &val)) + if (!getvalue (&src, &val, src_end)) return FALSE; new_symbol->symbol.value = val - section->vma; break; @@ -498,7 +498,7 @@ first_phase (bfd *abfd, int type, char *src) record. */ static bfd_boolean -pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *)) +pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *, char *)) { unsigned int chars_on_line; bfd_boolean is_eof = FALSE; @@ -539,8 +539,7 @@ pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *)) /* Put a null at the end. */ src[chars_on_line] = 0; - - if (!func (abfd, type, src)) + if (!func (abfd, type, src, src + chars_on_line)) return FALSE; } |