summaryrefslogtreecommitdiffstats
path: root/libdw
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-01-04 16:08:22 +0100
committerMark Wielaard <[email protected]>2015-01-15 14:19:55 +0100
commita1ea2423c0245d4a9f84523bcb5cb7cc96a27ec8 (patch)
treee4db45f2b0bb01b9ed83a7edb10d029e34f85392 /libdw
parente16e14100fe2ff70535977fe9ebd32f8d7ca5146 (diff)
libdw: Check register number in CFI isn't insanely large.
Some cfi.c array size allocation calculations might overflow when trying to accommodate insanely large number of registers. Don't allow register numbers larger than INT32_MAX / sizeof (dwarf_frame_register). Found by afl-fuzz. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/cfi.c11
2 files changed, 15 insertions, 1 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 6c8fe0f6..b3093a16 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-01-04 Mark Wielaard <[email protected]>
+
+ * cfi.c (enough_registers): Check reg < INT32_MAX / sizeof
+ (dwarf_frame_register).
+
2015-01-02 Mark Wielaard <[email protected]>
* dwarf_getcfi_elf.c (parse_eh_frame_hdr): Add size check.
diff --git a/libdw/cfi.c b/libdw/cfi.c
index 632e91d3..5a6f956d 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -1,5 +1,5 @@
/* CFI program execution.
- Copyright (C) 2009-2010, 2014 Red Hat, Inc.
+ Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -79,6 +79,15 @@ execute_cfi (Dwarf_CFI *cache,
Dwarf_Frame *fs = *state;
inline bool enough_registers (Dwarf_Word reg)
{
+ /* Don't allow insanely large register numbers. 268435456 registers
+ should be enough for anybody. And very large values might overflow
+ the array size and offsetof calculations below. */
+ if (unlikely (reg >= INT32_MAX / sizeof (fs->regs[0])))
+ {
+ result = DWARF_E_INVALID_CFI;
+ return false;
+ }
+
if (fs->nregs <= reg)
{
size_t size = offsetof (Dwarf_Frame, regs[reg + 1]);