aboutsummaryrefslogtreecommitdiff
path: root/lib/libsecureboot/vectx.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsecureboot/vectx.c')
-rw-r--r--lib/libsecureboot/vectx.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/lib/libsecureboot/vectx.c b/lib/libsecureboot/vectx.c
index 3e5277d935f0..45a15ddece4b 100644
--- a/lib/libsecureboot/vectx.c
+++ b/lib/libsecureboot/vectx.c
@@ -32,6 +32,11 @@ __FBSDID("$FreeBSD$");
#undef _KERNEL
#endif
+#ifdef VECTX_DEBUG
+static int vectx_debug = VECTX_DEBUG;
+# define DEBUG_PRINTF(n, x) if (vectx_debug >= n) printf x
+#endif
+
#include "libsecureboot-priv.h"
#include <verify_file.h>
@@ -52,10 +57,11 @@ struct vectx {
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 */
+ off_t vec_size; /* size of path */
size_t vec_hashsz; /* size of hash */
int vec_fd; /* file descriptor */
int vec_status; /* verification status */
+ int vec_closing; /* we are closing */
};
@@ -125,6 +131,7 @@ vectx_open(int fd, const char *path, off_t off, struct stat *stp,
ctx->vec_want = NULL;
ctx->vec_status = 0;
ctx->vec_hashsz = hashsz = 0;
+ ctx->vec_closing = 0;
if (rc == 0) {
/* we are not verifying this */
@@ -229,6 +236,12 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes)
x = nbytes - off;
x = MIN(PAGE_SIZE, x);
d = n = read(ctx->vec_fd, &bp[off], x);
+ if (ctx->vec_closing && n < x) {
+ DEBUG_PRINTF(3,
+ ("%s: read %d off=%ld hashed=%ld size=%ld\n",
+ __func__, n, (long)ctx->vec_off,
+ (long)ctx->vec_hashed, (long)ctx->vec_size));
+ }
if (n < 0) {
return (n);
}
@@ -242,6 +255,12 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes)
ctx->vec_off += x;
}
if (d > 0) {
+ if (ctx->vec_closing && d < PAGE_SIZE) {
+ DEBUG_PRINTF(3,
+ ("%s: update %ld + %d\n",
+ __func__,
+ (long)ctx->vec_hashed, d));
+ }
ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], d);
off += d;
ctx->vec_off += d;
@@ -286,7 +305,14 @@ vectx_lseek(struct vectx *ctx, off_t off, int whence)
/*
* Convert whence to SEEK_SET
*/
+ DEBUG_PRINTF(3,
+ ("%s(%s, %ld, %d)\n", __func__, ctx->vec_path, (long)off, whence));
if (whence == SEEK_END && off <= 0) {
+ if (ctx->vec_closing && ctx->vec_hashed < ctx->vec_size) {
+ DEBUG_PRINTF(3, ("%s: SEEK_END %ld\n",
+ __func__,
+ (long)(ctx->vec_size - ctx->vec_hashed)));
+ }
whence = SEEK_SET;
off += ctx->vec_size;
} else if (whence == SEEK_CUR) {
@@ -294,12 +320,22 @@ vectx_lseek(struct vectx *ctx, off_t off, int whence)
off += ctx->vec_off;
}
if (whence != SEEK_SET ||
- (size_t)off > ctx->vec_size) {
- printf("ERROR: %s: unsupported operation: whence=%d off=%lld -> %lld\n",
- __func__, whence, (long long)ctx->vec_off, (long long)off);
+ off > ctx->vec_size) {
+ printf("ERROR: %s: unsupported operation: whence=%d off=%ld -> %ld\n",
+ __func__, whence, (long)ctx->vec_off, (long)off);
return (-1);
}
if (off < ctx->vec_hashed) {
+#ifdef _STANDALONE
+ struct open_file *f = fd2open_file(ctx->vec_fd);
+
+ if (f != NULL &&
+ strncmp(f->f_ops->fs_name, "tftp", 4) == 0) {
+ /* we cannot rewind if we've hashed much of the file */
+ if (ctx->vec_hashed > ctx->vec_size / 5)
+ return (-1); /* refuse! */
+ }
+#endif
/* seeking backwards! just do it */
ctx->vec_off = lseek(ctx->vec_fd, off, whence);
return (ctx->vec_off);
@@ -337,6 +373,7 @@ vectx_close(struct vectx *ctx, int severity, const char *caller)
{
int rc;
+ ctx->vec_closing = 1;
if (ctx->vec_hashsz == 0) {
rc = ctx->vec_status;
} else {
@@ -356,16 +393,13 @@ vectx_close(struct vectx *ctx, int severity, const char *caller)
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);
if (rc == VE_FINGERPRINT_WRONG) {
- printf("Unverified: %s\n", ve_error_get());
#if !defined(UNIT_TEST) && !defined(DEBUG_VECTX)
/* we are generally called with VE_MUST */
if (severity > VE_WANT)
panic("cannot continue");
#endif
- } else if (severity > VE_WANT) {
- printf("%serified %s\n", (rc <= 0) ? "Unv" : "V",
- ctx->vec_path);
}
free(ctx);
return ((rc < 0) ? rc : 0);