git: 35bbdfad2862 - main - Pass severity to vectx_open() rather than vectx_close()

From: Simon J. Gerraty <sjg_at_FreeBSD.org>
Date: Fri, 10 Apr 2026 17:47:07 UTC
The branch main has been updated by sjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=35bbdfad28626255c63360d98c45e41f2c692ef0

commit 35bbdfad28626255c63360d98c45e41f2c692ef0
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2026-04-10 17:43:15 +0000
Commit:     Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2026-04-10 17:46:54 +0000

    Pass severity to vectx_open() rather than vectx_close()
    
    file_loadraw() can have a need to load unverified files
    like "dtrace_dof".  Allow severity_guess() to look at the filename
    but if it returns less than VE_MUST check that the type is not
    one we insist on verifying.
    
    In vectx_open if severity < VE_MUST we can allow it to be unverified.
    If passed VE_GUESS we call severity_guess().
    Regardless, we record severity in ctx so it is available to vectx_close().
    
    Sponsored by: Hewlett Packard Enterprise Development LP
    
    Reviewed by:    khng
    Differential Revision:  https://reviews.freebsd.org/D56297
---
 lib/libsecureboot/h/verify_file.h |  5 ++--
 lib/libsecureboot/tests/tvo.c     |  6 ++---
 lib/libsecureboot/vectx.c         | 48 ++++++++++++++++++++++++++-------------
 lib/libsecureboot/verify_file.c   |  3 ++-
 stand/common/commands.c           |  2 +-
 stand/common/load_elf.c           |  7 +++---
 stand/common/load_elf_obj.c       |  5 ++--
 stand/common/module.c             | 16 +++++++++++--
 stand/i386/loader/chain.c         |  4 ++--
 9 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/lib/libsecureboot/h/verify_file.h b/lib/libsecureboot/h/verify_file.h
index f918ed6d0e38..19bef24b1dee 100644
--- a/lib/libsecureboot/h/verify_file.h
+++ b/lib/libsecureboot/h/verify_file.h
@@ -51,6 +51,7 @@ int	ve_status_get(int);
 int	load_manifest(const char *, const char *, const char *, struct stat *);
 int	pass_manifest(const char *, const char *);
 int	pass_manifest_export_envs(void);
+int	severity_guess(const char *);
 void	verify_report(const char *, int, int, struct stat *);
 int	verify_file(int, const char *, off_t, int, const char *);
 void	verify_pcr_export(void);
@@ -59,9 +60,9 @@ int	is_verified(struct stat *);
 void	add_verify_status(struct stat *, int);
 
 struct vectx;
-struct vectx* vectx_open(int, const char *, off_t, struct stat *, int *, const char *);
+struct vectx* vectx_open(int, const char *, int, off_t, struct stat *, int *, const char *);
 ssize_t	vectx_read(struct vectx *, void *, size_t);
 off_t	vectx_lseek(struct vectx *, off_t, int);
-int	vectx_close(struct vectx *, int, const char *);
+int	vectx_close(struct vectx *, const char *);
 
 #endif	/* _VERIFY_FILE_H_ */
diff --git a/lib/libsecureboot/tests/tvo.c b/lib/libsecureboot/tests/tvo.c
index 7851e79c5a2a..407fcbefd6db 100644
--- a/lib/libsecureboot/tests/tvo.c
+++ b/lib/libsecureboot/tests/tvo.c
@@ -170,8 +170,8 @@ main(int argc, char *argv[])
 				fstat(fd, &st);
 				lseek(fd, 0, SEEK_SET);
 				off = st.st_size % 512;
