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

            Bug ID: 34895
           Summary: ld -z pack-relative-relocs: NULL dereference in
                    _bfd_x86_elf_link_relax_section for a relocation
                    against symbol 0 with a one-entry symtab
           Product: binutils
           Version: 2.48 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: martin.mirchev at u dot nus.edu
  Target Milestone: ---

_bfd_x86_elf_link_relax_section() (bfd/elfxx-x86.c) loads local symbols only
when sh_info > 1:

    1134   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
    1135   if (isymbuf == NULL && symtab_hdr->sh_info > 1)

but later treats any r_symndx < sh_info as local:

    1181   if (r_symndx < symtab_hdr->sh_info)
    1183     isym = isymbuf + r_symndx;
    1184     switch (isym->st_shndx)

With sh_info == 1 and a relocation against symbol 0, isymbuf stays NULL and
line 1184 reads address 0x1c.

Tested on master 1ec1cee48577c7b1960ddce5a6054b3f9fab6ef5 (GNU ld
2.47.50.20261027). Release: Ubuntu 22.04 gcc 11 -g -O2. ASan:
-O1 -g -fsanitize=address,undefined.

Attached (all files in ld-x86-relr-null-isym.tar.gz): relr-null-isym.s,
make-relr-null-isym.c, relr-null-isym.o,
relr-control.o. relr-null-isym.o is the .s assembled and then edited so that
the symtab holds only the null entry (sh_info 1) and the R_X86_64_64 in
.rela.data points at symbol 0. relr-control.o is the object before the edit.

  $ ld -shared -z pack-relative-relocs -o out.so relr-null-isym.o
  Segmentation fault (exit 139)
  $ ld -shared -z pack-relative-relocs -o out.so relr-control.o   (exit 0)

ASan+UBSan:
  bfd/elfxx-x86.c:1184:16: runtime error: member access within null pointer of
type 'struct Elf_Internal_Sym'
  ERROR: AddressSanitizer: SEGV on unknown address 0x00000000001c
  The signal is caused by a READ memory access.
    #0 _bfd_x86_elf_link_relax_section bfd/elfxx-x86.c:1184
    #1 lang_size_sections_1 ld/ldlang.c:6575
    #4 one_lang_size_sections_pass ld/ldlang.c:6780
    #5 lang_size_sections ld/ldlang.c:6881
    #6 lang_relax_sections ld/ldlang.c:8314
    #7 ldelf_map_segments ld/ldelfgen.c:266
    #8 gldelf_x86_64_after_allocation ld/eelf_x86_64.c:193
    #10 lang_process ld/ldlang.c:8960
    #11 main ld/ldmain.c:971

The control links cleanly in both builds.

The load condition and the local-index test should agree: either load the
symbols whenever sh_info is non-zero, or reject a symbol-0 relocation (or a
NULL isymbuf) with a bad-value error before the dereference.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified
manually.

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

Reply via email to