]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: Add more sanity checks to print_debug_exception_table.
authorMark Wielaard <mjw@redhat.com>
Sun, 21 Dec 2014 21:55:54 +0000 (22:55 +0100)
committerMark Wielaard <mjw@redhat.com>
Mon, 12 Jan 2015 20:59:35 +0000 (21:59 +0100)
https://bugzilla.redhat.com/show_bug.cgi?id=1170810

Reported-by: Alexander Cherepanov <cherepan@mccme.ru>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
src/ChangeLog
src/readelf.c

index 0ae863edac29afc4cb20cbcef285262f79814320..00a587cd189e9969c489db5a8852eace55681683 100644 (file)
@@ -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.
index df0a874d679b21c7c22069d4d9c5802ab77e3723..a05b2382e3462574b34bb9970bbcd6c4626dd7a3 100644 (file)
@@ -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;