]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: Sanity check verneed and verdef offsets in handle_symtab.
authorMark Wielaard <mark@klomp.org>
Wed, 3 Mar 2021 20:40:53 +0000 (21:40 +0100)
committerMark Wielaard <mark@klomp.org>
Wed, 3 Mar 2021 20:44:45 +0000 (21:44 +0100)
We are going through vna_next, vn_next and vd_next in a while loop.
Make sure that all offsets are sane. We don't want things to wrap
around so we go in cycles.

https://sourceware.org/bugzilla/show_bug.cgi?id=27501

Signed-off-by: Mark Wielaard <mark@klomp.org>
src/ChangeLog
src/readelf.c

index 791015bb5763a993bc340b28fd58ad7528b8e075..14cd6cacc70a8cc9d1d918653447bec8e0448c6a 100644 (file)
@@ -1,3 +1,8 @@
+2021-03-03  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (handle_symtab): Sanity check verneed vna_next,
+       vn_next and verdef vd_next offsets.
+
 2021-03-02  Timm Bäder  <tbaeder@redhat.com>
 
        * elfcompress.c (process_file): Remove cleanup() function and
index 715af3b3e616a3d29b5b8bb66983be629bfb5a9e..b97404554576b6862930108b0215a2d8841841bf 100644 (file)
@@ -2554,7 +2554,9 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                                                 &vernaux_mem);
                      while (vernaux != NULL
                             && vernaux->vna_other != *versym
-                            && vernaux->vna_next != 0)
+                            && vernaux->vna_next != 0
+                            && (verneed_data->d_size - vna_offset
+                                >= vernaux->vna_next))
                        {
                          /* Update the offset.  */
                          vna_offset += vernaux->vna_next;
@@ -2571,6 +2573,9 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                        /* Found it.  */
                        break;
 
+                     if (verneed_data->d_size - vn_offset < verneed->vn_next)
+                       break;
+
                      vn_offset += verneed->vn_next;
                      verneed = (verneed->vn_next == 0
                                 ? NULL
@@ -2606,6 +2611,9 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                        /* Found the definition.  */
                        break;
 
+                     if (verdef_data->d_size - vd_offset < verdef->vd_next)
+                       break;
+
                      vd_offset += verdef->vd_next;
                      verdef = (verdef->vd_next == 0
                                ? NULL