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

--- Comment #238 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Alan Modra <[email protected]>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=335d76afde546678f9432fab956679b69c5740b6

commit 335d76afde546678f9432fab956679b69c5740b6
Author: Harshit Kumar <[email protected]>
Date:   Mon Oct 5 03:14:53 2026 +0530

    bfd: validate COFF and XCOFF symbol tables before the linker walks them

    Linker passes in cofflink.c and xcofflink.c walk the symbol table,
    advancing per-symbol state arrays by (1 + n_numaux) entries.  These
    arrays include sym_hashes, sym_indices, csect_cache, and debug_index.
    File headers supply obj_raw_syment_count to size these arrays.  A symbol
    can claim more auxiliary entries than remain in the table, driving
    pointers past their allocated buffers.  The condition can drive
    symbol-table and parallel-state cursors out of bounds.  In
    xcoff_link_input_bfd, this condition demonstrably causes heap writes
    into flinfo.sym_indices.

    Prior commits hardened adjacent code paths:
    - Commit d7e49fd331d ("Report aux buffer overrun in
      coff_get_normalized_symtab") added diagnostic reporting to the
      existing PR 17512 auxiliary-entry bounds check.
    - Commit c2bf7de1eb7 ("xcofflink buffer overflows") bounds-checked the
      XTY_LD x_scnlen index and relocation r_symndx in
      xcoff_link_add_symbols.
    - Commit 23acf2f003f ("PR 34053 buffer overflow in
      xcoff_link_add_symbols") added CSECT_SYM_P checks in
      xcoff_link_add_symbols.

    PE DLL processing calls coff_get_normalized_symtab during link finish.
    The generic COFF linker backend paths hardened here directly walk raw
    external symbols without first canonicalizing them.  Therefore, these
    generic paths require direct validation.

    The XCOFF linker never calls coff_get_normalized_symtab.  It reads
    obj_coff_external_syms directly.  Therefore, PR 17512 checks do not
    execute for XCOFF.  This omission leaves two unvalidated paths:

    1. In xcoff_link_check_ar_symbols, an unchecked n_numaux advances the
    raw symbol pointer past remaining entries and skips subsequent symbols,
    leaving the member unvalidated before extraction into the link.
    2. Non-csect symbols such as .file (class C_FILE, 103) bypass the
    CSECT_SYM_P check in xcoff_link_add_symbols.  In xcoff_link_input_bfd,
    the loop writes out of bounds into flinfo.sym_indices.

    Separately, generic COFF links also directly walk raw external symbols
    without canonicalization.  In coff_link_add_object_symbols and
    _bfd_coff_link_input_bfd, the loops advance parallel cursors without
    checking symbol bounds.

    Function fill_comdat_hash walks raw symbols.  Its auxiliary access is
    already bounded by PR 17512.  It does not advance a parallel heap array.
    Therefore, this patch does not change fill_comdat_hash.  The patch
    deliberately does not add duplicate checks inside inner consuming loops.
    Entry validation protects all subsequent loop passes.

    Add helper function _bfd_coff_check_symbol_table in bfd/coffgen.c.  The
    helper walks raw external symbols once after reading.  It verifies that
    (1 + n_numaux) does not exceed remaining entries.  The helper runs at
    linker entry points before array allocations advance.  Valid objects
    match declared table sizes exactly and pass unchanged.  The helper
    reuses the missing aux entries diagnostic from coffgen.c.  Because
    n_numaux is unsigned char, (bfd_size_type) sym.n_numaux + 1 cannot wrap.

    Tested on an x86_64-pc-linux-gnu host with ld configured for
    --target=rs6000-aix5 --enable-targets=i386-pe.  The new test
    ld-powerpc/xcoff-aux.exp reports 7 passes and 0 unexpected failures.  On
    the unpatched baseline (commit ac7113d5e24), the malformed testcases
    fail before the fix: standalone non-csect overruns fail with assertion
    or SIGABRT (status 134); archive member overruns crash with SIGSEGV
    (status 139) in bfd_xcoff_build_dynamic_sections.  The csect case passes
    on both builds because commit 23acf2f003f already rejects it, so the
    four non-csect standalone and archive cases discriminate the new fix.

    The test file ld/testsuite/ld-powerpc/xcoff-aux.exp tests standalone
    objects and archive members (covering exact-fit controls, boundary
    conditions, and inflated overruns).  The DejaGnu driver finds the test
    automatically without driver modifications.

    bfd/
            * libcoff-in.h (_bfd_coff_check_symbol_table): Declare.
            * libcoff.h: Regenerate.
            * coffgen.c (_bfd_coff_check_symbol_table): New function.
            * cofflink.c (coff_link_add_object_symbols): Call
            _bfd_coff_check_symbol_table.
            (_bfd_coff_link_input_bfd): Likewise.
            * xcofflink.c (xcoff_link_add_object_symbols): Call
            _bfd_coff_check_symbol_table.
            (xcoff_link_check_archive_element): Likewise; free symbols
            on check failure when !keep_syms_p.
            (bfd_xcoff_build_dynamic_sections): Likewise.
            (xcoff_link_input_bfd): Likewise.

    ld/
            * testsuite/ld-powerpc/xcoff-aux.exp: New test.

    Signed-off-by: Harshit Kumar <[email protected]>

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

Reply via email to