-				vp = vectx_open(fd, argv[optind], off,
-				    &st, &error, __func__);
+				vp = vectx_open(fd, argv[optind], VE_GUESS,
+				    off, &st, &error, __func__);
 				if (!vp) {
 					printf("vectx_open(%s) failed: %d %s\n",
 					    argv[optind], error,
@@ -190,7 +190,7 @@ main(int argc, char *argv[])
 					off = vectx_lseek(vp, 0, SEEK_END);
 					/* repeating that should be harmless */
 					off = vectx_lseek(vp, 0, SEEK_END);
-					error = vectx_close(vp, VE_MUST, __func__);
+					error = vectx_close(vp, __func__);
 					if (error) {
 						printf("vectx_close(%s) == %d %s\n",
 						    argv[optind], error,
diff --git a/lib/libsecureboot/vectx.c b/lib/libsecureboot/vectx.c
index 2d56830cd81d..4b42293a0d93 100644
--- a/lib/libsecureboot/vectx.c
+++ b/lib/libsecureboot/vectx.c
@@ -60,6 +60,7 @@ struct vectx {
 	int		vec_fd;		/* file descriptor */
 	int		vec_status;	/* verification status */
 	int		vec_closing;	/* we are closing */
+	int		vec_severity;	/* usually VE_MUST */
 };
 
 
@@ -93,7 +94,8 @@ struct vectx {
  *	NULL is only returned for non-files or out-of-memory.
  */
 struct vectx *
-vectx_open(int fd, const char *path, off_t off, struct stat *stp,
+vectx_open(int fd, const char *path, int severity,
+    off_t off, struct stat *stp,
     int *error, const char *caller)
 {
 	struct vectx *ctx;
@@ -106,14 +108,19 @@ vectx_open(int fd, const char *path, off_t off, struct stat *stp,
 	    stp = &st;
 
 	rc = verify_prep(fd, path, off, stp, __func__);
+	if (severity == VE_GUESS)
+		severity = severity_guess(path);
 
 	DEBUG_PRINTF(2,
-	    ("vectx_open: caller=%s,fd=%d,name='%s',prep_rc=%d\n",
-		caller, fd, path, rc));
+	    ("vectx_open: caller=%s,fd=%d,name='%s',prep_rc=%d,severity=%d\n",
+		caller, fd, path, rc, severity));
 
 	switch (rc) {
 	case VE_FINGERPRINT_NONE:
 	case VE_FINGERPRINT_UNKNOWN:
+		if (severity < VE_MUST)
+			break;
+		/* FALLTHROUGH */
 	case VE_FINGERPRINT_WRONG:
 		*error = rc;
 		return (NULL);
@@ -127,19 +134,24 @@ vectx_open(int fd, const char *path, off_t off, struct stat *stp,
 	ctx->vec_off = 0;
 	ctx->vec_hashed = 0;
 	ctx->vec_want = NULL;
+	ctx->vec_severity = severity;
 	ctx->vec_status = 0;
 	ctx->vec_hashsz = hashsz = 0;
 	ctx->vec_closing = 0;
 
-	if (rc == 0) {
+	if (rc == VE_UNVERIFIED_OK) {
 		/* we are not verifying this */
 		*error = 0;
 		return (ctx);
 	}
 	cp = fingerprint_info_lookup(fd, path);
 	if (!cp) {
-		ctx->vec_status = VE_FINGERPRINT_NONE;
-		ve_error_set("%s: no entry", path);
+		if (severity < VE_MUST)
+			ctx->vec_status = VE_UNVERIFIED_OK;
+		else {
+			ctx->vec_status = VE_FINGERPRINT_NONE;
+			ve_error_set("%s: no entry", path);
+		}
 	} else {
 		if (strncmp(cp, "no_hash", 7) == 0) {
 			ctx->vec_status = VE_FINGERPRINT_IGNORE;
@@ -167,8 +179,12 @@ vectx_open(int fd, const char *path, off_t off, struct stat *stp,
 		    cp += 7;
 #endif
 		} else {
-			ctx->vec_status = VE_FINGERPRINT_UNKNOWN;
-			ve_error_set("%s: no supported fingerprint", path);
+			if (severity < VE_MUST)
+				ctx->vec_status = VE_UNVERIFIED_OK;
+			else {
+				ctx->vec_status = VE_FINGERPRINT_UNKNOWN;
+				ve_error_set("%s: no supported fingerprint", path);
+			}
 		}
 	}
 	*error = ctx->vec_status;
@@ -183,9 +199,9 @@ vectx_open(int fd, const char *path, off_t off, struct stat *stp,
 		}
 	}
 	DEBUG_PRINTF(2,
-	    ("vectx_open: caller=%s,name='%s',hashsz=%lu,status=%d\n",
+	    ("vectx_open: caller=%s,name='%s',hashsz=%lu,severity=%d,status=%d\n",
 		caller, path, (unsigned long)ctx->vec_hashsz,
-		ctx->vec_status));
+		severity, ctx->vec_status));
 	return (ctx);
 
 enomem:					/* unlikely */
@@ -379,7 +395,7 @@ vectx_lseek(struct vectx *ctx, off_t off, int whence)
  * @return 0 or an error.
  */
 int
-vectx_close(struct vectx *ctx, int severity, const char *caller)
+vectx_close(struct vectx *ctx, const char *caller)
 {
 	int rc;
 
@@ -393,7 +409,7 @@ vectx_close(struct vectx *ctx, int severity, const char *caller)
 		 * these tend to be processed in a more deterministic
 		 * order, which makes our pseudo pcr more useful.
 		 */
-		ve_pcr_updating_set((severity == VE_MUST));
+		ve_pcr_updating_set((ctx->vec_severity == VE_MUST));
 #endif
 		/* make sure we have hashed it all */
 		vectx_lseek(ctx, 0, SEEK_END);
@@ -401,13 +417,13 @@ vectx_close(struct vectx *ctx, int severity, const char *caller)
 		    ctx->vec_path, ctx->vec_want, ctx->vec_hashsz);
 	}
 	DEBUG_PRINTF(2,
-	    ("vectx_close: caller=%s,name='%s',rc=%d,severity=%d\n",
-		caller,ctx->vec_path, rc, severity));
-	verify_report(ctx->vec_path, severity, rc, NULL);
+	    ("vectx_close: caller=%s,name='%s',severity=%d,rc=%d\n",
+		caller,ctx->vec_path, ctx->vec_severity, rc));
+	verify_report(ctx->vec_path, ctx->vec_severity, rc, NULL);
 	if (rc == VE_FINGERPRINT_WRONG) {
 #if !defined(UNIT_TEST) && !defined(DEBUG_VECTX)
 		/* we are generally called with VE_MUST */
-		if (severity > VE_WANT)
+		if (ctx->vec_severity > VE_WANT)
 			panic("cannot continue");
 #endif
 	}
diff --git a/lib/libsecureboot/verify_file.c b/lib/libsecureboot/verify_file.c
index ee263dafe774..b1aad36672d0 100644
--- a/lib/libsecureboot/verify_file.c
+++ b/lib/libsecureboot/verify_file.c
@@ -271,7 +271,7 @@ find_manifest(const char *name)
 # define ACCEPT_NO_FP_DEFAULT	VE_MUST
 #endif
 
-static int
+int
 severity_guess(const char *filename)
 {
 	const char *cp;
@@ -285,6 +285,7 @@ severity_guess(const char *filename)
 	 */
 	if ((cp = strrchr(filename, '.'))) {
 		if (strcmp(cp, ".cookie") == 0 ||
+		    strcmp(cp, ".dof") == 0 ||
 		    strcmp(cp, ".hints") == 0 ||
 		    strcmp(cp, ".order") == 0 ||
 		    strcmp(cp, ".tgz") == 0)
diff --git a/stand/common/commands.c b/stand/common/commands.c
index 41687ece42fd..4ed247a6b935 100644
--- a/stand/common/commands.c
+++ b/stand/common/commands.c
@@ -308,7 +308,7 @@ command_set(int argc, char *argv[])
 		ves = ve_status_get(-1);
 		if (ves == VE_UNVERIFIED_OK) {
 #ifdef LOADER_VERIEXEC_TESTING
-			printf("Checking: %s\n", var);
+			printf("Checking: %s\n", argv[1]);
 #endif
 			if (is_restricted_var(argv[1])) {
 				printf("Ignoring restricted variable: %s\n",
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index b9f55a21e403..10131f7ccb88 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -283,7 +283,8 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef)
 	{
 		int verror;
 
-		ef->vctx = vectx_open(ef->fd, filename, 0L, NULL, &verror, __func__);
+		ef->vctx = vectx_open(ef->fd, filename, VE_MUST,
+		    0L, NULL, &verror, __func__);
 		if (verror) {
 			printf("Unverified %s: %s\n", filename, ve_error_get());
 			close(ef->fd);
@@ -504,7 +505,7 @@ out:
 		if (!err && ef.vctx) {
 			int verror;
 
-			verror = vectx_close(ef.vctx, VE_MUST, __func__);
+			verror = vectx_close(ef.vctx, __func__);
 			if (verror) {
 				err = EAUTH;
 				file_discard(fp);
@@ -1095,7 +1096,7 @@ out:
 		if (!err && ef.vctx) {
 			int verror;
 
-			verror = vectx_close(ef.vctx, VE_MUST, __func__);
+			verror = vectx_close(ef.vctx, __func__);
 			if (verror) {
 				err = EAUTH;
 				file_discard(fp);
diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c
index 9e32daa53696..706391ffbd8f 100644
--- a/stand/common/load_elf_obj.c
+++ b/stand/common/load_elf_obj.c
@@ -104,7 +104,8 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest,
 	{
 		int verror;
 
-		ef.vctx = vectx_open(ef.fd, filename, 0L, NULL, &verror, __func__);
+		ef.vctx = vectx_open(ef.fd, filename, VE_MUST,
+		    0L, NULL, &verror, __func__);
 		if (verror) {
 			printf("Unverified %s: %s\n", filename, ve_error_get());
 			close(ef.fd);
@@ -196,7 +197,7 @@ out:
 	if (!err && ef.vctx) {
 		int verror;
 
-		verror = vectx_close(ef.vctx, VE_MUST, __func__);
+		verror = vectx_close(ef.vctx, __func__);
 		if (verror) {
 			err = EAUTH;
 			file_discard(fp);
diff --git a/stand/common/module.c b/stand/common/module.c
index bc06ba01fa06..f75428458373 100644
--- a/stand/common/module.c
+++ b/stand/common/module.c
@@ -661,6 +661,7 @@ file_loadraw(const char *fname, const char *type, int insert)
 	vm_offset_t			laddr;
 #ifdef LOADER_VERIEXEC_VECTX
 	struct vectx		*vctx;
+	int			severity;
 	int			verror;
 #endif
 
@@ -690,7 +691,16 @@ file_loadraw(const char *fname, const char *type, int insert)
 	}
 
 #ifdef LOADER_VERIEXEC_VECTX
-	vctx = vectx_open(fd, name, 0L, NULL, &verror, __func__);
+	severity = severity_guess(name);
+	if (severity < VE_MUST) {
+		/* double check against type */
+		if (strcmp(type, "md_image") == 0
+		    || strcmp(type, "mfs_root") == 0
+		    || strcmp(type, "acpi_dsdt") == 0
+		    || strcmp(type, "cpu_microcode") == 0)
+			severity = VE_MUST;
+	}
+	vctx = vectx_open(fd, name, severity, 0L, NULL, &verror, __func__);
 	if (verror) {
 		sprintf(command_errbuf, "can't verify '%s': %s",
 		    name, ve_error_get());
@@ -741,7 +751,9 @@ file_loadraw(const char *fname, const char *type, int insert)
 	if (module_verbose > MODULE_VERBOSE_SILENT)
 		printf("size=%#jx\n", (uintmax_t)(laddr - loadaddr));
 #ifdef LOADER_VERIEXEC_VECTX
-	verror = vectx_close(vctx, VE_MUST, __func__);
+	verror = vectx_close(vctx, __func__);
+	DEBUG_PRINTF(1,("%s: vectx_close(%s): %d\n", __func__,
+		name, verror));
 	if (verror) {
 		free(name);
 		close(fd);
diff --git a/stand/i386/loader/chain.c b/stand/i386/loader/chain.c
index 9d58f9f3de33..5d8d66039770 100644
--- a/stand/i386/loader/chain.c
+++ b/stand/i386/loader/chain.c
@@ -83,7 +83,7 @@ command_chain(int argc, char *argv[])
 	}
 
 #ifdef LOADER_VERIEXEC_VECTX
-	vctx = vectx_open(fd, argv[1], 0L, NULL, &verror, __func__);
+	vctx = vectx_open(fd, argv[1], VE_MUST, 0L, NULL, &verror, __func__);
 	if (verror) {
 		sprintf(command_errbuf, "can't verify: %s", argv[1]);
 		close(fd);
@@ -127,7 +127,7 @@ command_chain(int argc, char *argv[])
 	}
 	close(fd);
 #ifdef LOADER_VERIEXEC_VECTX
-	verror = vectx_close(vctx, VE_MUST, __func__);
+	verror = vectx_close(vctx, __func__);
 	if (verror) {
 		free(vctx);
 		return (CMD_ERROR);