mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
asan: c4x, c54x coff_canonicalize_reloc buffer overflow
Sometimes the investigation of a fuzzing bug report leads into areas you'd rather not go. In this instance by the time I'd figured out the real cause was a target variant that had never been properly supported in binutils, the time needed to fix it was less than the time needed to rip it out. * coffcode.h (coff_set_alignment_hook): Call bfd_coff_swap_reloc_in not coff_swap_reloc_in. (coff_slurp_reloc_table): Likewise. Don't use RELOC type. (ticoff0_swap_table): Use coff_swap_reloc_v0_out and coff_swap_reloc_v0_in. * coffswap.h (coff_swap_reloc_v0_in, coff_swap_reloc_v0_out): New. * coff-tic54x.c (tic54x_lookup_howto): Don't abort. * coffgen.c (coff_get_normalized_symtab): Use PTR_ADD. * bfd-in.h (PTR_ADD, NPTR_ADD): Avoid warnings when passing an expression. * bfd-in2.h: Regenerate.
This commit is contained in:
parent
e028124942
commit
1ed0032b40
@ -114,9 +114,9 @@ typedef struct bfd bfd;
|
||||
#endif
|
||||
|
||||
/* Silence "applying zero offset to null pointer" UBSAN warnings. */
|
||||
#define PTR_ADD(P,A) ((A) ? (P) + (A) : (P))
|
||||
#define PTR_ADD(P,A) ((A) != 0 ? (P) + (A) : (P))
|
||||
/* Also prevent non-zero offsets from being applied to a null pointer. */
|
||||
#define NPTR_ADD(P,A) ((P) ? (P) + (A) : (P))
|
||||
#define NPTR_ADD(P,A) ((P) != NULL ? (P) + (A) : (P))
|
||||
|
||||
#ifdef BFD64
|
||||
|
||||
|
@ -121,9 +121,9 @@ typedef struct bfd bfd;
|
||||
#endif
|
||||
|
||||
/* Silence "applying zero offset to null pointer" UBSAN warnings. */
|
||||
#define PTR_ADD(P,A) ((A) ? (P) + (A) : (P))
|
||||
#define PTR_ADD(P,A) ((A) != 0 ? (P) + (A) : (P))
|
||||
/* Also prevent non-zero offsets from being applied to a null pointer. */
|
||||
#define NPTR_ADD(P,A) ((P) ? (P) + (A) : (P))
|
||||
#define NPTR_ADD(P,A) ((P) != NULL ? (P) + (A) : (P))
|
||||
|
||||
#ifdef BFD64
|
||||
|
||||
|
@ -278,7 +278,7 @@ tic54x_lookup_howto (bfd *abfd,
|
||||
|
||||
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
|
||||
abfd, (unsigned int) dst->r_type);
|
||||
abort ();
|
||||
internal->howto = NULL;
|
||||
}
|
||||
|
||||
#define RELOC_PROCESSING(RELENT,RELOC,SYMS,ABFD,SECT)\
|
||||
|
@ -1948,7 +1948,7 @@ coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
if (bfd_bread (& dst, relsz, abfd) != relsz)
|
||||
return;
|
||||
|
||||
coff_swap_reloc_in (abfd, &dst, &n);
|
||||
bfd_coff_swap_reloc_in (abfd, &dst, &n);
|
||||
if (bfd_seek (abfd, oldpos, 0) != 0)
|
||||
return;
|
||||
if (n.r_vaddr < 0x10000)
|
||||
@ -2019,7 +2019,7 @@ coff_set_alignment_hook (bfd * abfd, asection * section, void * scnhdr)
|
||||
if (bfd_bread (& dst, relsz, abfd) != relsz)
|
||||
return;
|
||||
|
||||
coff_swap_reloc_in (abfd, &dst, &n);
|
||||
bfd_coff_swap_reloc_in (abfd, &dst, &n);
|
||||
if (bfd_seek (abfd, oldpos, 0) != 0)
|
||||
return;
|
||||
section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
|
||||
@ -5070,7 +5070,7 @@ SUBSUBSECTION
|
||||
static bool
|
||||
coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
|
||||
{
|
||||
RELOC *native_relocs;
|
||||
bfd_byte *native_relocs;
|
||||
arelent *reloc_cache;
|
||||
arelent *cache_ptr;
|
||||
unsigned int idx;
|
||||
@ -5085,9 +5085,9 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
|
||||
if (!coff_slurp_symbol_table (abfd))
|
||||
return false;
|
||||
|
||||
native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos,
|
||||
asect->reloc_count,
|
||||
bfd_coff_relsz (abfd));
|
||||
native_relocs = (bfd_byte *) buy_and_read (abfd, asect->rel_filepos,
|
||||
asect->reloc_count,
|
||||
bfd_coff_relsz (abfd));
|
||||
if (native_relocs == NULL)
|
||||
return false;
|
||||
|
||||
@ -5106,16 +5106,16 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
|
||||
for (idx = 0; idx < asect->reloc_count; idx++)
|
||||
{
|
||||
struct internal_reloc dst;
|
||||
struct external_reloc *src;
|
||||
void *src;
|
||||
#ifndef RELOC_PROCESSING
|
||||
asymbol *ptr;
|
||||
#endif
|
||||
|
||||
cache_ptr = reloc_cache + idx;
|
||||
src = native_relocs + idx;
|
||||
src = native_relocs + idx * (size_t) bfd_coff_relsz (abfd);
|
||||
|
||||
dst.r_offset = 0;
|
||||
coff_swap_reloc_in (abfd, src, &dst);
|
||||
bfd_coff_swap_reloc_in (abfd, src, &dst);
|
||||
|
||||
#ifdef RELOC_PROCESSING
|
||||
RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect);
|
||||
@ -5444,7 +5444,7 @@ static bfd_coff_backend_data ticoff0_swap_table =
|
||||
{
|
||||
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
|
||||
coff_SWAP_aux_out, coff_SWAP_sym_out,
|
||||
coff_SWAP_lineno_out, coff_SWAP_reloc_out,
|
||||
coff_SWAP_lineno_out, coff_swap_reloc_v0_out,
|
||||
coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out,
|
||||
coff_SWAP_scnhdr_out,
|
||||
FILHSZ_V0, AOUTSZ, SCNHSZ_V01, SYMESZ, AUXESZ, RELSZ_V0, LINESZ, FILNMLEN,
|
||||
@ -5467,7 +5467,7 @@ static bfd_coff_backend_data ticoff0_swap_table =
|
||||
#endif
|
||||
32768,
|
||||
coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
|
||||
coff_SWAP_reloc_in, ticoff0_bad_format_hook, coff_set_arch_mach_hook,
|
||||
coff_swap_reloc_v0_in, ticoff0_bad_format_hook, coff_set_arch_mach_hook,
|
||||
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
|
||||
coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
|
||||
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
|
||||
|
@ -1807,7 +1807,7 @@ coff_get_normalized_symtab (bfd *abfd)
|
||||
|
||||
/* Mark the end of the symbols. */
|
||||
symesz = bfd_coff_symesz (abfd);
|
||||
raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz;
|
||||
raw_end = PTR_ADD (raw_src, obj_raw_syment_count (abfd) * symesz);
|
||||
|
||||
/* FIXME SOMEDAY. A string table size of zero is very weird, but
|
||||
probably possible. If one shows up, it will probably kill us. */
|
||||
|
@ -246,6 +246,33 @@ coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
|
||||
return bfd_coff_relsz (abfd);
|
||||
}
|
||||
|
||||
#ifdef TICOFF
|
||||
static void
|
||||
coff_swap_reloc_v0_in (bfd *abfd, void *src, void *dst)
|
||||
{
|
||||
struct external_reloc_v0 *reloc_src = (struct external_reloc_v0 *) src;
|
||||
struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
|
||||
|
||||
reloc_dst->r_vaddr = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
|
||||
reloc_dst->r_symndx = H_GET_16 (abfd, reloc_src->r_symndx);
|
||||
reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
coff_swap_reloc_v0_out (bfd *abfd, void *src, void *dst)
|
||||
{
|
||||
struct internal_reloc *reloc_src = (struct internal_reloc *) src;
|
||||
struct external_reloc_v0 *reloc_dst = (struct external_reloc_v0 *) dst;
|
||||
|
||||
PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
|
||||
H_PUT_16 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
|
||||
H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
|
||||
SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
|
||||
|
||||
return bfd_coff_relsz (abfd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NO_COFF_RELOCS */
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user