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 <skaif@digiscrypt.com>
/* 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: