From b28a894209451b93ba830f56e40871e44e9c7c28 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 11 Dec 2008 02:09:28 -0800 Subject: [PATCH] Fixes RHBZ#465878: eu-readelf crash on empty archive --- libdwfl/ChangeLog | 7 +++++++ libdwfl/offline.c | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 41ff69b..4f03855 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,10 @@ +2008-12-11 Roland McGrath + + * 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 * dwfl_getmodules.c (dwfl_getmodules): Typo fix in last change. diff --git a/libdwfl/offline.c b/libdwfl/offline.c index ff7b793..b3a95dd 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; -- 2.7.4