]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Fixes RHBZ#465878: eu-readelf crash on empty archive
authorRoland McGrath <roland@redhat.com>
Thu, 11 Dec 2008 10:09:28 +0000 (02:09 -0800)
committerRoland McGrath <roland@redhat.com>
Thu, 11 Dec 2008 10:09:28 +0000 (02:09 -0800)
libdwfl/ChangeLog
libdwfl/offline.c

index 41ff69bca104785035b31dff8cb656f8baf11a9c..4f03855f5c6b88394a7934c3ab918c390a16f4c3 100644 (file)
@@ -1,3 +1,10 @@
+2008-12-11  Roland McGrath  <roland@redhat.com>
+
+       * offline.c (process_archive): Don't call elf_end and close if
+       returning NULL.  Check first elf_begin call and set error code
+       specially for empty archive.
+       Fixes RHBZ#465878.
+
 2008-12-02  Roland McGrath  <roland@redhat.com>
 
        * dwfl_getmodules.c (dwfl_getmodules): Typo fix in last change.
index ff7b793aa4148ce78a24d5e1a46cf8649e49bdb0..b3a95dd991c9a3dce1a41a3b1a41f7c48ba99c42 100644 (file)
@@ -1,5 +1,5 @@
 /* Recover relocatibility for addresses computed from debug information.
-   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -259,16 +259,23 @@ process_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd,
 
 {
   Dwfl_Module *mod = NULL;
+  Elf *member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive);
+  if (unlikely (member == NULL)) /* Empty archive.  */
+    {
+      __libdwfl_seterrno (DWFL_E_BADELF);
+      return NULL;
+    }
+
   while (process_archive_member (dwfl, name, file_name, predicate,
-                                fd, elf_begin (fd, ELF_C_READ_MMAP_PRIVATE,
-                                               archive), &mod) != ELF_C_NULL)
-    ;
+                                fd, member, &mod) != ELF_C_NULL)
+    member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive);
 
   /* We can drop the archive Elf handle even if we're still using members
      in live modules.  When the last module's elf_end on a member returns
      zero, that module will close FD.  If no modules survived the predicate,
      we are all done with the file right here.  */
-  if (elf_end (archive) == 0)
+  if (mod != NULL              /* If no modules, caller will clean up.  */
+      && elf_end (archive) == 0)
     close (fd);
 
   return mod;