diff options
| author | Simon J. Gerraty <sjg@FreeBSD.org> | 2026-04-10 17:43:15 +0000 |
|---|---|---|
| committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2026-04-10 17:46:54 +0000 |
| commit | 35bbdfad28626255c63360d98c45e41f2c692ef0 (patch) | |
| tree | e03fcfd9fd379c4246a2e29f4160d582db89ede2 | |
| parent | fc68534a9ad93f6df1756ffa8e707c30a35ce4d7 (diff) | |
| -rw-r--r-- | lib/libsecureboot/h/verify_file.h | 5 | ||||
| -rw-r--r-- | lib/libsecureboot/tests/tvo.c | 6 | ||||
| -rw-r--r-- | lib/libsecureboot/vectx.c | 48 | ||||
| -rw-r--r-- | lib/libsecureboot/verify_file.c | 3 | ||||
| -rw-r--r-- | stand/common/commands.c | 2 | ||||
| -rw-r--r-- | stand/common/load_elf.c | 7 | ||||
| -rw-r--r-- | stand/common/load_elf_obj.c | 5 | ||||
| -rw-r--r-- | stand/common/module.c | 16 | ||||
| -rw-r--r-- | 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); |
