]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: When the version chain ends, stop processing the entries.
authorMark Wielaard <mjw@redhat.com>
Mon, 17 Nov 2014 22:35:28 +0000 (23:35 +0100)
committerMark Wielaard <mjw@redhat.com>
Mon, 17 Nov 2014 22:42:56 +0000 (23:42 +0100)
The version definition, auxiliary version, version dependency and needed
version sections chain information together through "next" fields. When
the "next" field is zero there are no more information entries. Stop
processing when we see zero instead of repeatedly processing the same
entry (at offset zero from the current one).

Signed-off-by: Mark Wielaard <mjw@redhat.com>
src/ChangeLog
src/readelf.c

index 727d1001ab2ffc88dae76ca3c3ed63d1bc6d2d4c..2ab15942a39b09a9abf5e32ae4f75ad52387b217 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+       * readelf.c (handle_verneed): Check vna_next and vn_next exist.
+       (handle_verdef): Check vda_next and vd_next exist.
+       (handle_versym): Check vd_next, vna_next and vn_next exist.
+       Check vername and filename are not NULL before use.
+
 2014-11-17  Mark Wielaard  <mjw@redhat.com>
 
        * elfcmp.c (main): Check section names are NULL before use.
index bd97ca6dfeb8e18bd783abe7e971d96cd856a08d..c14bfb66c47ca2a4c86f74d07663c593b9812bcb 100644 (file)
@@ -2505,10 +2505,16 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                  get_ver_flags (aux->vna_flags),
                  (unsigned short int) aux->vna_other);
 
+         if (aux->vna_next == 0)
+           break;
+
          auxoffset += aux->vna_next;
        }
 
       /* Find the next offset.  */
+      if (need->vn_next == 0)
+       break;
+
       offset += need->vn_next;
     }
 }
@@ -2583,10 +2589,15 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                  auxoffset, cnt2,
                  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
 
+         if (aux->vda_next == 0)
+           break;
+
          auxoffset += aux->vda_next;
        }
 
       /* Find the next offset.  */
+      if (def->vd_next == 0)
+       break;
       offset += def->vd_next;
     }
 }
@@ -2665,6 +2676,8 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
 
              nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
 
+             if (def->vd_next == 0)
+               break;
              offset += def->vd_next;
            }
        }
@@ -2709,9 +2722,13 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                  nvername = MAX (nvername,
                                  (size_t) (aux->vna_other & 0x7fff));
 
+                 if (aux->vna_next == 0)
+                   break;
                  auxoffset += aux->vna_next;
                }
 
+             if (need->vn_next == 0)
+               break;
              offset += need->vn_next;
            }
        }
@@ -2763,6 +2780,8 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
              filename[def->vd_ndx & 0x7fff] = NULL;
 
+             if (def->vd_next == 0)
+               break;
              offset += def->vd_next;
            }
        }
@@ -2800,9 +2819,13 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
                  filename[aux->vna_other & 0x7fff]
                    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
 
+                 if (aux->vna_next == 0)
+                   break;
                  auxoffset += aux->vna_next;
                }
 
+             if (need->vn_next == 0)
+               break;
              offset += need->vn_next;
            }
        }
@@ -2863,10 +2886,11 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
        default:
          n = printf ("%4d%c%s",
                      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
-                     (unsigned int) (*sym & 0x7fff) < nvername
+                     (vername != NULL
+                      && (unsigned int) (*sym & 0x7fff) < nvername)
                      ? vername[*sym & 0x7fff] : "???");
          if ((unsigned int) (*sym & 0x7fff) < nvername
-             && filename[*sym & 0x7fff] != NULL)
+             && filename != NULL && filename[*sym & 0x7fff] != NULL)
            n += printf ("(%s)", filename[*sym & 0x7fff]);
          printf ("%*s", MAX (0, 33 - (int) n), " ");
          break;