git: 1e6690a40729 - stable/14 - stand: Improve error handling when loading ELF files

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 09 Oct 2026 00:20:46 UTC
The branch stable/14 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=1e6690a40729a469ccc5fe6ca3de819925cb78d9

commit 1e6690a40729a469ccc5fe6ca3de819925cb78d9
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-07-31 17:51:37 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-10-08 18:41:24 +0000

    stand: Improve error handling when loading ELF files
    
    Previously all the 'goto out' statements after the image was loaded into
    memory returned success rather than an error.  This is despite comments
    indicating some of these conditions were in fact errors, and some of
    these error conditions (such as missing PT_DYNAMIC) are treated as errors
    in the kernel linker.
    
    In addition, when failing to looking up the symbols for the linker
    set, those cases returned failure leaking memory (though it's clear
    from the original code from commit ca49b3342d1e that only the second
    failure was intended to be an actual error).
    
    To avoid more confusion, move the assignment of `ret` to just before
    the `out` label so that `goto out` always returns an error.  This is a
    more consistent pattern with other code in the tree that tends to use
    labels for the error case.
    
    Restructure some other code to avoid a few bogus errors.
    Specifically, a symbol table is not required so don't treat lack of a
    symbol table as an error.  Also, if the start symbol for the module
    metadata linker set is not found, don't treat that as an error either.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D58540
    
    (cherry picked from commit 80ee17c0285e5520e9c1db6760e84b7727778df5)
---
 stand/common/load_elf.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index ec50f2970845..6d4cc5335bda 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -843,7 +843,6 @@ nosyms:
 	if (module_verbose > MODULE_VERBOSE_SILENT)
 		printf("\n");
 
-	ret = lastaddr - firstaddr;
 	fp->f_addr = firstaddr;
 
 	php = NULL;
@@ -906,25 +905,28 @@ nosyms:
 			break;
 		}
 	}
-	if (ef->hashtab == NULL || ef->symtab == NULL ||
-	    ef->strtab == NULL || ef->strsz == 0)
-		goto out;
-	COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets));
-	COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains));
-	ef->buckets = ef->hashtab + 2;
-	ef->chains = ef->buckets + ef->nbuckets;
-
-	if (__elfN(lookup_symbol)(ef, "__start_set_modmetadata_set", &sym,
-	    STT_NOTYPE) != 0)
-		return 0;
-	p_start = sym.st_value + ef->off;
-	if (__elfN(lookup_symbol)(ef, "__stop_set_modmetadata_set", &sym,
-	    STT_NOTYPE) != 0)
-		return 0;
-	p_end = sym.st_value + ef->off;
+	if (ef->hashtab != NULL && ef->symtab != NULL &&
+	    ef->strtab != NULL && ef->strsz != 0) {
+		COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets));
+		COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains));
+		ef->buckets = ef->hashtab + 2;
+		ef->chains = ef->buckets + ef->nbuckets;
+	}
 
-	if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0)
-		goto out;
+	/* Don't emit a warning if there is no symbol table. */
+	if (ef->buckets != 0 && __elfN(lookup_symbol)(ef,
+	    "__start_set_modmetadata_set", &sym, STT_NOTYPE) == 0) {
+		p_start = sym.st_value + ef->off;
+		if (__elfN(lookup_symbol)(ef, "__stop_set_modmetadata_set",
+		    &sym, STT_NOTYPE) != 0)
+			goto out;
+		p_end = sym.st_value + ef->off;
+
+		if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) != 0)
+			goto out;
+	}
+
+	ret = lastaddr - firstaddr;
 
 out:
 	if (dp)