summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2020-03-08 17:42:42 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2020-03-08 17:42:42 +0000
commitafc571b1a6fb341b0e3f603d4f3a2538093e91f5 (patch)
treea446172ecf9eb86977386f59f06ecfdd1bc7b1b2
parent601ee53858f61e7a130dc2e306202b5297626d25 (diff)
downloadsrc-test2-afc571b1a6fb341b0e3f603d4f3a2538093e91f5.tar.gz
src-test2-afc571b1a6fb341b0e3f603d4f3a2538093e91f5.zip
Notes
-rw-r--r--lib/libsecureboot/h/libsecureboot.h6
-rw-r--r--lib/libsecureboot/h/verify_file.h24
-rw-r--r--lib/libsecureboot/tests/tvo.c20
-rw-r--r--lib/libsecureboot/vectx.c104
-rw-r--r--lib/libsecureboot/verify_file.c117
-rw-r--r--share/mk/src.opts.mk1
-rw-r--r--stand/common/bootstrap.h12
-rw-r--r--stand/common/interp_forth.c4
-rw-r--r--stand/common/interp_simple.c2
-rw-r--r--stand/common/load_elf.c86
-rw-r--r--stand/common/load_elf_obj.c47
-rw-r--r--stand/common/misc.c10
-rw-r--r--stand/common/module.c43
-rw-r--r--stand/efi/loader/arch/i386/i386_copy.c5
-rw-r--r--stand/efi/loader/copy.c4
-rw-r--r--stand/efi/loader/loader_efi.h3
-rw-r--r--stand/efi/loader/main.c2
-rw-r--r--stand/ficl/loader.c2
-rw-r--r--stand/i386/libi386/i386_copy.c4
-rw-r--r--stand/i386/libi386/libi386.h4
-rw-r--r--stand/i386/loader/chain.c31
-rw-r--r--stand/libofw/libofw.h3
-rw-r--r--stand/libofw/ofw_copy.c4
-rw-r--r--stand/loader.mk3
-rw-r--r--stand/mips/beri/loader/arch.c6
-rw-r--r--stand/powerpc/kboot/main.c8
-rw-r--r--stand/uboot/lib/copy.c4
-rw-r--r--stand/uboot/lib/libuboot.h3
-rw-r--r--stand/userboot/userboot/copy.c4
-rw-r--r--stand/userboot/userboot/libuserboot.h3
30 files changed, 422 insertions, 147 deletions
diff --git a/lib/libsecureboot/h/libsecureboot.h b/lib/libsecureboot/h/libsecureboot.h
index d7d72e880744..581b72b411d2 100644
--- a/lib/libsecureboot/h/libsecureboot.h
+++ b/lib/libsecureboot/h/libsecureboot.h
@@ -69,12 +69,6 @@ void fingerprint_info_add(const char *, 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);
diff --git a/lib/libsecureboot/h/verify_file.h b/lib/libsecureboot/h/verify_file.h
index c10f17af1469..844b8266f42c 100644
--- a/lib/libsecureboot/h/verify_file.h
+++ b/lib/libsecureboot/h/verify_file.h
@@ -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_ */
diff --git a/lib/libsecureboot/tests/tvo.c b/lib/libsecureboot/tests/tvo.c
index ad3bccb0614f..879d87f128f1 100644
--- a/lib/libsecureboot/tests/tvo.c
+++ b/lib/libsecureboot/tests/tvo.c
@@ -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,
diff --git a/lib/libsecureboot/vectx.c b/lib/libsecureboot/vectx.c
index 97a8d97efb88..908e24fb554c 100644
--- a/lib/libsecureboot/vectx.c
+++ b/lib/libsecureboot/vectx.c
@@ -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 stat *stp, int *error)
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 stat *stp, int *error)
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);
}
diff --git a/lib/libsecureboot/verify_file.c b/lib/libsecureboot/verify_file.c
index 92845fb6879d..eee749667759 100644
--- a/lib/libsecureboot/verify_file.c
+++ b/lib/libsecureboot/verify_file.c
@@ -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,6 +327,58 @@ 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
*
@@ -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, int severity)
*/
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, int severity)
if (strncmp(cp, "loader.ve.", 10) == 0) {
cp += 10;
verify_tweak(fd, off, &st, cp,
- &accept_no_fp, &verbose,
- &verifying);
+ &accept_no_fp, &verbose);
}
}
}
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 287ac5559f63..c301f72dc96e 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -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
diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
index 3e723765104e..2be6538efe4c 100644
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -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);
@@ -349,8 +351,4 @@ time_t time(time_t *tloc);
#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed")
#endif
-#ifdef LOADER_VERIEXEC
-#include <verify_file.h>
-#endif
-
#endif /* !_BOOTSTRAP_H_ */
diff --git a/stand/common/interp_forth.c b/stand/common/interp_forth.c
index 04b94ff20a15..19f1c75dc191 100644
--- a/stand/common/interp_forth.c
+++ b/stand/common/interp_forth.c
@@ -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);
diff --git a/stand/common/interp_simple.c b/stand/common/interp_simple.c
index 80d756f9dfeb..e25743d4f01c 100644
--- a/stand/common/interp_simple.c
+++ b/stand/common/interp_simple.c
@@ -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);
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index 9a1c81b62ed9..cb542718fe2f 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -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_t ef, uint64_t off)
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_t ef, uint64_t off)
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_t ef, uint64_t off)
*/
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_t ef, uint64_t off)
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, uint64_t dest)
}
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, uint64_t dest)
}
/* 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, uint64_t dest)
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, uint64_t dest)
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);
}
diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c
index ae45ce7366b7..4bff74764922 100644
--- a/stand/common/load_elf_obj.c
+++ b/stand/common/load_elf_obj.c
@@ -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_file_t ef, uint64_t off)
/* 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_file_t ef, uint64_t off)
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");
diff --git a/stand/common/misc.c b/stand/common/misc.c
index 75dc475991c5..d85597522f8a 100644
--- a/stand/common/misc.c
+++ b/stand/common/misc.c
@@ -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 off)
*/
/* 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
diff --git a/stand/common/module.c b/stand/common/module.c
index 401bb8843874..bd8d091d91c9 100644
--- a/stand/common/module.c
+++ b/stand/common/module.c
@@ -616,6 +616,14 @@ file_load_dependencies(struct preloaded_file *base_file)
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);
+ return(NULL);
+ }
+#else
#ifdef LOADER_VERIEXEC
- if (verify_file(fd, name, 0, VE_MUST) < 0) {
- sprintf(command_errbuf, "can't verify '%s'", name);
+ if (verify_file(fd, name, 0, VE_MUST, __func__) < 0) {
+ sprintf(command_errbuf, "can't verify '%s': %s",
+ name, ve_error_get());
free(name);
close(fd);
return(NULL);
}
#endif
+#endif
if (archsw.arch_loadaddr != NULL)
loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
@@ -666,7 +691,7 @@ file_loadraw(const char *fname, char *type, int insert)
laddr = loadaddr;
for (;;) {
/* read in 4k chunks; size is not really important */
- got = archsw.arch_readin(fd, laddr, 4096);
+ got = archsw.arch_readin(VECTX_HANDLE(fd), laddr, 4096);
if (got == 0) /* end of file */
break;
if (got < 0) { /* error */
@@ -674,12 +699,24 @@ file_loadraw(const char *fname, char *type, int insert)
"error reading '%s': %s", name, strerror(errno));
free(name);
close(fd);
+#ifdef LOADER_VERIEXEC_VECTX
+ free(vctx);
+#endif
return(NULL);
}
laddr += got;
}
printf("size=%#jx\n", (uintmax_t)(laddr - loadaddr));
+#ifdef LOADER_VERIEXEC_VECTX
+ verror = vectx_close(vctx, VE_MUST, __func__);
+ if (verror) {
+ free(name);
+ close(fd);
+ free(vctx);
+ return(NULL);
+ }
+#endif
/* Looks OK so far; create & populate control structure */
fp = file_alloc();
diff --git a/stand/efi/loader/arch/i386/i386_copy.c b/stand/efi/loader/arch/i386/i386_copy.c
index 522913f5da43..2c4b0deb49cf 100644
--- a/stand/efi/loader/arch/i386/i386_copy.c
+++ b/stand/efi/loader/arch/i386/i386_copy.c
@@ -51,9 +51,8 @@ i386_copyout(const vm_offset_t src, void *dest, const size_t len)
return(len);
}
-
ssize_t
-i386_readin(const int fd, vm_offset_t dest, const size_t len)
+i386_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
{
- return (read(fd, PTOV(dest), len));
+ return (VECTX_READ(fd, PTOV(dest), len));
}
diff --git a/stand/efi/loader/copy.c b/stand/efi/loader/copy.c
index 6e6e368e0b24..6499a44b9bbe 100644
--- a/stand/efi/loader/copy.c
+++ b/stand/efi/loader/copy.c
@@ -341,14 +341,14 @@ efi_copyout(const vm_offset_t src, void *dest, const size_t len)
ssize_t
-efi_readin(const int fd, vm_offset_t dest, const size_t len)
+efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
{
if (!efi_check_space(dest + stage_offset + len)) {
errno = ENOMEM;
return (-1);
}
- return (read(fd, (void *)(dest + stage_offset), len));
+ return (VECTX_READ(fd, (void *)(dest + stage_offset), len));
}
void
diff --git a/stand/efi/loader/loader_efi.h b/stand/efi/loader/loader_efi.h
index 780fbfe4c6aa..4d077514e423 100644
--- a/stand/efi/loader/loader_efi.h
+++ b/stand/efi/loader/loader_efi.h
@@ -32,6 +32,7 @@
#define _LOADER_EFI_COPY_H_
#include <stand.h>
+#include <readin.h>
int efi_autoload(void);
@@ -39,7 +40,7 @@ int efi_copy_init(void);
ssize_t efi_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t efi_copyout(const vm_offset_t src, void *dest, const size_t len);
-ssize_t efi_readin(const int fd, vm_offset_t dest, const size_t len);
+ssize_t efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
void * efi_translate(vm_offset_t ptr);
void efi_copy_finish(void);
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index 143c003adbb1..214b4bb7e5f2 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -1460,7 +1460,7 @@ command_chain(int argc, char *argv[])
}
#ifdef LOADER_VERIEXEC
- if (verify_file(fd, name, 0, VE_MUST) < 0) {
+ if (verify_file(fd, name, 0, VE_MUST, __func__) < 0) {
sprintf(command_errbuf, "can't verify: %s", name);
close(fd);
return (CMD_ERROR);
diff --git a/stand/ficl/loader.c b/stand/ficl/loader.c
index 6d25f5502d49..2d1e1b908e9d 100644
--- a/stand/ficl/loader.c
+++ b/stand/ficl/loader.c
@@ -530,7 +530,7 @@ static void pfopen(FICL_VM *pVM)
fd = open(name, mode);
#ifdef LOADER_VERIEXEC
if (fd >= 0) {
- if (verify_file(fd, name, 0, VE_GUESS) < 0) {
+ if (verify_file(fd, name, 0, VE_GUESS, __func__) < 0) {
/* not verified writing ok but reading is not */
if ((mode & O_ACCMODE) != O_WRONLY) {
close(fd);
diff --git a/stand/i386/libi386/i386_copy.c b/stand/i386/libi386/i386_copy.c
index c73077dce468..a1e7c734ebf3 100644
--- a/stand/i386/libi386/i386_copy.c
+++ b/stand/i386/libi386/i386_copy.c
@@ -63,7 +63,7 @@ i386_copyout(const vm_offset_t src, void *dest, const size_t len)
ssize_t
-i386_readin(const int fd, vm_offset_t dest, const size_t len)
+i386_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
{
if (dest + len >= memtop_copyin) {
@@ -71,5 +71,5 @@ i386_readin(const int fd, vm_offset_t dest, const size_t len)
return (-1);
}
- return (read(fd, PTOV(dest), len));
+ return (VECTX_READ(fd, PTOV(dest), len));
}
diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h
index 2f254b918f5c..d25df8fc44a5 100644
--- a/stand/i386/libi386/libi386.h
+++ b/stand/i386/libi386/libi386.h
@@ -89,6 +89,8 @@ extern struct devdesc currdev; /* our current device */
#define MAXDEV 31 /* maximum number of distinct devices */
#define MAXBDDEV MAXDEV
+#include <readin.h>
+
/* exported devices XXX rename? */
extern struct devsw bioscd;
extern struct devsw biosfd;
@@ -104,7 +106,7 @@ int bd_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
ssize_t i386_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t i386_copyout(const vm_offset_t src, void *dest, const size_t len);
-ssize_t i386_readin(const int fd, vm_offset_t dest, const size_t len);
+ssize_t i386_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
struct preloaded_file;
void bios_addsmapdata(struct preloaded_file *);
diff --git a/stand/i386/loader/chain.c b/stand/i386/loader/chain.c
index 2a4816773882..96d029f4818b 100644
--- a/stand/i386/loader/chain.c
+++ b/stand/i386/loader/chain.c
@@ -43,6 +43,12 @@ __FBSDID("$FreeBSD$");
#include "libi386/libi386.h"
#include "btxv86.h"
+#ifdef LOADER_VERIEXEC_VECTX
+#define VECTX_HANDLE(x) vctx
+#else
+#define VECTX_HANDLE(x) x
+#endif
+
/*
* The MBR/VBR is located in first sector of disk/partition.
* Read 512B to temporary location and set up relocation. Then
@@ -59,6 +65,10 @@ command_chain(int argc, char *argv[])
struct stat st;
vm_offset_t mem = 0x100000;
struct i386_devdesc *rootdev;
+#ifdef LOADER_VERIEXEC_VECTX
+ struct vectx *vctx;
+ int verror;
+#endif
if (argc == 1) {
command_errmsg = "no device or file name specified";
@@ -75,6 +85,15 @@ command_chain(int argc, char *argv[])
return (CMD_ERROR);
}
+#ifdef LOADER_VERIEXEC_VECTX
+ vctx = vectx_open(fd, argv[1], 0L, NULL, &verror, __func__);
+ if (verror) {
+ sprintf(command_errbuf, "can't verify: %s", argv[1]);
+ close(fd);
+ free(vctx);
+ return (CMD_ERROR);
+ }
+#else
#ifdef LOADER_VERIEXEC
if (verify_file(fd, argv[1], 0, VE_MUST) < 0) {
sprintf(command_errbuf, "can't verify: %s", argv[1]);
@@ -82,7 +101,7 @@ command_chain(int argc, char *argv[])
return (CMD_ERROR);
}
#endif
-
+#endif
len = strlen(argv[1]);
if (argv[1][len-1] != ':') {
if (fstat(fd, &st) == -1) {
@@ -104,13 +123,19 @@ command_chain(int argc, char *argv[])
return (CMD_ERROR);
}
- if (archsw.arch_readin(fd, mem, size) != size) {
+ if (archsw.arch_readin(VECTX_HANDLE(fd), mem, size) != size) {
command_errmsg = "failed to read disk";
close(fd);
return (CMD_ERROR);
}
close(fd);
-
+#ifdef LOADER_VERIEXEC_VECTX
+ verror = vectx_close(vctx, VE_MUST, __func__);
+ if (verror) {
+ free(vctx);
+ return (CMD_ERROR);
+ }
+#endif
if (argv[1][len-1] == ':' &&
*((uint16_t *)PTOV(mem + DOSMAGICOFFSET)) != DOSMAGIC) {
command_errmsg = "wrong magic";
diff --git a/stand/libofw/libofw.h b/stand/libofw/libofw.h
index a4bfc27699a4..0483c9dbf754 100644
--- a/stand/libofw/libofw.h
+++ b/stand/libofw/libofw.h
@@ -26,6 +26,7 @@
*/
#include "openfirm.h"
+#include <readin.h>
struct ofw_devdesc {
struct devdesc dd;
@@ -51,7 +52,7 @@ int ofwn_getunit(const char *);
ssize_t ofw_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t ofw_copyout(const vm_offset_t src, void *dest, const size_t len);
-ssize_t ofw_readin(const int fd, vm_offset_t dest, const size_t len);
+ssize_t ofw_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
extern int ofw_boot(void);
extern int ofw_autoload(void);
diff --git a/stand/libofw/ofw_copy.c b/stand/libofw/ofw_copy.c
index d83dbeddb577..1d46ba29d9ca 100644
--- a/stand/libofw/ofw_copy.c
+++ b/stand/libofw/ofw_copy.c
@@ -133,7 +133,7 @@ ofw_copyout(const vm_offset_t src, void *dest, const size_t len)
}
ssize_t
-ofw_readin(const int fd, vm_offset_t dest, const size_t len)
+ofw_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
{
void *buf;
size_t resid, chunk, get;
@@ -157,7 +157,7 @@ ofw_readin(const int fd, vm_offset_t dest, const size_t len)
for (resid = len; resid > 0; resid -= got, p += got) {
get = min(chunk, resid);
- got = read(fd, buf, get);
+ got = VECTX_READ(fd, buf, get);
if (got <= 0) {
if (got < 0)
diff --git a/stand/loader.mk b/stand/loader.mk
index 1cef7d2535b1..f260be7d093d 100644
--- a/stand/loader.mk
+++ b/stand/loader.mk
@@ -73,6 +73,9 @@ SRCS+= interp_simple.c
.if ${MK_LOADER_VERIEXEC} != "no"
CFLAGS+= -DLOADER_VERIEXEC -I${SRCTOP}/lib/libsecureboot/h
+.if ${MK_LOADER_VERIEXEC_VECTX} != "no"
+CFLAGS+= -DLOADER_VERIEXEC_VECTX
+.endif
.endif
.if ${MK_LOADER_VERIEXEC_PASS_MANIFEST} != "no"
diff --git a/stand/mips/beri/loader/arch.c b/stand/mips/beri/loader/arch.c
index 5ce8ede9c6a3..a30f18dfbce9 100644
--- a/stand/mips/beri/loader/arch.c
+++ b/stand/mips/beri/loader/arch.c
@@ -44,7 +44,7 @@ static int beri_arch_autoload(void);
static ssize_t beri_arch_copyin(const void *src, vm_offset_t va, size_t len);
static ssize_t beri_arch_copyout(vm_offset_t va, void *dst, size_t len);
static uint64_t beri_arch_loadaddr(u_int type, void *data, uint64_t addr);
-static ssize_t beri_arch_readin(int fd, vm_offset_t va, size_t len);
+static ssize_t beri_arch_readin(readin_handle_t fd, vm_offset_t va, size_t len);
struct arch_switch archsw = {
.arch_autoload = beri_arch_autoload,
@@ -90,8 +90,8 @@ beri_arch_loadaddr(u_int type, void *data, uint64_t addr)
}
static ssize_t
-beri_arch_readin(int fd, vm_offset_t va, size_t len)
+beri_arch_readin(readin_handle_t fd, vm_offset_t va, size_t len)
{
- return (read(fd, (void *)va, len));
+ return (VECTX_READ(fd, (void *)va, len));
}
diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c
index 21721afcfab2..10a5e89adb9b 100644
--- a/stand/powerpc/kboot/main.c
+++ b/stand/powerpc/kboot/main.c
@@ -32,7 +32,7 @@ __FBSDID("$FreeBSD$");
#include <fdt_platform.h>
#include <machine/cpufunc.h>
-#include "bootstrap.h"
+#include <bootstrap.h>
#include "host_syscall.h"
@@ -42,7 +42,7 @@ extern void *_end;
int kboot_getdev(void **vdev, const char *devspec, const char **path);
ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len);
-ssize_t kboot_readin(const int fd, vm_offset_t dest, const size_t len);
+ssize_t kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
int kboot_autoload(void);
uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr);
int kboot_setcurrdev(struct env_var *ev, int flags, const void *value);
@@ -410,7 +410,7 @@ kboot_copyout(vm_offset_t src, void *dest, const size_t len)
}
ssize_t
-kboot_readin(const int fd, vm_offset_t dest, const size_t len)
+kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
{
void *buf;
size_t resid, chunk, get;
@@ -428,7 +428,7 @@ kboot_readin(const int fd, vm_offset_t dest, const size_t len)
for (resid = len; resid > 0; resid -= got, p += got) {
get = min(chunk, resid);
- got = read(fd, buf, get);
+ got = VECTX_READ(fd, buf, get);
if (got <= 0) {
if (got < 0)
printf("kboot_readin: read failed\n");
diff --git a/stand/uboot/lib/copy.c b/stand/uboot/lib/copy.c
index 7fd5fd671c02..65451d0fbec0 100644
--- a/stand/uboot/lib/copy.c
+++ b/stand/uboot/lib/copy.c
@@ -160,7 +160,7 @@ uboot_copyout(const vm_offset_t src, void *dest, const size_t len)
}
ssize_t
-uboot_readin(const int fd, vm_offset_t dest, const size_t len)
+uboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
{
- return (read(fd, (void *)dest, len));
+ return (VECTX_READ(fd, (void *)dest, len));
}
diff --git a/stand/uboot/lib/libuboot.h b/stand/uboot/lib/libuboot.h
index 59438e711a65..18a12c216d7e 100644
--- a/stand/uboot/lib/libuboot.h
+++ b/stand/uboot/lib/libuboot.h
@@ -28,6 +28,7 @@
*/
#include <disk.h>
+#include <readin.h>
struct uboot_devdesc {
union {
@@ -62,7 +63,7 @@ extern uintptr_t uboot_heap_end;
uint64_t uboot_loadaddr(u_int type, void *data, uint64_t addr);
ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len);
-ssize_t uboot_readin(const int fd, vm_offset_t dest, const size_t len);
+ssize_t uboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
extern int uboot_autoload(void);
struct preloaded_file;
diff --git a/stand/userboot/userboot/copy.c b/stand/userboot/userboot/copy.c
index f8763e9b526a..f39c83c57d70 100644
--- a/stand/userboot/userboot/copy.c
+++ b/stand/userboot/userboot/copy.c
@@ -48,7 +48,7 @@ userboot_copyout(vm_offset_t va, void *dst, size_t len)
}
ssize_t
-userboot_readin(int fd, vm_offset_t va, size_t len)
+userboot_readin(readin_handle_t fd, vm_offset_t va, size_t len)
{
ssize_t res, s;
size_t sz;
@@ -59,7 +59,7 @@ userboot_readin(int fd, vm_offset_t va, size_t len)
sz = len;
if (sz > sizeof(buf))
sz = sizeof(buf);
- s = read(fd, buf, sz);
+ s = VECTX_READ(fd, buf, sz);
if (s == 0)
break;
if (s < 0)
diff --git a/stand/userboot/userboot/libuserboot.h b/stand/userboot/userboot/libuserboot.h
index e2048d5fef94..fa60180c6b08 100644
--- a/stand/userboot/userboot/libuserboot.h
+++ b/stand/userboot/userboot/libuserboot.h
@@ -27,6 +27,7 @@
*/
#include "userboot.h"
+#include <readin.h>
extern struct loader_callbacks *callbacks;
extern void *callbacks_arg;
@@ -54,7 +55,7 @@ extern void delay(int);
extern int userboot_autoload(void);
extern ssize_t userboot_copyin(const void *, vm_offset_t, size_t);
extern ssize_t userboot_copyout(vm_offset_t, void *, size_t);
-extern ssize_t userboot_readin(int, vm_offset_t, size_t);
+extern ssize_t userboot_readin(readin_handle_t, vm_offset_t, size_t);
extern int userboot_getdev(void **, const char *, const char **);
char *userboot_fmtdev(void *vdev);
int userboot_setcurrdev(struct env_var *ev, int flags, const void *value);