svn commit: r358744 - in head: lib/libsecureboot lib/libsecureboot/h lib/libsecureboot/tests share/mk stand stand/common stand/efi/loader stand/efi/loader/arch/i386 stand/ficl stand/i386/libi386 st...

Simon J. Gerraty sjg at FreeBSD.org
Sun Mar 8 17:42:46 UTC 2020


Author: sjg
Date: Sun Mar  8 17:42:42 2020
New Revision: 358744
URL: https://svnweb.freebsd.org/changeset/base/358744

Log:
  veloader use vectx API for kernel and modules
  
  The vectx API, computes the hash for verifying a file as it is read.
  This avoids the overhead of reading files twice - once to verify, then
  again to load.
  
  For doing an install via loader, avoiding the need to rewind
  large files is critical.
  
  This API is only used for modules, kernel and mdimage as these are the
  biggest files read by the loader.
  The reduction in boot time depends on how expensive the I/O is
  on any given platform.  On a fast VM we see 6% improvement.
  
  For install via loader the first file to be verified is likely to be the
  kernel, so some of the prep work (finding manifest etc) done by
  verify_file() needs to be factored so it can be reused for
  vectx_open().
  
  For missing or unrecognized fingerprint entries, we fail
  in vectx_open() unless verifying is disabled.
  
  Otherwise fingerprint check happens in vectx_close() and
  since this API is only used for files which must be verified
  (VE_MUST) we panic if we get an incorrect hash.
  
  Reviewed by:	imp,tsoome
  MFC after:	1 week
  Sponsored by:	Juniper Networks
  Differential Revision:	https://reviews.freebsd.org//D23827

Modified:
  head/lib/libsecureboot/h/libsecureboot.h
  head/lib/libsecureboot/h/verify_file.h
  head/lib/libsecureboot/tests/tvo.c
  head/lib/libsecureboot/vectx.c
  head/lib/libsecureboot/verify_file.c
  head/share/mk/src.opts.mk
  head/stand/common/bootstrap.h
  head/stand/common/interp_forth.c
  head/stand/common/interp_simple.c
  head/stand/common/load_elf.c
  head/stand/common/load_elf_obj.c
  head/stand/common/misc.c
  head/stand/common/module.c
  head/stand/efi/loader/arch/i386/i386_copy.c
  head/stand/efi/loader/copy.c
  head/stand/efi/loader/loader_efi.h
  head/stand/efi/loader/main.c
  head/stand/ficl/loader.c
  head/stand/i386/libi386/i386_copy.c
  head/stand/i386/libi386/libi386.h
  head/stand/i386/loader/chain.c
  head/stand/libofw/libofw.h
  head/stand/libofw/ofw_copy.c
  head/stand/loader.mk
  head/stand/mips/beri/loader/arch.c
  head/stand/powerpc/kboot/main.c
  head/stand/uboot/lib/copy.c
  head/stand/uboot/lib/libuboot.h
  head/stand/userboot/userboot/copy.c
  head/stand/userboot/userboot/libuserboot.h

