diff options
author | Mark Wielaard <mjw@redhat.com> | 2014-12-21 22:55:54 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2015-01-12 21:59:35 +0100 |
commit | cda1a31d0e88fb9bea0a14996ac6fa3bd8585648 (patch) | |
tree | a173fc524fbf05185493e7ba02171fbc66f64b83 | |
parent | daf278fda6d9bd329b517757f9ba2d74619f3be7 (diff) | |
download | elfutils-cda1a31d0e88fb9bea0a14996ac6fa3bd8585648.tar.gz |
readelf: Add more sanity checks to print_debug_exception_table.
https://bugzilla.redhat.com/show_bug.cgi?id=1170810
Reported-by: Alexander Cherepanov <cherepan@mccme.ru>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/readelf.c | 18 |
2 files changed, 20 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 0ae863ed..00a587cd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2014-12-20 Mark Wielaard <mjw@redhat.com> + + * readelf.c (print_debug_exception_table): Add max_action overflow + check. Check action_table_end before reading slib128. Check + max_ar_filter underflow. + 2014-12-18 Ulrich Drepper <drepper@gmail.com> * Makefile.am: Suppress output of textrel_check command. diff --git a/src/readelf.c b/src/readelf.c index df0a874d..a05b2382 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -7853,8 +7853,10 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), { puts ("\n Action table:"); - if ((size_t) (dataend - action_table) < max_action + 1) + size_t maxdata = (size_t) (dataend - action_table); + if (max_action > maxdata || maxdata - max_action < 1) { + invalid_action_table: fputs (gettext (" <INVALID DATA>\n"), stdout); return; } @@ -7870,6 +7872,8 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter) max_ar_filter = ar_filter; int ar_disp; + if (readp >= action_table_end) + goto invalid_action_table; get_sleb128 (ar_disp, readp, action_table_end); printf (" [%4u] ar_filter: % d\n" @@ -7888,6 +7892,7 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), if (max_ar_filter > 0 && ttype_base != NULL) { + unsigned char dsize; puts ("\n TType table:"); // XXX Not *4, size of encoding; @@ -7895,20 +7900,25 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), { case DW_EH_PE_udata2: case DW_EH_PE_sdata2: - readp = ttype_base - max_ar_filter * 2; + dsize = 2; break; case DW_EH_PE_udata4: case DW_EH_PE_sdata4: - readp = ttype_base - max_ar_filter * 4; + dsize = 4; break; case DW_EH_PE_udata8: case DW_EH_PE_sdata8: - readp = ttype_base - max_ar_filter * 8; + dsize = 8; break; default: error (1, 0, gettext ("invalid TType encoding")); } + if (max_ar_filter + > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize) + goto invalid_data; + + readp = ttype_base - max_ar_filter * dsize; do { uint64_t ttype; |