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
This commit is contained in:
@@ -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_ */
|
||||
|
||||
@@ -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,
|
||||
|
||||
+32
-16
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest,
|
||||
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 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest)
|
||||
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);
|
||||
|
||||
@@ -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 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest,
|
||||
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);
|
||||
|
||||
+14
-2
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user