https://sourceware.org/bugzilla/show_bug.cgi?id=31872

            Bug ID: 31872
           Summary: Segfault in objdump
                    (elf_slurp_reloc_table_from_section)
           Product: binutils
           Version: 2.42
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: g.priamo at diag dot uniroma1.it
  Target Milestone: ---

Created attachment 15574
  --> https://sourceware.org/bugzilla/attachment.cgi?id=15574&action=edit
Testcase

### Describe the bug 

AddressSanitizer: SEGV on unknown address in objdump
(`elf_slurp_reloc_table_from_section`).

### To Reproduce

Cloned binutils from git://sourceware.org/git/binutils-gdb.git and built
version 2.42.50.20240610 taking inspiration from the build script in
[oss-fuzz](https://github.com/google/oss-fuzz/blob/master/projects/binutils/build.sh):

```
export CFLAGS="-O0 -g -fno-omit-frame-pointer -fno-function-sections
-fno-unique-section-names -fsanitize=address"

cd binutils
sed -i 's/vfprintf (stderr/\/\//' elfcomm.c
sed -i 's/fprintf (stderr/\/\//' elfcomm.c
cd ../

./configure --disable-gdb --disable-gdbserver --disable-gdbsupport \
            --disable-libdecnumber --disable-readline --disable-sim \
            --disable-libbacktrace --disable-gas --disable-ld --disable-werror
\
      --enable-targets=all
make clean
make MAKEINFO=true && true
```

The crash also reproduces with this simpler build configuration:
```
./configure --enable-targets=all
make
```

### ASAN Output

```
./objdump -S testcase



./target: warning: testcase has a section extending past end of file
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
./target: testcase: attempt to load strings from a non-string section (number
21)
AddressSanitizer:DEADLYSIGNAL
=================================================================
==59106==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc
0x000000000000 bp 0x7ffd14f63c50 sp 0x7ffd14f639b8 T0)
==59106==Hint: pc points to the zero page.
==59106==The signal is caused by a READ memory access.
==59106==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x7f3562d3341f  (/lib/x86_64-linux-gnu/libpthread.so.0+0x1441f)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==59106==ABORTING
```

### gdb analysis
The pointer `ebd->elf_info_to_howto` points to the zero page:
`$3 = (_Bool (*)(bfd *, arelent *, Elf_Internal_Rela *)) 0x0`

```
Crashing thread backtrace:
#0  0x0000000000000000 in ??
#1  0x0000000000c163b1 in elf_slurp_reloc_table_from_section (objdump)
                       1539: _Bool elf_slurp_reloc_table_from_section(abfd =
(bfd *)0x6120000001c0, asect = (asection *)0x621000007de8, rel_hdr =
(Elf_Internal_Shdr *)0x62100000a818, reloc_count = (bfd_size_type)32, relents =
(arelent *)0x62100000bb38, symbols = (asymbol **)0x62100000b9c8, dynamic =
(_Bool)false) {
                       ||||:
                       ||||: /* Local reference: const struct elf_backend_data
* const ebd = 0x33249a0 <elf64_bed>; */
                       ||||: /* Local reference: _Bool res = false; */
                       ||||: /* Local reference: arelent * relent =
0x62100000bb38; */
                       ||||: /* Local reference: Elf_Internal_Rela rela =
{r_offset = 6, r_info = 34359738378, r_addend = 0}; */
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       1618:       && ebd->elf_info_to_howto != NULL)
                       1619:      || ebd->elf_info_to_howto_rel == NULL)
                       1620:    res = ebd->elf_info_to_howto (abfd, relent,
&rela);
                       ||||:
                       ----: }
                       at ./elfcode.h:1620

#2  0x0000000000c158f9 in bfd_elf64_slurp_reloc_table (objdump)
                       1639: _Bool bfd_elf64_slurp_reloc_table(abfd = (bfd
*)0x6120000001c0, asect = (asection *)0x621000007de8, symbols = (asymbol
**)0x62100000b9c8, dynamic = (_Bool)false) {
                       ||||:
                       ||||: /* Local reference: Elf_Internal_Shdr * rel_hdr2 =
0x62100000a818; */
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       ||||: /* Local reference: asection * asect =
0x621000007de8; */
                       1704: 
                       1705:   if (rel_hdr2
                       1706:       && !elf_slurp_reloc_table_from_section
(abfd, asect,
                       ||||:
                       ----: }
                       at ./elfcode.h:1706

#3  0x0000000000c5f16f in _bfd_elf_canonicalize_reloc (objdump)
                       9286: long _bfd_elf_canonicalize_reloc(abfd = (bfd
*)0x6120000001c0, section = (sec_ptr)0x621000007de8, relptr = (arelent
**)0x6120000004c0, symbols = (asymbol **)0x62100000b9c8) {
                       ||||:
                       ||||: /* Local reference: const struct elf_backend_data
* bed = 0x33249a0 <elf64_bed>; */
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       ||||: /* Local reference: sec_ptr section =
0x621000007de8; */
                       ||||: /* Local reference: asymbol ** symbols =
0x62100000b9c8; */
                       9293:   const struct elf_backend_data *bed =
get_elf_backend_data (abfd);
                       9294: 
                       9295:   if (! bed->s->slurp_reloc_table (abfd, section,
symbols, false))
                       ||||:
                       ----: }
                       at elf.c:9295

#4  0x0000000000b5077c in bfd_canonicalize_reloc (objdump)
                       2117: long bfd_canonicalize_reloc(abfd = (bfd
*)0x6120000001c0, asect = (sec_ptr)0x621000007de8, location = (arelent
**)0x6120000004c0, symbols = (asymbol **)0x62100000b9c8) {
                       ||||:
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       2126:     }
                       2127: 
                       2128:   return BFD_SEND (abfd, _bfd_canonicalize_reloc,
                       ||||:
                       ----: }
                       at bfd.c:2128

#5  0x0000000001dfa884 in bfd_generic_get_relocated_section_contents (objdump)
                       8569: bfd_byte
bfd_generic_get_relocated_section_contents(abfd = (bfd *)0x6120000001c0,
link_info = (struct bfd_link_info *)0x7fffffffcb60, link_order = (struct
bfd_link_order *)0x7fffffffccd0, data = (bfd_byte *)0x612000000340 "\032\001",
relocatable = (_Bool)false, symbols = (asymbol **)0x62100000b9c8) {
                       ||||:
                       ||||: /* Local reference: long int reloc_count =
140737488341632; */
                       ||||: /* Local reference: bfd * input_bfd =
0x6120000001c0; */
                       8599:     goto error_return;
                       8600: 
                       8601:   reloc_count = bfd_canonicalize_reloc (input_bfd,
                       ||||:
                       ----: }
                       at reloc.c:8601

#6  0x0000000000b51b70 in bfd_get_relocated_section_contents (objdump)
                       2644: bfd_byte bfd_get_relocated_section_contents(abfd =
(bfd *)0x6120000001c0, link_info = (struct bfd_link_info *)0x7fffffffcb60,
link_order = (struct bfd_link_order *)0x7fffffffccd0, data = (bfd_byte
*)0x612000000340 "\032\001", relocatable = (_Bool)false, symbols = (asymbol
**)0x62100000b9c8) {
                       ||||:
                       ||||: /* Local reference: bfd_byte *(*)(bfd *, struct
bfd_link_info *, struct bfd_link_order *, bfd_byte *, _Bool, asymbol **) fn =
0x1dfa4d0 <bfd_generic_get_relocated_section_contents>; */
                       ||||: /* Local reference: bfd * abfd2 = 0x6120000001c0;
*/
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       ||||: /* Local reference: struct bfd_link_info *
link_info = 0x7fffffffcb60; */
                       ||||: /* Local reference: struct bfd_link_order *
link_order = 0x7fffffffccd0; */
                       ||||: /* Local reference: bfd_byte * data =
0x612000000340 "\032\001"; */
                       ||||: /* Local reference: _Bool relocatable = false; */
                       ||||: /* Local reference: asymbol ** symbols =
0x62100000b9c8; */
                       2664:   fn =
abfd2->xvec->_bfd_get_relocated_section_contents;
                       2665: 
                       2666:   return (*fn) (abfd, link_info, link_order, data,
relocatable, symbols);
                       ||||:
                       ----: }
                       at bfd.c:2666

#7  0x0000000000b8092d in bfd_simple_get_relocated_section_contents (objdump)
                       204: bfd_byte
bfd_simple_get_relocated_section_contents(abfd = (bfd *)0x6120000001c0, sec =
(asection *)0x621000007de8, outbuf = (bfd_byte *)0x612000000340 "\032\001",
symbol_table = (asymbol **)0x62100000b9c8) {
                       |||:
                       |||: /* Local reference: bfd_byte * contents = 0x0; */
                       |||: /* Local reference: bfd * abfd = 0x6120000001c0; */
                       274:     }
                       275: 
                       276:   contents = bfd_get_relocated_section_contents
(abfd,
                       |||:
                       ---: }
                       at simple.c:276

#8  0x00000000004cd763 in load_specific_debug_section (objdump)
                       4273: _Bool load_specific_debug_section(debug = (enum
dwarf_section_display_enum)info, sec = (asection *)0x621000007de8, file = (void
*)0x6120000001c0) {
                       ||||:
                       ||||: /* Local reference: enum
dwarf_section_display_enum debug = info; */
                       ||||: /* Local reference: _Bool ret = false; */
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       4318:      && debug_displays [debug].relocate)
                       4319:    {
                       4320:      ret =
bfd_simple_get_relocated_section_contents (abfd,
                       ||||:
                       ----: }
                       at ./objdump.c:4320

#9  0x00000000004ccf07 in load_debug_section (objdump)
                       4380: _Bool load_debug_section(debug = (enum
dwarf_section_display_enum)info, file = (void *)0x6120000001c0) {
                       ||||:
                       ||||: /* Local reference: struct dwarf_section * section
= 0x36f9ff0 <debug_displays+336>; */
                       ||||: /* Local reference: const char * name = 0x1fbe520
<str> ".debug_info"; */
                       ||||: /* Local reference: asection * sec =
0x621000007de8; */
                       ||||: /* Local reference: enum
dwarf_section_display_enum debug = info; */
                       ||||: /* Local reference: void * file = 0x6120000001c0;
*/
                       4413: 
                       4414:   section->name = name;
                       4415:   return load_specific_debug_section (debug, sec,
file);
                       ||||:
                       ----: }
                       at ./objdump.c:4415

#10 0x00000000004f1a79 in load_separate_debug_files (objdump)
                       12419: _Bool load_separate_debug_files(file = (void
*)0x6120000001c0, filename = (const char *)0x621000000110 "testcase") {
                       |||||:
                       |||||: /* Local reference: void * file = 0x6120000001c0;
*/
                       12426:   if (load_debug_section (str, file)
                       12427:       && load_debug_section (abbrev, file)
                       12428:       && load_debug_section (info, file))
                       |||||:
                       -----: }
                       at ./dwarf.c:12428

#11 0x00000000004d30ad in dump_bfd (objdump)
                       5644: void dump_bfd(abfd = (bfd *)0x6120000001c0,
is_mainfile = (_Bool)true) {
                       ||||:
                       ||||: /* Local reference: _Bool is_mainfile = true; */
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       5656:   if (byte_get != NULL &&
might_need_separate_debug_info (is_mainfile))
                       5657:     {
                       5658:       load_separate_debug_files (abfd,
bfd_get_filename (abfd));
                       ||||:
                       ----: }
                       at ./objdump.c:5658

#12 0x00000000004d2ce0 in display_object_bfd (objdump)
                       5846: void display_object_bfd(abfd = (bfd
*)0x6120000001c0) {
                       ||||:
                       ||||: /* Local reference: char ** matching = 0x0; */
                       ||||: /* Local reference: bfd * abfd = 0x6120000001c0;
*/
                       5850:   if (bfd_check_format_matches (abfd, bfd_object,
&matching))
                       5851:     {
                       5852:       dump_bfd (abfd, true);
                       ||||:
                       ----: }
                       at ./objdump.c:5852

#13 0x00000000004d2be1 in display_any_bfd (objdump)
                       5882: void display_any_bfd(file = (bfd *)0x6120000001c0,
level = (int)0) {
                       ||||:
                       ||||: /* Local reference: bfd * file = 0x6120000001c0;
*/
                       5937:     }
                       5938:   else
                       5939:     display_object_bfd (file);
                       ||||:
                       ----: }
                       at ./objdump.c:5939

#14 0x00000000004d19dd in display_file (objdump)
                       5943: void display_file(filename = (char
*)0x7fffffffdfcb "testcase", target = (char *)0x0, last_file = (_Bool)true) {
                       ||||:
                       ||||: /* Local reference: bfd * file = 0x6120000001c0;
*/
                       5958:     }
                       5959: 
                       5960:   display_any_bfd (file, 0);
                       ||||:
                       ----: }
                       at ./objdump.c:5960

#15 0x00000000004d0007 in main (objdump)
                       5977: int main(argc = (int)3, argv = (char
**)0x7fffffffdbb8) {
                       ||||:
                       ||||: /* Local reference: int argc = 3; */
                       ||||: /* Local reference: char * target = 0x0; */
                       ||||: /* Local reference: char ** argv = 0x7fffffffdbb8;
*/
                       6375:    for (; optind < argc;)
                       6376:      {
                       6377:        display_file (argv[optind], target, optind
== argc - 1);
                       ||||:
                       ----: }
                       at ./objdump.c:6377

Register info:
   rax - 0x0000000000000000 (0)
   rbx - 0x00007fffffffc040 (140737488339008)
   rcx - 0x0000000000000000 (0)
   rdx - 0x00007fffffffc000 (140737488338944)
   rsi - 0x000062100000bb38 (107820859046712)
   rdi - 0x00006120000001c0 (106790066848192)
   rbp - 0x00007fffffffc270 (0x7fffffffc270)
   rsp - 0x00007fffffffbfd8 (0x7fffffffbfd8)
    r8 - 0x00000c2e7fff8070 (13393855479920)
    r9 - 0x0000000000000060 (96)
   r10 - 0x000000000000000c (12)
   r11 - 0x000000000000000c (12)
   r12 - 0x000000000041d680 (4314752)
   r13 - 0x00007fffffffdbb0 (140737488346032)
   r14 - 0x0000000000000000 (0)
   r15 - 0x0000000000000000 (0)
   rip - 0x0000000000000000 (0x0)
eflags - 0x00010246 ([ PF ZF IF RF ])
    cs - 0x00000033 (51)
    ss - 0x0000002b (43)
    ds - 0x00000000 (0)
    es - 0x00000000 (0)
    fs - 0x00000000 (0)
    gs - 0x00000000 (0)
```

### Environment info

`uname -a` output: Linux ThinkPad 5.15.0-107-generic #117~20.04.1-Ubuntu SMP
Tue Apr 30 10:35:57 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux


### Testcase
See attached testcase file

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to