git: 714d6d09b57e - main - imgact_elf: exclude invalid alignment requests

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sun, 12 Dec 2021 14:30:35 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=714d6d09b57e9cf98a5c3f45f869c08be5454849

commit 714d6d09b57e9cf98a5c3f45f869c08be5454849
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-12-08 09:33:57 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-12 14:28:38 +0000

    imgact_elf: exclude invalid alignment requests
    
    Only accept at most superpage alignment, or if the arch does not have
    superpages supported, artificially limit it to PAGE_SIZE * 1024.
    This is somewhat arbitrary, and e.g. could change what binaries do
    we accept between native i386 vs. amd64 ia32 with superpages disabled,
    but I do not believe the difference there is affecting anybody with
    real (useful) binaries.
    
    Reported and tested by: pho
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D33359
---
 sys/kern/imgact_elf.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 7e7d4bdc1647..3b05b38f3ed1 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1112,7 +1112,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
 	Elf_Brandinfo *brand_info;
 	struct sysentvec *sv;
 	u_long addr, baddr, et_dyn_addr, entry, proghdr;
-	u_long maxalign, mapsz, maxv, maxv1;
+	u_long maxalign, maxsalign, mapsz, maxv, maxv1;
 	uint32_t fctl0;
 	int32_t osrel;
 	bool free_interp;
@@ -1153,7 +1153,20 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
 	interp = NULL;
 	free_interp = false;
 	td = curthread;
+
+	/*
+	 * Somewhat arbitrary, limit accepted max alignment for the
+	 * loadable segment to the max supported superpage size. Too
+	 * large alignment requests are not useful and are indicators
+	 * of corrupted or outright malicious binary.
+	 */
 	maxalign = PAGE_SIZE;
+	maxsalign = PAGE_SIZE * 1024;
+	for (i = MAXPAGESIZES - 1; i > 0; i--) {
+		if (pagesizes[i] > maxsalign)
+			maxsalign = pagesizes[i];
+	}
+
 	mapsz = 0;
 
 	for (i = 0; i < hdr->e_phnum; i++) {
@@ -1161,6 +1174,11 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
 		case PT_LOAD:
 			if (n == 0)
 				baddr = phdr[i].p_vaddr;
+			if (phdr[i].p_align > maxsalign) {
+				uprintf("Invalid segment alignment\n");
+				error = ENOEXEC;
+				goto ret;
+			}
 			if (phdr[i].p_align > maxalign)
 				maxalign = phdr[i].p_align;
 			mapsz += phdr[i].p_memsz;