git: 63fc4e820c86 - main - rtld: extract header validation into new helper check_elf_headers()

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 06 Dec 2021 18:48:21 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=63fc4e820c86f5dedb80cc31b7918deb284b455e

commit 63fc4e820c86f5dedb80cc31b7918deb284b455e
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-11 17:51:26 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-06 18:46:49 +0000

    rtld: extract header validation into new helper check_elf_headers()
    
    Reviewed by:    emaste
    Discussed with: jrtc27
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D32960
---
 libexec/rtld-elf/map_object.c | 60 ++++++++++++++++++++++++-------------------
 libexec/rtld-elf/rtld.h       |  1 +
 2 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c
index b725fe93b8f6..2da323c115cc 100644
--- a/libexec/rtld-elf/map_object.c
+++ b/libexec/rtld-elf/map_object.c
@@ -345,6 +345,39 @@ error:
     return (NULL);
 }
 
+bool
+check_elf_headers(const Elf_Ehdr *hdr, const char *path)
+{
+	if (!IS_ELF(*hdr)) {
+		_rtld_error("%s: invalid file format", path);
+		return (false);
+	}
+	if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
+	    hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
+		_rtld_error("%s: unsupported file layout", path);
+		return (false);
+	}
+	if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
+	    hdr->e_version != EV_CURRENT) {
+		_rtld_error("%s: unsupported file version", path);
+		return (false);
+	}
+	if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
+		_rtld_error("%s: unsupported file type", path);
+		return (false);
+	}
+	if (hdr->e_machine != ELF_TARG_MACH) {
+		_rtld_error("%s: unsupported machine", path);
+		return (false);
+	}
+	if (hdr->e_phentsize != sizeof(Elf_Phdr)) {
+		_rtld_error(
+	    "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
+		return (false);
+	}
+	return (true);
+}
+
 static Elf_Ehdr *
 get_elf_header(int fd, const char *path, const struct stat *sbp,
     Elf_Phdr **phdr_p)
@@ -366,39 +399,14 @@ get_elf_header(int fd, const char *path, const struct stat *sbp,
 	}
 
 	/* Make sure the file is valid */
-	if (!IS_ELF(*hdr)) {
-		_rtld_error("%s: invalid file format", path);
+	if (!check_elf_headers(hdr, path))
 		goto error;
-	}
-	if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
-	    hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
-		_rtld_error("%s: unsupported file layout", path);
-		goto error;
-	}
-	if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
-	    hdr->e_version != EV_CURRENT) {
-		_rtld_error("%s: unsupported file version", path);
-		goto error;
-	}
-	if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
-		_rtld_error("%s: unsupported file type", path);
-		goto error;
-	}
-	if (hdr->e_machine != ELF_TARG_MACH) {
-		_rtld_error("%s: unsupported machine", path);
-		goto error;
-	}
 
 	/*
 	 * We rely on the program header being in the first page.  This is
 	 * not strictly required by the ABI specification, but it seems to
 	 * always true in practice.  And, it simplifies things considerably.
 	 */
-	if (hdr->e_phentsize != sizeof(Elf_Phdr)) {
-		_rtld_error(
-	    "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
-		goto error;
-	}
 	if (phdr_in_zero_page(hdr)) {
 		phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff);
 	} else {
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index b216e80115bc..48b3ad526828 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -405,6 +405,7 @@ void free_tls_offset(Obj_Entry *obj);
 const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
 int convert_prot(int elfflags);
 void *_get_tp(void);	/* libc implementation */
+bool check_elf_headers(const Elf_Ehdr *hdr, const char *path);
 
 /*
  * MD function declarations.