Small changes:
- remove the per-page stuff. It has been disabled for 10 years, and it is not implemented properly. - typo in comment - use KASSERT
This commit is contained in:
parent
ba69475758
commit
bc1457cb8c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_veriexec.c,v 1.9 2015/07/24 13:02:52 maxv Exp $ */
|
||||
/* $NetBSD: kern_veriexec.c,v 1.10 2015/08/04 11:42:08 maxv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
|
||||
@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_veriexec.c,v 1.9 2015/07/24 13:02:52 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_veriexec.c,v 1.10 2015/08/04 11:42:08 maxv Exp $");
|
||||
|
||||
#include "opt_veriexec.h"
|
||||
|
||||
@ -92,11 +92,7 @@ struct veriexec_file_entry {
|
||||
u_char *filename; /* File name. */
|
||||
u_char type; /* Entry type. */
|
||||
u_char status; /* Evaluation status. */
|
||||
u_char page_fp_status; /* Per-page FP status. */
|
||||
u_char *fp; /* Fingerprint. */
|
||||
void *page_fp; /* Per-page fingerprints */
|
||||
size_t npages; /* Number of pages. */
|
||||
size_t last_page_size; /* To support < PAGE_SIZE */
|
||||
struct veriexec_fpops *ops; /* Fingerprint ops vector*/
|
||||
size_t filename_len; /* Length of filename. */
|
||||
};
|
||||
@ -227,7 +223,7 @@ SYSCTL_SETUP(sysctl_kern_veriexec_setup, "sysctl kern.veriexec setup")
|
||||
}
|
||||
|
||||
/*
|
||||
* Add ops to the fignerprint ops vector list.
|
||||
* Add ops to the fingerprint ops vector list.
|
||||
*/
|
||||
int
|
||||
veriexec_fpops_add(const char *fp_type, size_t hash_len, size_t ctx_size,
|
||||
@ -236,16 +232,14 @@ veriexec_fpops_add(const char *fp_type, size_t hash_len, size_t ctx_size,
|
||||
{
|
||||
struct veriexec_fpops *ops;
|
||||
|
||||
/* Sanity check all parameters. */
|
||||
if ((fp_type == NULL) || (hash_len == 0) || (ctx_size == 0) ||
|
||||
(init == NULL) || (update == NULL) || (final == NULL))
|
||||
return (EFAULT);
|
||||
KASSERT((init != NULL) && (update != NULL) && (final != NULL));
|
||||
KASSERT((hash_len != 0) && (ctx_size != 0));
|
||||
KASSERT(fp_type != NULL);
|
||||
|
||||
if (veriexec_fpops_lookup(fp_type) != NULL)
|
||||
return (EEXIST);
|
||||
|
||||
ops = kmem_alloc(sizeof(*ops), KM_SLEEP);
|
||||
|
||||
ops->type = fp_type;
|
||||
ops->hash_len = hash_len;
|
||||
ops->context_size = ctx_size;
|
||||
@ -422,11 +416,11 @@ veriexec_fp_calc(struct lwp *l, struct vnode *vp, int file_lock_state,
|
||||
struct veriexec_file_entry *vfe, u_char *fp)
|
||||
{
|
||||
struct vattr va;
|
||||
void *ctx, *page_ctx;
|
||||
u_char *buf, *page_fp;
|
||||
void *ctx;
|
||||
u_char *buf;
|
||||
off_t offset, len;
|
||||
size_t resid, npages;
|
||||
int error, do_perpage, pagen;
|
||||
size_t resid;
|
||||
int error;
|
||||
|
||||
KASSERT(file_lock_state != VERIEXEC_LOCKED);
|
||||
KASSERT(file_lock_state != VERIEXEC_UNLOCKED);
|
||||
@ -439,32 +433,13 @@ veriexec_fp_calc(struct lwp *l, struct vnode *vp, int file_lock_state,
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
#ifdef notyet /* XXX - for now */
|
||||
if ((vfe->type & VERIEXEC_UNTRUSTED) &&
|
||||
(vfe->page_fp_status == PAGE_FP_NONE))
|
||||
do_perpage = 1;
|
||||
else
|
||||
#endif /* notyet */
|
||||
do_perpage = 0;
|
||||
|
||||
ctx = kmem_alloc(vfe->ops->context_size, KM_SLEEP);
|
||||
buf = kmem_alloc(PAGE_SIZE, KM_SLEEP);
|
||||
|
||||
page_ctx = NULL;
|
||||
page_fp = NULL;
|
||||
npages = 0;
|
||||
if (do_perpage) {
|
||||
npages = (va.va_size >> PAGE_SHIFT) + 1;
|
||||
page_fp = kmem_alloc(vfe->ops->hash_len * npages, KM_SLEEP);
|
||||
vfe->page_fp = page_fp;
|
||||
page_ctx = kmem_alloc(vfe->ops->context_size, KM_SLEEP);
|
||||
}
|
||||
|
||||
(vfe->ops->init)(ctx);
|
||||
|
||||
len = 0;
|
||||
error = 0;
|
||||
pagen = 0;
|
||||
for (offset = 0; offset < va.va_size; offset += PAGE_SIZE) {
|
||||
len = ((va.va_size - offset) < PAGE_SIZE) ?
|
||||
(va.va_size - offset) : PAGE_SIZE;
|
||||
@ -476,51 +451,18 @@ veriexec_fp_calc(struct lwp *l, struct vnode *vp, int file_lock_state,
|
||||
l->l_cred, &resid, NULL);
|
||||
|
||||
if (error) {
|
||||
if (do_perpage) {
|
||||
kmem_free(vfe->page_fp,
|
||||
vfe->ops->hash_len * npages);
|
||||
vfe->page_fp = NULL;
|
||||
}
|
||||
|
||||
goto bad;
|
||||
}
|
||||
|
||||
(vfe->ops->update)(ctx, buf, (unsigned int) len);
|
||||
|
||||
if (do_perpage) {
|
||||
(vfe->ops->init)(page_ctx);
|
||||
(vfe->ops->update)(page_ctx, buf, (unsigned int)len);
|
||||
(vfe->ops->final)(page_fp, page_ctx);
|
||||
|
||||
if (veriexec_verbose >= 2) {
|
||||
int i;
|
||||
|
||||
printf("hash for page %d: ", pagen);
|
||||
for (i = 0; i < vfe->ops->hash_len; i++)
|
||||
printf("%02x", page_fp[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
page_fp += vfe->ops->hash_len;
|
||||
pagen++;
|
||||
}
|
||||
|
||||
if (len != PAGE_SIZE)
|
||||
break;
|
||||
}
|
||||
|
||||
(vfe->ops->final)(fp, ctx);
|
||||
|
||||
if (do_perpage) {
|
||||
vfe->last_page_size = len;
|
||||
vfe->page_fp_status = PAGE_FP_READY;
|
||||
vfe->npages = npages;
|
||||
}
|
||||
|
||||
bad:
|
||||
if (do_perpage)
|
||||
kmem_free(page_ctx, vfe->ops->context_size);
|
||||
|
||||
kmem_free(ctx, vfe->ops->context_size);
|
||||
kmem_free(buf, PAGE_SIZE);
|
||||
|
||||
@ -606,7 +548,6 @@ veriexec_file_report(struct veriexec_file_entry *vfe, const u_char *msg,
|
||||
{
|
||||
if (vfe != NULL && vfe->filename != NULL)
|
||||
filename = vfe->filename;
|
||||
|
||||
if (filename == NULL)
|
||||
return;
|
||||
|
||||
@ -782,81 +723,6 @@ veriexec_verify(struct lwp *l, struct vnode *vp, const u_char *name, int flag,
|
||||
return (r);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Evaluate per-page fingerprints.
|
||||
*/
|
||||
int
|
||||
veriexec_page_verify(struct veriexec_file_entry *vfe, struct vm_page *pg,
|
||||
size_t idx, struct lwp *l)
|
||||
{
|
||||
void *ctx;
|
||||
u_char *fp;
|
||||
u_char *page_fp;
|
||||
int error;
|
||||
vaddr_t kva;
|
||||
|
||||
if (vfe->page_fp_status == PAGE_FP_NONE)
|
||||
return (0);
|
||||
|
||||
if (vfe->page_fp_status == PAGE_FP_FAIL)
|
||||
return (EPERM);
|
||||
|
||||
if (idx >= vfe->npages)
|
||||
return (0);
|
||||
|
||||
ctx = kmem_alloc(vfe->ops->context_size, KM_SLEEP);
|
||||
fp = kmem_alloc(vfe->ops->hash_len, KM_SLEEP);
|
||||
kva = uvm_km_alloc(kernel_map, PAGE_SIZE, VM_PGCOLOR_BUCKET(pg),
|
||||
UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_WAITVA);
|
||||
pmap_kenter_pa(kva, VM_PAGE_TO_PHYS(pg), VM_PROT_READ, 0);
|
||||
pmap_update(pmap_kernel());
|
||||
|
||||
page_fp = (u_char *) vfe->page_fp + (vfe->ops->hash_len * idx);
|
||||
(vfe->ops->init)(ctx);
|
||||
(vfe->ops->update)(ctx, (void *) kva,
|
||||
((vfe->npages - 1) == idx) ? vfe->last_page_size
|
||||
: PAGE_SIZE);
|
||||
(vfe->ops->final)(fp, ctx);
|
||||
|
||||
pmap_kremove(kva, PAGE_SIZE);
|
||||
pmap_update(pmap_kernel());
|
||||
uvm_km_free(kernel_map, kva, PAGE_SIZE, UVM_KMF_VAONLY);
|
||||
|
||||
error = veriexec_fp_cmp(vfe->ops, page_fp, fp);
|
||||
if (error) {
|
||||
const char *msg;
|
||||
|
||||
if (veriexec_strict > VERIEXEC_LEARNING) {
|
||||
msg = "Pages modified: Killing process.";
|
||||
} else {
|
||||
msg = "Pages modified.";
|
||||
error = 0;
|
||||
}
|
||||
|
||||
veriexec_file_report(msg, "[page_in]", l,
|
||||
REPORT_ALWAYS|REPORT_ALARM);
|
||||
|
||||
if (error) {
|
||||
ksiginfo_t ksi;
|
||||
|
||||
KSI_INIT(&ksi);
|
||||
ksi.ksi_signo = SIGKILL;
|
||||
ksi.ksi_code = SI_NOINFO;
|
||||
ksi.ksi_pid = l->l_proc->p_pid;
|
||||
ksi.ksi_uid = 0;
|
||||
|
||||
kpsignal(l->l_proc, &ksi, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
kmem_free(ctx, vfe->ops->context_size);
|
||||
kmem_free(fp, vfe->ops->hash_len);
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* notyet */
|
||||
|
||||
/*
|
||||
* Veriexec remove policy code.
|
||||
*/
|
||||
@ -992,8 +858,6 @@ veriexec_file_free(struct veriexec_file_entry *vfe)
|
||||
if (vfe != NULL) {
|
||||
if (vfe->fp != NULL)
|
||||
kmem_free(vfe->fp, vfe->ops->hash_len);
|
||||
if (vfe->page_fp != NULL)
|
||||
kmem_free(vfe->page_fp, vfe->ops->hash_len);
|
||||
if (vfe->filename != NULL)
|
||||
kmem_free(vfe->filename, vfe->filename_len);
|
||||
rw_destroy(&vfe->lock);
|
||||
@ -1267,11 +1131,6 @@ veriexec_file_add(struct lwp *l, prop_dictionary_t dict)
|
||||
} else
|
||||
vfe->filename = NULL;
|
||||
|
||||
vfe->page_fp = NULL;
|
||||
vfe->page_fp_status = PAGE_FP_NONE;
|
||||
vfe->npages = 0;
|
||||
vfe->last_page_size = 0;
|
||||
|
||||
if (prop_bool_true(prop_dictionary_get(dict, "eval-on-load")) ||
|
||||
(vfe->type & VERIEXEC_UNTRUSTED)) {
|
||||
u_char status;
|
||||
|
Loading…
Reference in New Issue
Block a user