aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2021-04-05 01:01:28 +0000
committerEd Maste <emaste@FreeBSD.org>2021-04-05 01:01:28 +0000
commitea444392bb5b351c930f28a02a4e68f51b25ba69 (patch)
tree26fc21b8d80d2b83347d498435289719e492ac8c
parent6f2addd838810ce33c7e9ad9543827d45e0b491c (diff)
downloadsrc-ea444392bb5b351c930f28a02a4e68f51b25ba69.tar.gz
src-ea444392bb5b351c930f28a02a4e68f51b25ba69.zip
readelf: return error in case of invalid file
GNU readelf exits with an error for a number of invalid file cases. Previously ELF Tool Chain readelf always exited with 0. Now we exit 1 upon detecting an error with one or more input files, but in any case all of them are processed. This should catch common failure cases. We still do not report an error for some types of malformed ELF files, but this is consistent with GNU readelf. PR: 252727 Reviewed by: jkoshy, markj MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29377
-rw-r--r--contrib/elftoolchain/readelf/readelf.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index 022c9e9066ab..81e6897cf3cd 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -285,7 +285,7 @@ static const char *elf_osabi(unsigned int abi);
static const char *elf_type(unsigned int type);
static const char *elf_ver(unsigned int ver);
static const char *dt_type(unsigned int mach, unsigned int dtype);
-static void dump_ar(struct readelf *re, int);
+static bool dump_ar(struct readelf *re, int);
static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe);
static void dump_attributes(struct readelf *re);
static uint8_t *dump_compatibility_tag(uint8_t *p, uint8_t *pe);
@@ -315,7 +315,7 @@ static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die,
Dwarf_Addr base);
static void dump_dwarf_str(struct readelf *re);
static void dump_eflags(struct readelf *re, uint64_t e_flags);
-static void dump_elf(struct readelf *re);
+static bool dump_elf(struct readelf *re);
static void dump_flags(struct flag_desc *fd, uint64_t flags);
static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab);
static void dump_dynamic(struct readelf *re);
@@ -7211,18 +7211,18 @@ unload_sections(struct readelf *re)
}
}
-static void
+static bool
dump_elf(struct readelf *re)
{
/* Fetch ELF header. No need to continue if it fails. */
if (gelf_getehdr(re->elf, &re->ehdr) == NULL) {
warnx("gelf_getehdr failed: %s", elf_errmsg(-1));
- return;
+ return (false);
}
if ((re->ec = gelf_getclass(re->elf)) == ELFCLASSNONE) {
warnx("gelf_getclass failed: %s", elf_errmsg(-1));
- return;
+ return (false);
}
if (re->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
re->dw_read = _read_msb;
@@ -7266,6 +7266,7 @@ dump_elf(struct readelf *re)
dump_dwarf(re);
if (re->options & ~RE_H)
unload_sections(re);
+ return (true);
}
static void
@@ -7311,7 +7312,7 @@ dump_dwarf(struct readelf *re)
dwarf_finish(re->dbg, &de);
}
-static void
+static bool
dump_ar(struct readelf *re, int fd)
{
Elf_Arsym *arsym;
@@ -7362,14 +7363,14 @@ dump_ar(struct readelf *re, int fd)
}
if (elf_rand(re->ar, SARMAG) != SARMAG) {
warnx("elf_rand() failed: %s", elf_errmsg(-1));
- return;
+ return (false);
}
}
process_members:
if ((re->options & ~RE_C) == 0)
- return;
+ return (true);
cmd = ELF_C_READ;
while ((re->elf = elf_begin(fd, cmd, re->ar)) != NULL) {
@@ -7389,11 +7390,14 @@ process_members:
elf_end(re->elf);
}
re->elf = re->ar;
+ return (true);
}
-static void
+static bool
dump_object(struct readelf *re, int fd)
{
+ bool rv = false;
+
if ((re->flags & DISPLAY_FILENAME) != 0)
printf("\nFile: %s\n", re->filename);
@@ -7407,10 +7411,10 @@ dump_object(struct readelf *re, int fd)
warnx("Not an ELF file.");
goto done;
case ELF_K_ELF:
- dump_elf(re);
+ rv = dump_elf(re);
break;
case ELF_K_AR:
- dump_ar(re, fd);
+ rv = dump_ar(re, fd);
break;
default:
warnx("Internal: libelf returned unknown elf kind.");
@@ -7418,6 +7422,7 @@ dump_object(struct readelf *re, int fd)
done:
elf_end(re->elf);
+ return (rv);
}
static void
@@ -7765,7 +7770,7 @@ main(int argc, char **argv)
fileargs_t *fa;
struct readelf *re, re_storage;
unsigned long si;
- int fd, opt, i;
+ int fd, opt, i, exit_code;
char *ep;
re = &re_storage;
@@ -7906,16 +7911,19 @@ main(int argc, char **argv)
err(1, "Unable to enter capability mode");
}
+ exit_code = EXIT_SUCCESS;
for (i = 0; i < argc; i++) {
re->filename = argv[i];
fd = fileargs_open(fa, re->filename);
if (fd < 0) {
warn("open %s failed", re->filename);
+ exit_code = EXIT_FAILURE;
} else {
- dump_object(re, fd);
+ if (!dump_object(re, fd))
+ exit_code = EXIT_FAILURE;
close(fd);
}
}
- exit(EXIT_SUCCESS);
+ exit(exit_code);
}