diff options
author | Roland McGrath <roland@redhat.com> | 2008-12-11 02:09:28 -0800 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2008-12-11 02:09:28 -0800 |
commit | b28a894209451b93ba830f56e40871e44e9c7c28 (patch) | |
tree | 54e89f81fb9a783d4b3f382136c60d100c01ac0b | |
parent | d353328036180fc028fd367e5fd49e69511b4436 (diff) |
Fixes RHBZ#465878: eu-readelf crash on empty archive
-rw-r--r-- | libdwfl/ChangeLog | 7 | ||||
-rw-r--r-- | libdwfl/offline.c | 17 |
2 files changed, 19 insertions, 5 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 41ff69bc..4f03855f 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -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. diff --git a/libdwfl/offline.c b/libdwfl/offline.c index ff7b793a..b3a95dd9 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -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; |