]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge from trunk, r12923 (Guard against negative symbol sizes in ELF
authorJulian Seward <jseward@acm.org>
Sun, 2 Sep 2012 21:04:15 +0000 (21:04 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 2 Sep 2012 21:04:15 +0000 (21:04 +0000)
symbol tables, #304980)

git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_8_BRANCH@12946

coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readelf.c

index 96a9f28e47a2829959a49c5fc875b6c37affa723..d42fa45250dc1ab5f8198feaa6a2f054bb8fa4a7 100644 (file)
@@ -872,8 +872,10 @@ extern Word ML_(search_one_cfitab) ( struct _DebugInfo* di, Addr ptr );
    if not found.  Binary search.  */
 extern Word ML_(search_one_fpotab) ( struct _DebugInfo* di, Addr ptr );
 
-/* Helper function for the most often needed searching for an rx mapping
-   containing the specified address range. */
+/* Helper function for the most often needed searching for an rx
+   mapping containing the specified address range.  The range must
+   fall entirely within the mapping to be considered to be within it.
+   Asserts if lo > hi; caller must ensure this doesn't happen. */
 extern struct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di,
                                                         Addr lo, Addr hi );
 
index f978522b17c8822cc891852cb4062ecfcc078873..d78dc7aabdf6993fdb57e99588ba90f6c7c92f60 100644 (file)
@@ -236,10 +236,21 @@ Bool get_elf_symbol_info (
    *sym_name_out   = sym_name;
    *sym_avma_out   = sym_svma; /* we will bias this shortly */
    *is_text_out    = True;
-   *sym_size_out   = (Int)sym->st_size;
    *sym_tocptr_out = 0; /* unknown/inapplicable */
    *from_opd_out   = False;
    *is_ifunc       = False;
+   /* Get the symbol size, but restrict it to fit in a signed 32 bit
+      int.  Also, deal with the stupid case of negative size by making
+      the size be 1.  Note that sym->st_size has type UWord,
+      effectively. */
+   { Word size_tmp = (Word)sym->st_size;
+     Word max_Int  = (1LL << 31) - 1;
+     if (size_tmp < 0)       size_tmp = 1;
+     if (size_tmp > max_Int) size_tmp = max_Int;
+     *sym_size_out = (Int)size_tmp;
+   }
+   /* After this point refer only to *sym_size_out and not to
+      sym->st_size. */
 
    /* Figure out if we're interested in the symbol.  Firstly, is it of
       the right flavour?  */
@@ -251,9 +262,9 @@ Bool get_elf_symbol_info (
         &&
         (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC 
          || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
-#ifdef STT_GNU_IFUNC
+#        ifdef STT_GNU_IFUNC
          || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
-#endif
+#        endif
         );
 
    /* Work out the svma and bias for each section as it will appear in
@@ -351,7 +362,7 @@ Bool get_elf_symbol_info (
    if (!plausible
        && *is_text_out
        && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
-       && sym->st_size > 0
+       && *sym_size_out > 0
        && di->opd_present
        && di->opd_size > 0
        && *sym_avma_out >= di->opd_avma
@@ -384,7 +395,7 @@ Bool get_elf_symbol_info (
       in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
       in /system/bin/linker:  __dl_strcmp __dl_strlen
    */
-   if (sym->st_size == 0) {
+   if (*sym_size_out == 0) {
 #     if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
       *sym_size_out = 2048;
 #     else
@@ -556,6 +567,9 @@ Bool get_elf_symbol_info (
          background. */
       Bool in_rx;
       vg_assert(di->fsm.have_rx_map);
+      /* This could actually wrap around and cause
+         ML_(find_rx_mapping) to assert.  But that seems so unlikely,
+         let's wait for it to happen before fixing it. */
       in_rx = (ML_(find_rx_mapping)(di, *sym_avma_out,
                                     *sym_avma_out + *sym_size_out) != NULL);
       if (in_text)