summaryrefslogtreecommitdiff
path: root/libdw/libdwP.h
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-12-04 21:43:44 +0100
committerMark Wielaard <mjw@redhat.com>2014-12-11 15:10:14 +0100
commitcb73b5a015606a02f952f7eddaba15327f6191fa (patch)
tree217bc940ebda5bcf26c4be3de047a1fbd5c3359c /libdw/libdwP.h
parentedb079a596b25379828836e501d003f20afdb879 (diff)
downloadelfutils-cb73b5a015606a02f952f7eddaba15327f6191fa.tar.gz
libdw: Add overflow checking to __libdw_form_val_len.
Pass endp as argument to __libdw_form_val_len and check we don't read beyond the end of expected data and don't return lengths that would overflow. Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libdw/libdwP.h')
-rw-r--r--libdw/libdwP.h22
1 files changed, 16 insertions, 6 deletions
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 5ccb13c4..351c5b47 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -458,14 +458,16 @@ extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
/* Helper functions for form handling. */
extern size_t __libdw_form_val_compute_len (Dwarf *dbg, struct Dwarf_CU *cu,
unsigned int form,
- const unsigned char *valp)
- __nonnull_attribute__ (1, 2, 4) internal_function;
+ const unsigned char *valp,
+ const unsigned char *endp)
+ __nonnull_attribute__ (1, 2, 4, 5) internal_function;
/* Find the length of a form attribute. */
static inline size_t
-__nonnull_attribute__ (1, 2, 4)
+__nonnull_attribute__ (1, 2, 4, 5)
__libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
- unsigned int form, const unsigned char *valp)
+ unsigned int form, const unsigned char *valp,
+ const unsigned char *endp)
{
/* Small lookup table of forms with fixed lengths. Absent indexes are
initialized 0, so any truly desired 0 is set to 0x80 and masked. */
@@ -483,11 +485,19 @@ __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
{
uint8_t len = form_lengths[form];
if (len != 0)
- return len & 0x7f; /* Mask to allow 0x80 -> 0. */
+ {
+ len &= 0x7f; /* Mask to allow 0x80 -> 0. */
+ if (unlikely (len > (size_t) (endp - valp)))
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+ return len;
+ }
}
/* Other forms require some computation. */
- return __libdw_form_val_compute_len (dbg, cu, form, valp);
+ return __libdw_form_val_compute_len (dbg, cu, form, valp, endp);
}
/* Helper function for DW_FORM_ref* handling. */