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-13 18:44:59 +0000
commit14b0c8e7687e0f5917b4d272bd16a6816cab3d12 (patch)
treed074102075c8f7566514843436a2712c22e8e771
parent113f92b13ec65a1a298630c06a680997e46a155b (diff)
downloadsrc-14b0c8e7687e0f5917b4d272bd16a6816cab3d12.tar.gz
src-14b0c8e7687e0f5917b4d272bd16a6816cab3d12.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 Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29377 (cherry picked from commit ea444392bb5b351c930f28a02a4e68f51b25ba69)
-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 d1c3c0a4b714..a3b7e7a6bcac 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -280,7 +280,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);
@@ -310,7 +310,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);
@@ -7203,18 +7203,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;
@@ -7258,6 +7258,7 @@ dump_elf(struct readelf *re)
dump_dwarf(re);
if (re->options & ~RE_H)
unload_sections(re);
+ return (true);
}
static void
@@ -7303,7 +7304,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;
@@ -7354,14 +7355,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) {
@@ -7381,11 +7382,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);
@@ -7399,10 +7403,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.");
@@ -7410,6 +7414,7 @@ dump_object(struct readelf *re, int fd)
done:
elf_end(re->elf);
+ return (rv);
}
static void
@@ -7755,7 +7760,7 @@ main(int argc, char **argv)
{
struct readelf *re, re_storage;
unsigned long si;
- int fd, opt, i;
+ int fd, opt, i, exit_code;
char *ep;
re = &re_storage;
@@ -7881,16 +7886,19 @@ main(int argc, char **argv)
errx(EXIT_FAILURE, "ELF library initialization failed: %s",
elf_errmsg(-1));
+ exit_code = EXIT_SUCCESS;
for (i = 0; i < argc; i++) {
re->filename = argv[i];
fd = open(re->filename, O_RDONLY);
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);
}