Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Apr 2021 18:46:38 GMT
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 14b0c8e7687e - stable/12 - readelf: return error in case of invalid file
Message-ID:  <202104131846.13DIkcAK058323@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=14b0c8e7687e0f5917b4d272bd16a6816cab3d12

commit 14b0c8e7687e0f5917b4d272bd16a6816cab3d12
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2021-04-05 01:01:28 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2021-04-13 18:44:59 +0000

    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)
---
 contrib/elftoolchain/readelf/readelf.c | 36 +++++++++++++++++++++-------------
 1 file 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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104131846.13DIkcAK058323>