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

            Bug ID: 34996
           Summary: ld accepts a COM (common) symbol whose st_value (used
                    as alignment) has its high bits set. bfd_log2()
                    converts it to 64. Later,
                    bfd_generic_define_common_symbol evaluates 1 << 64,
                    which is undefined behavior. UBSan reports shift
                    exponent 64 is too large,
           Product: binutils
           Version: 2.48 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: emily.west286 at gmail dot com
  Target Milestone: ---

Created attachment 17268
  --> https://sourceware.org/bugzilla/attachment.cgi?id=17268&action=edit
id:8 causing the shift overflow.

Potential duplicate of 3351, but crashed under type unsigned long int in this
report.

ld accepts common-symbol alignment that overflows a shift (elflink.c:5465)

Summary:
ld accepts a COM (common) symbol whose st_value (used as alignment) has its
high bits set. bfd_log2() converts it to 64. Later,
bfd_generic_define_common_symbol evaluates 1 << 64, which is undefined
behavior. UBSan reports shift exponent 64 is too large, and the link then fails
with alignment power 64 of section '.bss' is too big.

Attachments:
id:8 input for reproduction on build environment, below

Environment:
binutils ld from a UBSan-instrumented build. binutils-gdb commit:
819dfa7b5325656ccb58ea5f65761982bb7844e3 -fsanitize=undefined (see attached
Dockerfile) Source paths: /src/bfd/ and /src/ld/ Reproduction using the
attacked Dockerfile:

    docker run --rm -it -v "$PWD:/work" -w /work \
    -e UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=0 \
    ld-stock:latest /build/ld/ld-new afl-inputs/id:8  

Expected: link rejects the input with a clean error.
Actual: multiple UBSan reports runtime error: shift exponent 64 is too large
for 64-bit type 'long unsigned int'

    e.g., error: alignment power 64 of section '.bss' is too big.

Root cause:
Input: common symbol start with st_value = 0xffffff000000ffff. elflink.c:5465:
align = bfd_log2(st_value) returns 64. elflink.c:5472-5473: since old_alignment
is 0, the if runs and stores 64 into h->root.u.c.p->alignment_power.
linker.c:3172: bfd_generic_define_common_symbol evaluates 1 << 64 (UB),
reported by UBSan. Failure: ld’s .bss check rejects the link with alignment
power 64 of section '.bss' is too big.

Suggested fix
Reject common symbols whose alignment is out of range before calling
bfd_log2(). The maximum valid alignment is well below 64, so check st_value
against a bound (or against the largest power of two that a section can hold)
and report a malformed-input error.

Impact: In a non-sanitized build the shift is not checked, so the result is
unpredictable. No memory corruption was detected.

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

Reply via email to