Modified: head/lib/libsecureboot/h/libsecureboot.h
==============================================================================
--- head/lib/libsecureboot/h/libsecureboot.h	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/lib/libsecureboot/h/libsecureboot.h	Sun Mar  8 17:42:42 2020	(r358744)
@@ -69,12 +69,6 @@ void fingerprint_info_add(const char *, const char *, 
 int ve_check_hash(br_hash_compat_context *, const br_hash_class *,
     const char *, const char *, size_t);
 
-struct vectx;
-struct vectx* vectx_open(int, const char *, off_t, struct stat *, int *);
-ssize_t vectx_read(struct vectx *, void *, size_t);
-off_t vectx_lseek(struct vectx *, off_t, int);
-int vectx_close(struct vectx *);
-
 char * hexdigest(char *, size_t, unsigned char *, size_t);
 int  verify_fd(int, const char *, off_t, struct stat *);
 int  verify_open(const char *, int);

Modified: head/lib/libsecureboot/h/verify_file.h
==============================================================================
--- head/lib/libsecureboot/h/verify_file.h	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/lib/libsecureboot/h/verify_file.h	Sun Mar  8 17:42:42 2020	(r358744)
@@ -39,13 +39,21 @@
 
 struct stat;
 
-void    ve_debug_set(int);
-int     ve_status_get(int);
-void    ve_efi_init(void);
-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     verify_file(int, const char *, off_t, int);
-void    verify_pcr_export(void);
+int	verify_prep(int, const char *, off_t, struct stat *, const char *);
+void	ve_debug_set(int);
+char	*ve_error_get(void);
+void	ve_efi_init(void);
+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	verify_file(int, const char *, off_t, int, const char *);
+void	verify_pcr_export(void);
+
+struct vectx;
+struct vectx* vectx_open(int, const char *, 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 *);
 
 #endif	/* _VERIFY_FILE_H_ */

Modified: head/lib/libsecureboot/tests/tvo.c
==============================================================================
--- head/lib/libsecureboot/tests/tvo.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/lib/libsecureboot/tests/tvo.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$");
 #include <err.h>
 #include <verify_file.h>
 
+size_t DestdirLen;
+char *Destdir;
 char *Skip;
 
 int
@@ -42,7 +44,10 @@ main(int argc, char *argv[])
 	int Vflag;
 	char *cp;
 	char *prefix;
+	char *destdir;
 
+	Destdir = NULL;
+	DestdirLen = 0;
 	prefix = NULL;
 	Skip = NULL;
 
@@ -50,8 +55,12 @@ main(int argc, char *argv[])
 	printf("Trust %d\n", n);
 	Vflag = 0;
 
-	while ((c = getopt(argc, argv, "dp:s:T:V")) != -1) {
+	while ((c = getopt(argc, argv, "D:dp:s:T:V")) != -1) {
 		switch (c) {
+		case 'D':
+			Destdir = optarg;
+			DestdirLen = strlen(optarg);
+			break;
 		case 'd':
 			DebugVe++;
 			break;
@@ -92,7 +101,7 @@ main(int argc, char *argv[])
 				 */
 				int x;
 
-				x = verify_file(fd, argv[optind], 0, VE_GUESS);
+				x = verify_file(fd, argv[optind], 0, VE_GUESS, __func__);
 				printf("verify_file(%s) = %d\n", argv[optind], x);
 				close(fd);
 			}
@@ -147,7 +156,7 @@ main(int argc, char *argv[])
 				lseek(fd, 0, SEEK_SET);
 				off = st.st_size % 512;
 				vp = vectx_open(fd, argv[optind], off,
-				    &st, &error);
+				    &st, &error, __func__);
 				if (!vp) {
 					printf("vectx_open(%s) failed: %d %s\n",
 					    argv[optind], error,
@@ -155,7 +164,8 @@ main(int argc, char *argv[])
 				} else {
 					off = vectx_lseek(vp,
 					    (st.st_size % 1024), SEEK_SET);
-
+					/* we can seek backwards! */
+					off = vectx_lseek(vp, off/2, SEEK_SET);
 					if (off < st.st_size) {
 						n = vectx_read(vp, buf,
 						    sizeof(buf));
@@ -165,7 +175,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);
+					error = vectx_close(vp, VE_MUST, __func__);
 					if (error) {
 						printf("vectx_close(%s) == %d %s\n",
 						    argv[optind], error,

Modified: head/lib/libsecureboot/vectx.c
==============================================================================
--- head/lib/libsecureboot/vectx.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/lib/libsecureboot/vectx.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #include "libsecureboot-priv.h"
+#include <verify_file.h>
 
 /**
  * @file vectx.c
@@ -50,12 +51,14 @@ struct vectx {
 	const char	*vec_path;	/* path we are verifying */
 	const char	*vec_want;	/* hash value we want */
 	off_t		vec_off;	/* current offset */
+	off_t		vec_hashed;	/* where we have hashed to */
 	size_t		vec_size;	/* size of path */
 	size_t		vec_hashsz;	/* size of hash */
 	int		vec_fd;		/* file descriptor */
 	int		vec_status;	/* verification status */
 };
 
+
 /**
  * @brief
  * verify an open file as we read it
@@ -86,24 +89,31 @@ 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, int *error)
+vectx_open(int fd, const char *path, off_t off, struct stat *stp,
+    int *error, const char *caller)
 {
 	struct vectx *ctx;
 	struct stat st;
 	size_t hashsz;
 	char *cp;
+	int rc;
 
-	if (!stp) {
-		if (fstat(fd, &st) == 0)
-			stp = &st;
-	}
+	if (!stp)
+	    stp = &st;
 
-	/* we *should* only get called for files */
-	if (stp && !S_ISREG(stp->st_mode)) {
-		*error = 0;
+	rc = verify_prep(fd, path, off, stp, __func__);
+
+	DEBUG_PRINTF(2,
+	    ("vectx_open: caller=%s,name='%s',prep_rc=%d\n",
+		caller,path, rc));
+
+	switch (rc) {
+	case VE_FINGERPRINT_NONE:
+	case VE_FINGERPRINT_UNKNOWN:
+	case VE_FINGERPRINT_WRONG:
+		*error = rc;
 		return (NULL);
 	}
-
 	ctx = malloc(sizeof(struct vectx));
 	if (!ctx)
 		goto enomem;
@@ -111,10 +121,16 @@ vectx_open(int fd, const char *path, off_t off, struct
 	ctx->vec_path = path;
 	ctx->vec_size = stp->st_size;
 	ctx->vec_off = 0;
+	ctx->vec_hashed = 0;
 	ctx->vec_want = NULL;
 	ctx->vec_status = 0;
-	hashsz = 0;
+	ctx->vec_hashsz = hashsz = 0;
 
+	if (rc == 0) {
+		/* we are not verifying this */
+		*error = 0;
+		return (ctx);
+	}
 	cp = fingerprint_info_lookup(fd, path);
 	if (!cp) {
 		ctx->vec_status = VE_FINGERPRINT_NONE;
@@ -161,6 +177,10 @@ vectx_open(int fd, const char *path, off_t off, struct
 			vectx_lseek(ctx, off, SEEK_SET);
 		}
 	}
+	DEBUG_PRINTF(2,
+	    ("vectx_open: caller=%s,name='%s',hashsz=%lu,status=%d\n",
+		caller, path, (unsigned long)ctx->vec_hashsz,
+		ctx->vec_status));
 	return (ctx);
 
 enomem:					/* unlikely */
@@ -175,6 +195,8 @@ enomem:					/* unlikely */
  *
  * It is critical that all file I/O comes through here.
  * We keep track of current offset.
+ * We also track what offset we have hashed to,
+ * so we won't replay data if we seek backwards.
  *
  * @param[in] pctx
  *	pointer to ctx
@@ -190,6 +212,8 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes
 {
 	unsigned char *bp = buf;
 	int n;
+	int delta;
+	int x;
 	size_t off;
 
 	if (ctx->vec_hashsz == 0)	/* nothing to do */
@@ -201,9 +225,20 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes
 		if (n < 0)
 			return (n);
 		if (n > 0) {
-			ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], n);
-			off += n;
-			ctx->vec_off += n;
+			/* we may have seeked backwards! */
+			delta = ctx->vec_hashed - ctx->vec_off;
+			if (delta > 0) {
+				x = MIN(delta, n);
+				off += x;
+				n -= x;
+				ctx->vec_off += x;
+			}
+			if (n > 0) {
+				ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], n);
+				off += n;
+				ctx->vec_off += n;
+				ctx->vec_hashed += n;
+			}
 		}
 	} while (n > 0 && off < nbytes);
 	return (off);
@@ -213,10 +248,10 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes
  * @brief
  * vectx equivalent of lseek
  *
- * We do not actually, seek, but call vectx_read
+ * When seeking forwards we actually call vectx_read
  * to reach the desired offset.
  *
- * We do not support seeking backwards.
+ * We support seeking backwards.
  *
  * @param[in] pctx
  *	pointer to ctx
@@ -225,6 +260,8 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes
  *	desired offset
  *
  * @param[in] whence
+ * 	We try to convert whence to ``SEEK_SET``.
+ *	We do not support ``SEEK_DATA`` or ``SEEK_HOLE``.
  *
  * @return offset or error.
  */
@@ -239,22 +276,26 @@ vectx_lseek(struct vectx *ctx, off_t off, int whence)
 		return (lseek(ctx->vec_fd, off, whence));
 
 	/*
-	 * Try to convert whence to SEEK_SET
-	 * but we cannot support seeking backwards!
-	 * Nor beyond end of file.
+	 * Convert whence to SEEK_SET
 	 */
 	if (whence == SEEK_END && off <= 0) {
 		whence = SEEK_SET;
 		off += ctx->vec_size;
-	} else if (whence == SEEK_CUR && off >= 0) {
+	} else if (whence == SEEK_CUR) {
 		whence = SEEK_SET;
 		off += ctx->vec_off;
 	}
-	if (whence != SEEK_SET || off < ctx->vec_off ||
+	if (whence != SEEK_SET ||
 	    (size_t)off > ctx->vec_size) {
-		printf("ERROR: %s: unsupported operation\n",  __func__);
+		printf("ERROR: %s: unsupported operation: whence=%d off=%lld -> %lld\n",
+		    __func__, whence, (long long)ctx->vec_off, (long long)off);
 		return (-1);
 	}
+	if (off < ctx->vec_hashed) {
+		/* seeking backwards! just do it */
+		ctx->vec_off = lseek(ctx->vec_fd, off, whence);
+		return (ctx->vec_off);
+	}
 	n = 0;
 	do {
 		delta = off - ctx->vec_off;
@@ -281,16 +322,35 @@ vectx_lseek(struct vectx *ctx, off_t off, int whence)
  * @return 0 or an error.
  */
 int
-vectx_close(struct vectx *ctx)
+vectx_close(struct vectx *ctx, int severity, const char *caller)
 {
 	int rc;
 
 	if (ctx->vec_hashsz == 0) {
 		rc = ctx->vec_status;
 	} else {
+#ifdef VE_PCR_SUPPORT
+		/*
+		 * Only update pcr with things that must verify
+		 * these tend to be processed in a more deterministic
+		 * order, which makes our pseudo pcr more useful.
+		 */
+		ve_pcr_updating_set((severity == VE_MUST));
+#endif
 		rc = ve_check_hash(&ctx->vec_ctx, ctx->vec_md,
 		    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));
+	if (severity > VE_WANT || rc == VE_FINGERPRINT_WRONG)
+		printf("%serified %s\n", (rc <= 0) ? "Unv" : "V",
+		    ctx->vec_path);
+#if !defined(UNIT_TEST) && !defined(DEBUG_VECTX)
+	/* we are generally called with VE_MUST */
+	if (severity > VE_WANT && rc == VE_FINGERPRINT_WRONG)
+		panic("cannot continue");
+#endif
 	free(ctx);
 	return ((rc < 0) ? rc : 0);
 }

Modified: head/lib/libsecureboot/verify_file.c
==============================================================================
--- head/lib/libsecureboot/verify_file.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/lib/libsecureboot/verify_file.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$");
  * define MANIFEST_SKIP to Skip - in tests/tvo.c so that
  * tvo can control the value we use in find_manifest()
  */
+extern char *Destdir;
+extern size_t DestdirLen;
 extern char *Skip;
 # undef MANIFEST_SKIP
 # define MANIFEST_SKIP Skip
@@ -167,12 +169,21 @@ load_manifest(const char *name, const char *prefix,
 		ve_utc_set(stp->st_mtime);
 		content = (char *)verify_signed(name, VEF_VERBOSE);
 		if (content) {
+#ifdef UNIT_TEST
+			if (DestdirLen > 0 &&
+			    strncmp(name, Destdir, DestdirLen) == 0) {
+				name += DestdirLen;
+				if (prefix &&
+				    strncmp(prefix, Destdir, DestdirLen) == 0)
+					prefix += DestdirLen;
+			}
+#endif
 			fingerprint_info_add(name, prefix, skip, content, stp);
 			add_verify_status(stp, VE_VERIFIED);
 			loaded_manifests = 1; /* we are verifying! */
 			DEBUG_PRINTF(3, ("loaded: %s %s %s\n",
 				name, prefix, skip));
-			rc = 0;
+			rc = VE_VERIFIED;
 		} else {
 			rc = VE_FINGERPRINT_WRONG;
 			add_verify_status(stp, rc);	/* remember */
@@ -245,13 +256,15 @@ severity_guess(const char *filename)
 	return (VE_WANT);
 }
 
+static int Verifying = -1;		/* 0 if not verifying */
+
 static void
 verify_tweak(int fd, off_t off, struct stat *stp,
     char *tweak, int *accept_no_fp,
-    int *verbose, int *verifying)
+    int *verbose)
 {
 	if (strcmp(tweak, "off") == 0) {
-		*verifying = 0;
+		Verifying = 0;
 	} else if (strcmp(tweak, "strict") == 0) {
 		/* anything caller wants verified must be */
 		*accept_no_fp = VE_WANT;
@@ -314,7 +327,59 @@ getenv_int(const char *var, int def)
 	return (int)val;
 }
 
+
 /**
+ * @brief prepare to verify an open file
+ *
+ * @param[in] fd
+ * 	open descriptor
+ *
+ * @param[in] filename
+ * 	path we opened and will use to lookup fingerprint
+ *
+ * @param[in] stp
+ *	stat pointer so we can check file type
+ */
+int
+verify_prep(int fd, const char *filename, off_t off, struct stat *stp,
+    const char *caller)
+{
+	int rc;
+
+	if (Verifying < 0) {
+		Verifying = ve_trust_init();
+#ifndef UNIT_TEST
+		ve_debug_set(getenv_int("VE_DEBUG_LEVEL", VE_DEBUG_LEVEL));
+#endif
+		/* initialize ve_status with default result */
+		rc = Verifying ? VE_NOT_CHECKED : VE_NOT_VERIFYING;
+		ve_status_set(0, rc);
+		ve_status_state = VE_STATUS_NONE;
+		if (Verifying) {
+			ve_self_tests();
+			ve_anchor_verbose_set(1);
+		}
+	}
+	if (!Verifying || fd < 0)
+		return (0);
+	if (stp) {
+		if (fstat(fd, stp) < 0 || !S_ISREG(stp->st_mode))
+			return (0);
+	}
+	DEBUG_PRINTF(2,
+	    ("caller=%s,fd=%d,name='%s',off=%lld,dev=%lld,ino=%lld\n",
+		caller, fd, filename, (long long)off, (long long)stp->st_dev,
+		(long long)stp->st_ino));
+	rc = is_verified(stp);
+	if (rc == VE_NOT_CHECKED) {
+		rc = find_manifest(filename);
+	} else {
+		ve_status_set(fd, rc);
+	}
+	return (rc);
+}
+
+/**
  * @brief verify an open file
  *
  * @param[in] fd
@@ -342,45 +407,26 @@ getenv_int(const char *var, int def)
  * @return >= 0 on success < 0 on failure
  */
 int
-verify_file(int fd, const char *filename, off_t off, int severity)
+verify_file(int fd, const char *filename, off_t off, int severity,
+    const char *caller)
 {
-	static int verifying = -1;
+	static int once;
 	static int accept_no_fp = ACCEPT_NO_FP_DEFAULT;
 	static int verbose = VE_VERBOSE_DEFAULT;
 	struct stat st;
 	char *cp;
 	int rc;
 
-	if (verifying < 0) {
-		verifying = ve_trust_init();
-		verbose = getenv_int("VE_VERBOSE", VE_VERBOSE_DEFAULT);
-		ve_debug_set(getenv_int("VE_DEBUG_LEVEL", VE_DEBUG_LEVEL));
-		/* initialize ve_status with default result */
-		rc = verifying ? VE_NOT_CHECKED : VE_NOT_VERIFYING;
-		ve_status_set(0, rc);
-		ve_status_state = VE_STATUS_NONE;
-		if (verifying) {
-			ve_self_tests();
-			ve_anchor_verbose_set(1);
-		}
-	}
-	if (!verifying)
-		return (0);
+	rc = verify_prep(fd, filename, off, &st, caller);
 
-	if (fd < 0 || fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
+	if (!rc)
 		return (0);
 
-	DEBUG_PRINTF(3, ("fd=%d,name='%s',off=%lld,dev=%lld,ino=%lld\n",
-		fd, filename, (long long)off, (long long)st.st_dev,
-		(long long)st.st_ino));
-    
-
-	rc = is_verified(&st);
-	if (rc != VE_NOT_CHECKED) {
-		ve_status_set(fd, rc);
-		return (rc);
+	if (!once) {
+		once++;
+		verbose = getenv_int("VE_VERBOSE", VE_VERBOSE_DEFAULT);
 	}
-	rc = find_manifest(filename);
+
 	if (rc != VE_FINGERPRINT_WRONG && loaded_manifests) {
 		if (severity <= VE_GUESS)
 			severity = severity_guess(filename);
@@ -392,6 +438,12 @@ verify_file(int fd, const char *filename, off_t off, i
 		 */
 		ve_pcr_updating_set((severity == VE_MUST));
 #endif
+#ifdef UNIT_TEST
+		if (DestdirLen > 0 &&
+		    strncmp(filename, Destdir, DestdirLen) == 0) {
+			filename += DestdirLen;
+		}
+#endif
 		if ((rc = verify_fd(fd, filename, off, &st)) >= 0) {
 			if (verbose || severity > VE_WANT) {
 #if defined(VE_DEBUG_LEVEL) && VE_DEBUG_LEVEL > 0
@@ -412,8 +464,7 @@ verify_file(int fd, const char *filename, off_t off, i
 					if (strncmp(cp, "loader.ve.", 10) == 0) {
 						cp += 10;
 						verify_tweak(fd, off, &st, cp,
-						    &accept_no_fp, &verbose,
-						    &verifying);
+						    &accept_no_fp, &verbose);
 					}
 				}
 			}

Modified: head/share/mk/src.opts.mk
==============================================================================
--- head/share/mk/src.opts.mk	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/share/mk/src.opts.mk	Sun Mar  8 17:42:42 2020	(r358744)
@@ -222,6 +222,7 @@ __DEFAULT_DEPENDENT_OPTIONS= \
 	CLANG_FULL/CLANG \
 	LOADER_VERIEXEC/BEARSSL \
 	LOADER_EFI_SECUREBOOT/LOADER_VERIEXEC \
+	LOADER_VERIEXEC_VECTX/LOADER_VERIEXEC \
 	VERIEXEC/BEARSSL \
 
 # MK_*_SUPPORT options which default to "yes" unless their corresponding

Modified: head/stand/common/bootstrap.h
==============================================================================
--- head/stand/common/bootstrap.h	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/bootstrap.h	Sun Mar  8 17:42:42 2020	(r358744)
@@ -33,6 +33,8 @@
 #include <sys/queue.h>
 #include <sys/linker_set.h>
 
+#include "readin.h"
+
 /* Commands and return values; nonzero return sets command_errmsg != NULL */
 typedef int	(bootblk_cmd_t)(int argc, char *argv[]);
 #define	COMMAND_ERRBUFSZ	(256)
@@ -70,8 +72,8 @@ void	hexdump(caddr_t region, size_t len);
 size_t	strlenout(vm_offset_t str);
 char	*strdupout(vm_offset_t str);
 void	kern_bzero(vm_offset_t dest, size_t len);
-int	kern_pread(int fd, vm_offset_t dest, size_t len, off_t off);
-void	*alloc_pread(int fd, off_t off, size_t len);
+int	kern_pread(readin_handle_t fd, vm_offset_t dest, size_t len, off_t off);
+void	*alloc_pread(readin_handle_t fd, off_t off, size_t len);
 
 /* bcache.c */
 void	bcache_init(size_t nblks, size_t bsize);
@@ -303,7 +305,7 @@ struct arch_switch
     ssize_t	(*arch_copyout)(const vm_offset_t src, void *dest,
 				const size_t len);
     /* Read from file to module address space, same semantics as read() */
-    ssize_t	(*arch_readin)(const int fd, vm_offset_t dest,
+    ssize_t	(*arch_readin)(readin_handle_t fd, vm_offset_t dest,
 			       const size_t len);
     /* Perform ISA byte port I/O (only for systems with ISA) */
     int		(*arch_isainb)(int port);
@@ -347,10 +349,6 @@ time_t	time(time_t *tloc);
 
 #ifndef CTASSERT
 #define	CTASSERT(x)	_Static_assert(x, "compile-time assertion failed")
-#endif
-
-#ifdef LOADER_VERIEXEC
-#include <verify_file.h>
 #endif
 
 #endif /* !_BOOTSTRAP_H_ */

Modified: head/stand/common/interp_forth.c
==============================================================================
--- head/stand/common/interp_forth.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/interp_forth.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -284,7 +284,7 @@ bf_init(void)
 	/* try to load and run init file if present */
 	if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) {
 #ifdef LOADER_VERIEXEC
-		if (verify_file(fd, "/boot/boot.4th", 0, VE_GUESS) < 0) {
+		if (verify_file(fd, "/boot/boot.4th", 0, VE_GUESS, __func__) < 0) {
 			close(fd);
 			return;
 		}
@@ -386,7 +386,7 @@ interp_include(const char *filename)
 	}
 
 #ifdef LOADER_VERIEXEC
-	if (verify_file(fd, filename, 0, VE_GUESS) < 0) {
+	if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) {
 		close(fd);
 		sprintf(command_errbuf,"can't verify '%s'", filename);
 		return(CMD_ERROR);

Modified: head/stand/common/interp_simple.c
==============================================================================
--- head/stand/common/interp_simple.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/interp_simple.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -97,7 +97,7 @@ interp_include(const char *filename)
 	}
 
 #ifdef LOADER_VERIEXEC
-	if (verify_file(fd, filename, 0, VE_GUESS) < 0) {
+	if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) {
 		close(fd);
 		sprintf(command_errbuf,"can't verify '%s'", filename);
 		return(CMD_ERROR);

Modified: head/stand/common/load_elf.c
==============================================================================
--- head/stand/common/load_elf.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/load_elf.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -71,8 +71,17 @@ typedef struct elf_file {
 	size_t	firstlen;
 	int		kernel;
 	uint64_t	off;
+#ifdef LOADER_VERIEXEC_VECTX
+	struct vectx	*vctx;
+#endif
 } *elf_file_t;
 
+#ifdef LOADER_VERIEXEC_VECTX
+#define VECTX_HANDLE(ef) (ef)->vctx
+#else
+#define VECTX_HANDLE(ef) (ef)->fd
+#endif
+
 static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef,
     uint64_t loadaddr);
 static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef,
@@ -214,7 +223,20 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef)
 		close(ef->fd);
 		return (ENOMEM);
 	}
-	bytes_read = read(ef->fd, ef->firstpage, PAGE_SIZE);
+#ifdef LOADER_VERIEXEC_VECTX
+	{
+		int verror;
+
+		ef->vctx = vectx_open(ef->fd, filename, 0L, NULL, &verror, __func__);
+		if (verror) {
+			printf("Unverified %s: %s\n", filename, ve_error_get());
+			close(ef->fd);
+			free(ef->vctx);
+			return (EAUTH);
+		}
+	}
+#endif
+	bytes_read = VECTX_READ(VECTX_HANDLE(ef), ef->firstpage, PAGE_SIZE);
 	ef->firstlen = (size_t)bytes_read;
 	if (bytes_read < 0 || ef->firstlen <= sizeof(Elf_Ehdr)) {
 		err = EFTYPE; /* could be EIO, but may be small file */
@@ -245,10 +267,10 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef)
 		goto error;
 	}
 
-#ifdef LOADER_VERIEXEC
-	if (verify_file(ef->fd, filename, bytes_read, VE_MUST) < 0) {
-	    err = EAUTH;
-	    goto error;
+#if defined(LOADER_VERIEXEC) && !defined(LOADER_VERIEXEC_VECTX)
+	if (verify_file(ef->fd, filename, bytes_read, VE_MUST, __func__) < 0) {
+		err = EAUTH;
+		goto error;
 	}
 #endif
 	return (0);
@@ -259,6 +281,9 @@ error:
 		ef->firstpage = NULL;
 	}
 	if (ef->fd != -1) {
+#ifdef LOADER_VERIEXEC_VECTX
+		free(ef->vctx);
+#endif
 		close(ef->fd);
 		ef->fd = -1;
 	}
@@ -415,8 +440,20 @@ oerr:
 out:
 	if (ef.firstpage)
 		free(ef.firstpage);
-	if (ef.fd != -1)
+	if (ef.fd != -1) {
+#ifdef LOADER_VERIEXEC_VECTX
+		if (!err && ef.vctx) {
+			int verror;
+
+			verror = vectx_close(ef.vctx, VE_MUST, __func__);
+			if (verror) {
+				err = EAUTH;
+				file_discard(fp);
+			}
+		}
+#endif
 		close(ef.fd);
+	}
 	return (err);
 }
 
@@ -562,7 +599,8 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_
 			    phdr[i].p_vaddr + off, fpcopy);
 		}
 		if (phdr[i].p_filesz > fpcopy) {
-			if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy,
+			if (kern_pread(VECTX_HANDLE(ef),
+			    phdr[i].p_vaddr + off + fpcopy,
 			    phdr[i].p_filesz - fpcopy,
 			    phdr[i].p_offset + fpcopy) != 0) {
 				printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
@@ -606,7 +644,7 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_
 	chunk = (size_t)ehdr->e_shnum * (size_t)ehdr->e_shentsize;
 	if (chunk == 0 || ehdr->e_shoff == 0)
 		goto nosyms;
-	shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk);
+	shdr = alloc_pread(VECTX_HANDLE(ef), ehdr->e_shoff, chunk);
 	if (shdr == NULL) {
 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
 		    "_loadimage: failed to read section headers");
@@ -625,8 +663,8 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_
 	 */
 	chunk = shdr[ehdr->e_shstrndx].sh_size;
 	if (chunk) {
-		shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset,
-		    chunk);
+		shstr = alloc_pread(VECTX_HANDLE(ef),
+		    shdr[ehdr->e_shstrndx].sh_offset, chunk);
 		if (shstr) {
 			for (i = 0; i < ehdr->e_shnum; i++) {
 				if (strcmp(shstr + shdr[i].sh_name,
@@ -716,14 +754,14 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_
 		printf("0x%lx+0x%lx", (long)sizeof(size), (long)size);
 #endif
 
-		if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) {
+		if (VECTX_LSEEK(VECTX_HANDLE(ef), (off_t)shdr[i].sh_offset, SEEK_SET) == -1) {
 			printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
 			   "_loadimage: could not seek for symbols - skipped!");
 			lastaddr = ssym;
 			ssym = 0;
 			goto nosyms;
 		}
-		result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size);
+		result = archsw.arch_readin(VECTX_HANDLE(ef), lastaddr, shdr[i].sh_size);
 		if (result < 0 || (size_t)result != shdr[i].sh_size) {
 			printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
 			    "_loadimage: could not read symbols - skipped! "
@@ -933,14 +971,14 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, ui
 	}
 
 	size = (size_t)ef.ehdr->e_shnum * (size_t)ef.ehdr->e_shentsize;
-	shdr = alloc_pread(ef.fd, ef.ehdr->e_shoff, size);
+	shdr = alloc_pread(VECTX_HANDLE(&ef), ef.ehdr->e_shoff, size);
 	if (shdr == NULL) {
 		err = ENOMEM;
 		goto out;
 	}
 
 	/* Load shstrtab. */
-	shstrtab = alloc_pread(ef.fd, shdr[ef.ehdr->e_shstrndx].sh_offset,
+	shstrtab = alloc_pread(VECTX_HANDLE(&ef), shdr[ef.ehdr->e_shstrndx].sh_offset,
 	    shdr[ef.ehdr->e_shstrndx].sh_size);
 	if (shstrtab == NULL) {
 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
@@ -969,7 +1007,7 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, ui
 	}
 
 	/* Load set_modmetadata_set into memory */
-	err = kern_pread(ef.fd, dest, sh_meta->sh_size, sh_meta->sh_offset);
+	err = kern_pread(VECTX_HANDLE(&ef), dest, sh_meta->sh_size, sh_meta->sh_offset);
 	if (err != 0) {
 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
     "load_modmetadata: unable to load set_modmetadata_set: %d\n", err);
@@ -980,7 +1018,7 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, ui
 	dest += sh_meta->sh_size;
 
 	/* Load data sections into memory. */
-	err = kern_pread(ef.fd, dest, sh_data[0]->sh_size,
+	err = kern_pread(VECTX_HANDLE(&ef), dest, sh_data[0]->sh_size,
 	    sh_data[0]->sh_offset);
 	if (err != 0) {
 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
@@ -995,7 +1033,7 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, ui
 	ef.off = -(sh_data[0]->sh_addr - dest);
 	dest +=	(sh_data[1]->sh_addr - sh_data[0]->sh_addr);
 
-	err = kern_pread(ef.fd, dest, sh_data[1]->sh_size,
+	err = kern_pread(VECTX_HANDLE(&ef), dest, sh_data[1]->sh_size,
 	    sh_data[1]->sh_offset);
 	if (err != 0) {
 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
@@ -1017,8 +1055,20 @@ out:
 		free(shdr);
 	if (ef.firstpage != NULL)
 		free(ef.firstpage);
-	if (ef.fd != -1)
+	if (ef.fd != -1) {
+#ifdef LOADER_VERIEXEC_VECTX
+		if (!err && ef.vctx) {
+			int verror;
+
+			verror = vectx_close(ef.vctx, VE_MUST, __func__);
+			if (verror) {
+				err = EAUTH;
+				file_discard(fp);
+			}
+		}
+#endif
 		close(ef.fd);
+	}
 	return (err);
 }
 

Modified: head/stand/common/load_elf_obj.c
==============================================================================
--- head/stand/common/load_elf_obj.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/load_elf_obj.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -60,8 +60,17 @@ typedef struct elf_file {
 
 	int		fd;
 	vm_offset_t	off;
+#ifdef LOADER_VERIEXEC_VECTX
+	struct vectx	*vctx;
+#endif
 } *elf_file_t;
 
+#ifdef LOADER_VERIEXEC_VECTX
+#define VECTX_HANDLE(ef) (ef)->vctx
+#else
+#define VECTX_HANDLE(ef) (ef)->fd
+#endif
+
 static int __elfN(obj_loadimage)(struct preloaded_file *mp, elf_file_t ef,
     uint64_t loadaddr);
 static int __elfN(obj_lookup_set)(struct preloaded_file *mp, elf_file_t ef,
@@ -100,9 +109,22 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest,
 		return(EFTYPE);
 	if ((ef.fd = open(filename, O_RDONLY)) == -1)
 		return(errno);
+#ifdef LOADER_VERIEXEC_VECTX
+	{
+		int verror;
 
+		ef.vctx = vectx_open(ef.fd, filename, 0L, NULL, &verror, __func__);
+		if (verror) {
+			printf("Unverified %s: %s\n", filename, ve_error_get());
+			close(ef.fd);
+			free(ef.vctx);
+			return (EAUTH);
+		}
+	}
+#endif
+
 	hdr = &ef.hdr;
-	bytes_read = read(ef.fd, hdr, sizeof(*hdr));
+	bytes_read = VECTX_READ(VECTX_HANDLE(&ef), hdr, sizeof(*hdr));
 	if (bytes_read != sizeof(*hdr)) {
 		err = EFTYPE;	/* could be EIO, but may be small file */
 		goto oerr;
@@ -129,10 +151,10 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest,
 		goto oerr;
 	}
 
-#ifdef LOADER_VERIEXEC
-	if (verify_file(ef.fd, filename, bytes_read, VE_MUST) < 0) {
-	    err = EAUTH;
-	    goto oerr;
+#if defined(LOADER_VERIEXEC) && !defined(LOADER_VERIEXEC_VECTX)
+	if (verify_file(ef.fd, filename, bytes_read, VE_MUST, __func__) < 0) {
+		err = EAUTH;
+		goto oerr;
 	}
 #endif
 
@@ -181,6 +203,17 @@ ioerr:
 oerr:
 	file_discard(fp);
 out:
+#ifdef LOADER_VERIEXEC_VECTX
+	if (!err && ef.vctx) {
+		int verror;
+
+		verror = vectx_close(ef.vctx, VE_MUST, __func__);
+		if (verror) {
+			err = EAUTH;
+			file_discard(fp);
+		}
+	}
+#endif
 	close(ef.fd);
 	if (ef.e_shdr != NULL)
 		free(ef.e_shdr);
@@ -207,7 +240,7 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_f
 
 	/* Read in the section headers. */
 	shdrbytes = hdr->e_shnum * hdr->e_shentsize;
-	shdr = alloc_pread(ef->fd, (off_t)hdr->e_shoff, shdrbytes);
+	shdr = alloc_pread(VECTX_HANDLE(ef), (off_t)hdr->e_shoff, shdrbytes);
 	if (shdr == NULL) {
 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
 		    "_obj_loadimage: read section headers failed\n");
@@ -328,7 +361,7 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_f
 		if (cshdr == lshdr)
 			break;
 
-		if (kern_pread(ef->fd, (vm_offset_t)cshdr->sh_addr,
+		if (kern_pread(VECTX_HANDLE(ef), (vm_offset_t)cshdr->sh_addr,
 		    cshdr->sh_size, (off_t)cshdr->sh_offset) != 0) {
 			printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
 			    "_obj_loadimage: read failed\n");

Modified: head/stand/common/misc.c
==============================================================================
--- head/stand/common/misc.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/misc.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -116,10 +116,10 @@ kern_bzero(vm_offset_t dest, size_t len)
  * and it just returns 0 if successful.
  */
 int
-kern_pread(int fd, vm_offset_t dest, size_t len, off_t off)
+kern_pread(readin_handle_t fd, vm_offset_t dest, size_t len, off_t off)
 {
 
-	if (lseek(fd, off, SEEK_SET) == -1) {
+	if (VECTX_LSEEK(fd, off, SEEK_SET) == -1) {
 #ifdef DEBUG
 		printf("\nlseek failed\n");
 #endif
@@ -140,7 +140,7 @@ kern_pread(int fd, vm_offset_t dest, size_t len, off_t
  */
 /* coverity[ -tainted_data_return ] */
 void *
-alloc_pread(int fd, off_t off, size_t len)
+alloc_pread(readin_handle_t fd, off_t off, size_t len)
 {
 	void *buf;
 
@@ -152,14 +152,14 @@ alloc_pread(int fd, off_t off, size_t len)
 		errno = ENOMEM;
 		return (NULL);
 	}
-	if (lseek(fd, off, SEEK_SET) == -1) {
+	if (VECTX_LSEEK(fd, off, SEEK_SET) == -1) {
 #ifdef DEBUG
 		printf("\nlseek failed\n");
 #endif
 		free(buf);
 		return (NULL);
 	}
-	if ((size_t)read(fd, buf, len) != len) {
+	if ((size_t)VECTX_READ(fd, buf, len) != len) {
 #ifdef DEBUG
 		printf("\nread failed\n");
 #endif

Modified: head/stand/common/module.c
==============================================================================
--- head/stand/common/module.c	Sun Mar  8 16:55:34 2020	(r358743)
+++ head/stand/common/module.c	Sun Mar  8 17:42:42 2020	(r358744)
@@ -616,6 +616,14 @@ file_load_dependencies(struct preloaded_file *base_fil
 	return (error);
 }
 
+
+#ifdef LOADER_VERIEXEC_VECTX
+#define VECTX_HANDLE(fd) vctx
+#else
+#define VECTX_HANDLE(fd) fd
+#endif
+
+
 /*
  * We've been asked to load (fname) as (type), so just suck it in,
  * no arguments or anything.
@@ -627,6 +635,10 @@ file_loadraw(const char *fname, char *type, int insert
 	char			*name;
 	int				fd, got;
 	vm_offset_t			laddr;
+#ifdef LOADER_VERIEXEC_VECTX
+	struct vectx		*vctx;
+	int			verror;
+#endif
 
 	/* We can't load first */
 	if ((file_findfile(NULL, NULL)) == NULL) {
@@ -649,14 +661,27 @@ file_loadraw(const char *fname, char *type, int insert
 		return(NULL);
 	}
 
+#ifdef LOADER_VERIEXEC_VECTX
+	vctx = vectx_open(fd, name, 0L, NULL, &verror, __func__);
+	if (verror) {
+		sprintf(command_errbuf, "can't verify '%s': %s",
+		    name, ve_error_get());
+		free(name);
+		free(vctx);
+		close(fd);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list