From 0a6041ce9383338fa62acb207683780faaa8b42c Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 6 Oct 2021 10:17:29 +1030 Subject: [PATCH] PR28403, null pointer dereference in disassemble_bytes Indexing of symbol and howto arrays wasn't checked in aout targets. PR 28403 * aout-ns32k.c (MY (reloc_howto)): Sanity check howto_table index. Make r_index unsigned. (MY_swap_std_reloc_in): Make r_index unsigned. * aoutx.h (MOVE_ADDRESS): Sanity check symbol r_index. (aout_link_input_section_std): Make r_index unsigned. (aout_link_input_section_ext): Likewise. * i386lynx.c (MOVE_ADDRESS): Sanity check symbol r_index. (swap_ext_reloc_in, swap_std_reloc_in): Make r_index unsigned. * pdp11.c (MOVE_ADDRESS): Sanity check symbol r_index. --- bfd/aout-ns32k.c | 8 ++++--- bfd/aoutx.h | 11 +++++---- bfd/i386lynx.c | 62 +++++++++++++++++++++++++----------------------- bfd/pdp11.c | 3 ++- 4 files changed, 45 insertions(+), 39 deletions(-) diff --git a/bfd/aout-ns32k.c b/bfd/aout-ns32k.c index 83fde67cc26..eb721b256d1 100644 --- a/bfd/aout-ns32k.c +++ b/bfd/aout-ns32k.c @@ -143,12 +143,12 @@ reloc_howto_type MY (howto_table)[] = static reloc_howto_type * MY (reloc_howto) (bfd *abfd ATTRIBUTE_UNUSED, struct reloc_std_external *rel, - int *r_index, + unsigned int *r_index, int *r_extern, int *r_pcrel) { unsigned int r_length; - int r_ns32k_type; + unsigned int r_ns32k_type; *r_index = ((rel->r_index[2] << 16) | (rel->r_index[1] << 8) @@ -159,6 +159,8 @@ MY (reloc_howto) (bfd *abfd ATTRIBUTE_UNUSED, >> RELOC_STD_BITS_LENGTH_SH_LITTLE); r_ns32k_type = ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE) >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE); + if (r_length > 2 || r_ns32k_type > 2) + return NULL; return (MY (howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type); } @@ -271,7 +273,7 @@ MY_swap_std_reloc_in (bfd *abfd, asymbol **symbols, bfd_size_type symcount ATTRIBUTE_UNUSED) { - int r_index; + unsigned int r_index; int r_extern; int r_pcrel; struct aoutdata *su = &(abfd->tdata.aout_data->a); diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 17560bd8f54..ea09646f2b3 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2130,7 +2130,8 @@ NAME (aout, swap_ext_reloc_out) (bfd *abfd, if (r_extern) \ { \ /* Undefined symbol. */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ + if (r_index < bfd_get_symcount (abfd)) \ + cache_ptr->sym_ptr_ptr = symbols + r_index; \ cache_ptr->addend = ad; \ } \ else \ @@ -4021,7 +4022,7 @@ aout_link_input_section_std (struct aout_final_link_info *flaginfo, for (; rel < rel_end; rel++) { bfd_vma r_addr; - int r_index; + unsigned int r_index; int r_extern; int r_pcrel; int r_baserel = 0; @@ -4133,7 +4134,7 @@ aout_link_input_section_std (struct aout_final_link_info *flaginfo, map. */ r_index = symbol_map[r_index]; - if (r_index == -1) + if (r_index == -1u) { if (h != NULL) { @@ -4369,7 +4370,7 @@ aout_link_input_section_ext (struct aout_final_link_info *flaginfo, for (; rel < rel_end; rel++) { bfd_vma r_addr; - int r_index; + unsigned int r_index; int r_extern; unsigned int r_type; bfd_vma r_addend; @@ -4469,7 +4470,7 @@ aout_link_input_section_ext (struct aout_final_link_info *flaginfo, map. */ r_index = symbol_map[r_index]; - if (r_index == -1) + if (r_index == -1u) { if (h != NULL) { diff --git a/bfd/i386lynx.c b/bfd/i386lynx.c index c477e661c81..932ce1741e2 100644 --- a/bfd/i386lynx.c +++ b/bfd/i386lynx.c @@ -282,38 +282,40 @@ NAME(lynx,swap_ext_reloc_out) (bfd *abfd, #define MOVE_ADDRESS(ad) \ if (r_extern) \ { \ - /* undefined symbol */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ - cache_ptr->addend = ad; \ + /* undefined symbol */ \ + if (r_index < bfd_get_symcount (abfd)) \ + cache_ptr->sym_ptr_ptr = symbols + r_index; \ + cache_ptr->addend = ad; \ } \ else \ { \ - /* defined, section relative. replace symbol with pointer to \ - symbol which points to section */ \ - switch (r_index) { \ - case N_TEXT: \ - case N_TEXT | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->textsec->vma; \ - break; \ - case N_DATA: \ - case N_DATA | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->datasec->vma; \ - break; \ - case N_BSS: \ - case N_BSS | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->bsssec->vma; \ - break; \ - default: \ - case N_ABS: \ - case N_ABS | N_EXT: \ - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ - cache_ptr->addend = ad; \ - break; \ + /* defined, section relative. replace symbol with pointer to \ + symbol which points to section */ \ + switch (r_index) \ + { \ + case N_TEXT: \ + case N_TEXT | N_EXT: \ + cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ + cache_ptr->addend = ad - su->textsec->vma; \ + break; \ + case N_DATA: \ + case N_DATA | N_EXT: \ + cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ + cache_ptr->addend = ad - su->datasec->vma; \ + break; \ + case N_BSS: \ + case N_BSS | N_EXT: \ + cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ + cache_ptr->addend = ad - su->bsssec->vma; \ + break; \ + default: \ + case N_ABS: \ + case N_ABS | N_EXT: \ + cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ + cache_ptr->addend = ad; \ + break; \ + } \ } \ - } \ static void NAME(lynx,swap_ext_reloc_in) (bfd *abfd, @@ -322,7 +324,7 @@ NAME(lynx,swap_ext_reloc_in) (bfd *abfd, asymbol **symbols, bfd_size_type symcount ATTRIBUTE_UNUSED) { - int r_index; + unsigned int r_index; int r_extern; unsigned int r_type; struct aoutdata *su = &(abfd->tdata.aout_data->a); @@ -345,7 +347,7 @@ NAME(lynx,swap_std_reloc_in) (bfd *abfd, asymbol **symbols, bfd_size_type symcount ATTRIBUTE_UNUSED) { - int r_index; + unsigned int r_index; int r_extern; unsigned int r_length; int r_pcrel; diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 2c9fe0ae56b..6429b43be19 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -1862,7 +1862,8 @@ pdp11_aout_swap_reloc_out (bfd *abfd, arelent *g, bfd_byte *natptr) if (r_extern) \ { \ /* Undefined symbol. */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ + if (r_index < bfd_get_symcount (abfd)) \ + cache_ptr->sym_ptr_ptr = symbols + r_index; \ cache_ptr->addend = ad; \ } \ else \ -- 2.30.2