diff options
author | Alan Modra <amodra@gmail.com> | 2022-03-17 16:47:39 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2022-03-17 21:32:44 +1030 |
commit | 0c6a3cd13585be7d17d5ee76ac9c4404910d2b17 (patch) | |
tree | ca9d5e9e0a00232196837397e70549190b4d9d38 /bfd | |
parent | 4c5f3d0c9eb3ebe49f822bd1aabd3184f24998d8 (diff) | |
download | gdb-0c6a3cd13585be7d17d5ee76ac9c4404910d2b17.zip gdb-0c6a3cd13585be7d17d5ee76ac9c4404910d2b17.tar.gz gdb-0c6a3cd13585be7d17d5ee76ac9c4404910d2b17.tar.bz2 |
asan: Buffer overflow in som_set_reloc_info
* som.c (som_set_reloc_info): Add symcount parameter. Don't
access symbols past symcount. Don't access fixup past end_fixups.
(som_slurp_reloc_table): Adjust som_set_reloc_info calls.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/som.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -4939,6 +4939,7 @@ som_set_reloc_info (unsigned char *fixup, arelent *internal_relocs, asection *section, asymbol **symbols, + unsigned int symcount, bool just_count) { unsigned int op, varname, deallocate_contents = 0; @@ -5032,7 +5033,7 @@ som_set_reloc_info (unsigned char *fixup, else if (ISLOWER (c)) { int bits = (c - 'a') * 8; - for (v = 0; c > 'a'; --c) + for (v = 0; c > 'a' && fixup < end_fixups; --c) v = (v << 8) | *fixup++; if (varname == 'V') v = sign_extend (v, bits); @@ -5093,7 +5094,7 @@ som_set_reloc_info (unsigned char *fixup, /* A symbol to use in the relocation. Make a note of this if we are not just counting. */ case 'S': - if (! just_count) + if (! just_count && (unsigned int) c < symcount) rptr->sym_ptr_ptr = &symbols[c]; break; /* Argument relocation bits for a function call. */ @@ -5309,7 +5310,7 @@ som_slurp_reloc_table (bfd *abfd, need it again. */ section->reloc_count = som_set_reloc_info (external_relocs, fixup_stream_size, - NULL, NULL, NULL, true); + NULL, NULL, NULL, 0, true); som_section_data (section)->reloc_stream = external_relocs; } @@ -5335,7 +5336,8 @@ som_slurp_reloc_table (bfd *abfd, /* Process and internalize the relocations. */ som_set_reloc_info (external_relocs, fixup_stream_size, - internal_relocs, section, symbols, false); + internal_relocs, section, symbols, + bfd_get_symcount (abfd), false); /* We're done with the external relocations. Free them. */ free (external_relocs); |