From: Sayed Kaif Date: Mon, 6 Jul 2026 07:12:35 +0000 (+0530) Subject: libdw: Fix out-of-bounds read in CFI DW_CFA_advance_loc1 handling X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=77156c031116e7759783ced4fe61b99e72a35a5e;p=thirdparty%2Felfutils.git libdw: Fix out-of-bounds read in CFI DW_CFA_advance_loc1 handling execute_cfi walks a CFI instruction stream delimited by program and end. The outer loop condition (program < end) only guarantees that the opcode byte is present. The DW_CFA_advance_loc1 case then reads a one-byte operand with operand = *program++; without first checking that another byte is available. The sibling cases DW_CFA_advance_loc2/4/8 all guard their fixed-size reads with cfi_assert (program + N <= end), and readelf's own CFI printer guards advance_loc1 with an equivalent check, but this path was missing it. A crafted or truncated FDE/CIE whose instruction stream ends exactly on a DW_CFA_advance_loc1 opcode therefore causes a one-byte read past the end of the CFI data buffer. Add the matching bounds check so malformed input is rejected with DWARF_E_INVALID_CFI instead. Signed-off-by: Sayed Kaif --- diff --git a/libdw/cfi.c b/libdw/cfi.c index 743bfc07..a9607246 100644 --- a/libdw/cfi.c +++ b/libdw/cfi.c @@ -146,6 +146,7 @@ execute_cfi (Dwarf_CFI *cache, /* These cases move LOC, i.e. "create a new table row". */ case DW_CFA_advance_loc1: + cfi_assert (program + 1 <= end); operand = *program++; FALLTHROUGH; case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX: