diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-10-20 16:55:04 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-10-20 17:02:05 +0200 |
commit | 1adb61a4e1313b178f2db7d5ce766a505c073a24 (patch) | |
tree | 943874f558f00d936f9d7edc56487eb5d695991d | |
parent | bf043a5f9c9f807d670276b6c389bf5439245edb (diff) | |
download | systemtap-steved-1adb61a4e1313b178f2db7d5ce766a505c073a24.tar.gz systemtap-steved-1adb61a4e1313b178f2db7d5ce766a505c073a24.tar.xz systemtap-steved-1adb61a4e1313b178f2db7d5ce766a505c073a24.zip |
Make sure cie and fde end point to sane values in while doing unwind_frame.
* runtime/unwind.c (unwind_frame): Check end read from cie or fde doesn't
go passed end of unwind table.
-rw-r--r-- | runtime/unwind.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/runtime/unwind.c b/runtime/unwind.c index 0b4e6a9e..0e95ba08 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -677,6 +677,12 @@ static int unwind_frame(struct unwind_frame_info *frame, state.cieEnd = ptr; /* keep here temporarily */ ptr = (const u8 *)(cie + 2); end = (const u8 *)(cie + 1) + *cie; + + /* end should fall within unwind table. */ + if (((void *)end) < table + || ((void *)end) > ((void *)(table + table_len))) + goto err; + frame->call_frame = 1; if ((state.version = *ptr) != 1) { dbug_unwind(1, "CIE version number is %d. 1 is supported.\n", state.version); @@ -734,6 +740,11 @@ static int unwind_frame(struct unwind_frame_info *frame, state.cieEnd = end; end = (const u8 *)(fde + 1) + *fde; + /* end should fall within unwind table. */ + if (((void*)end) < table + || ((void *)end) > ((void *)(table + table_len))) + goto err; + /* skip augmentation */ if (((const char *)(cie + 2))[1] == 'z') { uleb128_t augSize = get_uleb128(&ptr, end); |