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

            Bug ID: 34387
           Summary: OOB read in intern_new_cie() with truncated
                    .debug_frame CIE augmentation data
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libdw
          Assignee: unassigned at sourceware dot org
          Reporter: karankurani3k at gmail dot com
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 16834
  --> https://sourceware.org/bugzilla/attachment.cgi?id=16834&action=edit
ASan trace and standalone reproducer for intern_new_cie CIE augmentation OOB
read

OOB read in libdw/cie.c intern_new_cie() (HEAD commit
6f8f78ce4a1b56f96f2db531cc2c9eddb5be1fc3)

The .debug_frame CIE augmentation parsing in intern_new_cie() reads the
non-z 'R' augmentation encoding byte without first checking that the CIE
augmentation data contains at least one byte.

Relevant read:

  cie->fde_encoding = *data++;

The issue is reachable with a crafted .debug_frame CIE whose augmentation
string is "R", but whose CIE body ends immediately after the
return_address_register field. In that case, dwarf_next_cfi() accepts zero
augmentation bytes and records augmentation_data_size as 0. Later,
intern_new_cie() interprets the "R" augmentation and dereferences data even
though no augmentation byte is available.

Relevant earlier behavior:

  if (! sized_augmentation)
    entry->cie.augmentation_data_size = bytes - entry->cie.augmentation_data;

For the non-z augmentation string "R", this can result in zero augmentation
bytes being accepted.

Minimal trigger:

  .debug_frame section is final at EOF
  CIE augmentation string: "R\0"
  section ends immediately after return_address_register
  no byte remains for the R augmentation FDE-address-encoding value

The attached reproducer creates a minimal ELF64 object with a final
.debug_frame section ending at EOF. The harness loads the ELF through
elf_memory() using an exact malloc-backed buffer and calls dwarf_getcfi()
followed by dwarf_cfi_addrframe().

ASan confirms the OOB read:

  ERROR: AddressSanitizer: heap-buffer-overflow
  READ of size 1
      #0 intern_new_cie libdw/cie.c:99
      #1 __libdw_intern_cie libdw/cie.c:197
      #2 __libdw_find_fde libdw/fde.c:308
      #3 dwarf_cfi_addrframe libdw/dwarf_cfi_addrframe.c:43
      #4 main cfi_harness.c:46

ASan reports the read starts exactly after the malloc-backed ELF buffer:

  0x512000000166 is located 0 bytes after 294-byte region
  [0x512000000040,0x512000000166)

CWE-125 (Out-of-bounds Read)
Impact: crash/DoS from crafted .debug_frame CIE augmentation data

Suggested fix: before consuming the 'R' augmentation byte in intern_new_cie(),
check that at least one byte of augmentation data is available.

Discoverer: Karan Kurani

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

Reply via email to