summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-10-20 16:55:04 +0200
committerMark Wielaard <mjw@redhat.com>2009-10-20 17:02:05 +0200
commit1adb61a4e1313b178f2db7d5ce766a505c073a24 (patch)
tree943874f558f00d936f9d7edc56487eb5d695991d
parentbf043a5f9c9f807d670276b6c389bf5439245edb (diff)
downloadsystemtap-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.c11
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);