2006-11-23 16:11:29 +03:00
|
|
|
/* $NetBSD: kern_verifiedexec.c,v 1.70 2006/11/23 13:11:29 elad Exp $ */
|
2002-10-29 15:31:20 +03:00
|
|
|
|
|
|
|
/*-
|
2006-07-15 20:48:51 +04:00
|
|
|
* Copyright 2005 Elad Efrat <elad@NetBSD.org>
|
2005-04-20 17:44:45 +04:00
|
|
|
* Copyright 2005 Brett Lymn <blymn@netbsd.org>
|
2002-10-29 15:31:20 +03:00
|
|
|
*
|
|
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
2005-04-20 17:44:45 +04:00
|
|
|
* by Brett Lymn and Elad Efrat
|
2002-10-29 15:31:20 +03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
2005-04-20 17:44:45 +04:00
|
|
|
* 2. Neither the name of The NetBSD Foundation nor the names of its
|
2002-10-29 15:31:20 +03:00
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2003-07-14 18:59:01 +04:00
|
|
|
#include <sys/cdefs.h>
|
2006-11-23 16:11:29 +03:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.70 2006/11/23 13:11:29 elad Exp $");
|
2005-07-17 02:47:18 +04:00
|
|
|
|
2006-07-24 20:37:28 +04:00
|
|
|
#include "opt_veriexec.h"
|
2003-07-14 18:59:01 +04:00
|
|
|
|
2002-10-29 15:31:20 +03:00
|
|
|
#include <sys/param.h>
|
2005-02-27 00:34:55 +03:00
|
|
|
#include <sys/mount.h>
|
2002-10-29 15:31:20 +03:00
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/vnode.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
#include <sys/namei.h>
|
2002-10-29 15:31:20 +03:00
|
|
|
#include <sys/exec.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
#include <sys/proc.h>
|
|
|
|
#include <sys/syslog.h>
|
2005-05-23 02:34:01 +04:00
|
|
|
#include <sys/sysctl.h>
|
2005-10-12 03:59:40 +04:00
|
|
|
#include <sys/inttypes.h>
|
2005-05-23 02:34:01 +04:00
|
|
|
#define VERIEXEC_NEED_NODE
|
2002-10-29 15:31:20 +03:00
|
|
|
#include <sys/verified_exec.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
#if defined(__FreeBSD__)
|
|
|
|
# include <sys/systm.h>
|
|
|
|
# include <sys/imgact.h>
|
|
|
|
# include <crypto/sha1.h>
|
2006-10-28 01:20:48 +04:00
|
|
|
# include <crypto/sha2/sha2.h>
|
|
|
|
# include <crypto/ripemd160/rmd160.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
#else
|
|
|
|
# include <sys/sha1.h>
|
2006-10-28 01:20:48 +04:00
|
|
|
# include <sys/sha2.h>
|
|
|
|
# include <sys/rmd160.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
#endif
|
|
|
|
#include <sys/md5.h>
|
2005-10-05 17:48:48 +04:00
|
|
|
#include <uvm/uvm_extern.h>
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
#include <sys/fileassoc.h>
|
2006-05-25 15:23:11 +04:00
|
|
|
#include <sys/kauth.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-10-10 21:36:29 +04:00
|
|
|
int veriexec_verbose;
|
|
|
|
int veriexec_strict;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-10-10 21:36:29 +04:00
|
|
|
char *veriexec_fp_names;
|
|
|
|
size_t veriexec_name_max;
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2005-10-10 21:36:29 +04:00
|
|
|
const struct sysctlnode *veriexec_count_node;
|
2005-05-23 02:34:01 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
int veriexec_hook;
|
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
/* Veriexecs table of hash types and their associated information. */
|
|
|
|
LIST_HEAD(veriexec_ops_head, veriexec_fp_ops) veriexec_ops_list;
|
2002-10-29 15:31:20 +03:00
|
|
|
|
|
|
|
/*
|
2005-04-20 17:44:45 +04:00
|
|
|
* Add fingerprint names to the global list.
|
2002-10-29 15:31:20 +03:00
|
|
|
*/
|
2005-04-20 17:44:45 +04:00
|
|
|
static void
|
|
|
|
veriexec_add_fp_name(char *name)
|
2002-10-29 15:31:20 +03:00
|
|
|
{
|
2005-04-20 17:44:45 +04:00
|
|
|
char *newp;
|
2005-05-20 00:16:19 +04:00
|
|
|
unsigned int new_max;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-05-28 19:49:36 +04:00
|
|
|
if (name == NULL)
|
|
|
|
return;
|
|
|
|
|
2006-10-25 02:38:41 +04:00
|
|
|
/*
|
|
|
|
* If we don't have space for any names, allocate enough for six
|
|
|
|
* which should be sufficient. (it's also enough for all algorithms
|
|
|
|
* we can support at the moment)
|
|
|
|
*/
|
2005-05-28 19:49:36 +04:00
|
|
|
if (veriexec_fp_names == NULL) {
|
|
|
|
veriexec_name_max = (VERIEXEC_TYPE_MAXLEN + 1) * 6;
|
2006-10-25 02:38:41 +04:00
|
|
|
veriexec_fp_names = malloc(veriexec_name_max, M_TEMP,
|
|
|
|
M_WAITOK|M_ZERO);
|
2005-05-28 19:49:36 +04:00
|
|
|
}
|
|
|
|
|
2006-10-25 02:38:41 +04:00
|
|
|
/*
|
|
|
|
* If we're running out of space for storing supported algorithms,
|
|
|
|
* extend the buffer with space for four names.
|
|
|
|
*/
|
|
|
|
if ((veriexec_name_max - strlen(veriexec_fp_names)) <=
|
|
|
|
VERIEXEC_TYPE_MAXLEN + 1) {
|
|
|
|
/* Add space for four algorithm names. */
|
2005-04-20 17:44:45 +04:00
|
|
|
new_max = veriexec_name_max + 4 * (VERIEXEC_TYPE_MAXLEN + 1);
|
2005-05-28 19:49:36 +04:00
|
|
|
newp = realloc(veriexec_fp_names, new_max, M_TEMP, M_WAITOK);
|
2005-04-20 17:44:45 +04:00
|
|
|
veriexec_fp_names = newp;
|
|
|
|
veriexec_name_max = new_max;
|
|
|
|
}
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2006-10-25 02:38:41 +04:00
|
|
|
if (*veriexec_fp_names != '\0')
|
|
|
|
strlcat(veriexec_fp_names, " ", veriexec_name_max);
|
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
strlcat(veriexec_fp_names, name, veriexec_name_max);
|
|
|
|
}
|
2005-02-27 00:34:55 +03:00
|
|
|
|
2005-05-28 19:49:36 +04:00
|
|
|
/*
|
|
|
|
* Add ops to the fignerprint ops vector list.
|
|
|
|
*/
|
|
|
|
int veriexec_add_fp_ops(struct veriexec_fp_ops *ops)
|
|
|
|
{
|
|
|
|
if (ops == NULL)
|
|
|
|
return (EFAULT);
|
|
|
|
|
|
|
|
if ((ops->init == NULL) ||
|
|
|
|
(ops->update == NULL) ||
|
|
|
|
(ops->final == NULL))
|
|
|
|
return (EFAULT);
|
|
|
|
|
|
|
|
ops->type[sizeof(ops->type) - 1] = '\0';
|
|
|
|
|
|
|
|
if (veriexec_find_ops(ops->type) != NULL)
|
|
|
|
return (EEXIST);
|
|
|
|
|
|
|
|
LIST_INSERT_HEAD(&veriexec_ops_list, ops, entries);
|
|
|
|
veriexec_add_fp_name(ops->type);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
/*
|
|
|
|
* Initialise the internal "default" fingerprint ops vector list.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
veriexec_init_fp_ops(void)
|
|
|
|
{
|
2005-10-10 21:36:29 +04:00
|
|
|
struct veriexec_fp_ops *ops;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
/* Register a fileassoc for Veriexec. */
|
|
|
|
veriexec_hook = fileassoc_register("veriexec", veriexec_clear);
|
|
|
|
if (veriexec_hook == FILEASSOC_INVAL)
|
2006-10-25 02:38:41 +04:00
|
|
|
panic("Veriexec: Can't register fileassoc");
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
LIST_INIT(&veriexec_ops_list);
|
2005-10-10 21:36:29 +04:00
|
|
|
veriexec_fp_names = NULL;
|
|
|
|
veriexec_name_max = 0;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-05-28 19:49:36 +04:00
|
|
|
#ifdef VERIFIED_EXEC_FP_RMD160
|
|
|
|
ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
|
|
|
|
VERIEXEC_OPINIT(ops, "RMD160", RMD160_DIGEST_LENGTH,
|
|
|
|
sizeof(RMD160_CTX), RMD160Init, RMD160Update,
|
|
|
|
RMD160Final);
|
|
|
|
(void) veriexec_add_fp_ops(ops);
|
|
|
|
#endif /* VERIFIED_EXEC_FP_RMD160 */
|
|
|
|
|
|
|
|
#ifdef VERIFIED_EXEC_FP_SHA256
|
|
|
|
ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
|
|
|
|
VERIEXEC_OPINIT(ops, "SHA256", SHA256_DIGEST_LENGTH,
|
|
|
|
sizeof(SHA256_CTX), SHA256_Init, SHA256_Update,
|
|
|
|
SHA256_Final);
|
|
|
|
(void) veriexec_add_fp_ops(ops);
|
|
|
|
#endif /* VERIFIED_EXEC_FP_SHA256 */
|
|
|
|
|
|
|
|
#ifdef VERIFIED_EXEC_FP_SHA384
|
|
|
|
ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
|
|
|
|
VERIEXEC_OPINIT(ops, "SHA384", SHA384_DIGEST_LENGTH,
|
|
|
|
sizeof(SHA384_CTX), SHA384_Init, SHA384_Update,
|
|
|
|
SHA384_Final);
|
|
|
|
(void) veriexec_add_fp_ops(ops);
|
|
|
|
#endif /* VERIFIED_EXEC_FP_SHA384 */
|
|
|
|
|
|
|
|
#ifdef VERIFIED_EXEC_FP_SHA512
|
|
|
|
ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
|
|
|
|
VERIEXEC_OPINIT(ops, "SHA512", SHA512_DIGEST_LENGTH,
|
|
|
|
sizeof(SHA512_CTX), SHA512_Init, SHA512_Update,
|
|
|
|
SHA512_Final);
|
|
|
|
(void) veriexec_add_fp_ops(ops);
|
|
|
|
#endif /* VERIFIED_EXEC_FP_SHA512 */
|
|
|
|
|
|
|
|
#ifdef VERIFIED_EXEC_FP_SHA1
|
|
|
|
ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
|
|
|
|
VERIEXEC_OPINIT(ops, "SHA1", SHA1_DIGEST_LENGTH,
|
|
|
|
sizeof(SHA1_CTX), SHA1Init, SHA1Update,
|
|
|
|
SHA1Final);
|
|
|
|
(void) veriexec_add_fp_ops(ops);
|
|
|
|
#endif /* VERIFIED_EXEC_FP_SHA1 */
|
|
|
|
|
|
|
|
#ifdef VERIFIED_EXEC_FP_MD5
|
|
|
|
ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
|
|
|
|
VERIEXEC_OPINIT(ops, "MD5", MD5_DIGEST_LENGTH, sizeof(MD5_CTX),
|
|
|
|
MD5Init, MD5Update, MD5Final);
|
|
|
|
(void) veriexec_add_fp_ops(ops);
|
|
|
|
#endif /* VERIFIED_EXEC_FP_MD5 */
|
2005-04-20 17:44:45 +04:00
|
|
|
}
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
struct veriexec_fp_ops *
|
|
|
|
veriexec_find_ops(u_char *name)
|
|
|
|
{
|
|
|
|
struct veriexec_fp_ops *ops;
|
|
|
|
|
2006-10-25 02:38:41 +04:00
|
|
|
if ((name == NULL) || (strlen(name) == 0))
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
name[VERIEXEC_TYPE_MAXLEN - 1] = '\0';
|
2006-05-25 15:23:11 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
LIST_FOREACH(ops, &veriexec_ops_list, entries) {
|
2006-10-25 02:38:41 +04:00
|
|
|
if (strncasecmp(name, ops->type, sizeof(ops->type) - 1) == 0)
|
2005-04-20 17:44:45 +04:00
|
|
|
return (ops);
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
return (NULL);
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
/*
|
|
|
|
* Calculate fingerprint. Information on hash length and routines used is
|
|
|
|
* extracted from veriexec_hash_list according to the hash type.
|
|
|
|
*/
|
|
|
|
int
|
2005-12-12 19:26:33 +03:00
|
|
|
veriexec_fp_calc(struct lwp *l, struct vnode *vp,
|
2006-07-16 00:07:36 +04:00
|
|
|
struct veriexec_file_entry *vfe, u_char *fp)
|
2002-10-29 15:31:20 +03:00
|
|
|
{
|
2006-07-16 00:07:36 +04:00
|
|
|
struct vattr va;
|
2005-10-10 21:36:29 +04:00
|
|
|
void *ctx, *page_ctx;
|
|
|
|
u_char *buf, *page_fp;
|
|
|
|
off_t offset, len;
|
|
|
|
size_t resid, npages;
|
|
|
|
int error, do_perpage, pagen;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2006-07-24 02:06:03 +04:00
|
|
|
error = VOP_GETATTR(vp, &va, l->l_cred, l);
|
2006-07-16 00:07:36 +04:00
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
|
2005-10-10 21:36:29 +04:00
|
|
|
#if 0 /* XXX - for now */
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if ((vfe->type & VERIEXEC_UNTRUSTED) &&
|
|
|
|
(vfe->page_fp_status == PAGE_FP_NONE))
|
2005-10-07 22:07:46 +04:00
|
|
|
do_perpage = 1;
|
2005-10-10 21:36:29 +04:00
|
|
|
else
|
2005-10-07 22:07:46 +04:00
|
|
|
#endif
|
2005-10-10 21:36:29 +04:00
|
|
|
do_perpage = 0;
|
2002-10-29 15:31:20 +03:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
ctx = (void *) malloc(vfe->ops->context_size, M_TEMP, M_WAITOK);
|
2005-05-28 20:37:20 +04:00
|
|
|
buf = (u_char *) malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2005-10-10 21:36:29 +04:00
|
|
|
page_ctx = NULL;
|
|
|
|
page_fp = NULL;
|
|
|
|
npages = 0;
|
2005-10-07 22:07:46 +04:00
|
|
|
if (do_perpage) {
|
2006-07-16 00:07:36 +04:00
|
|
|
npages = (va.va_size >> PAGE_SHIFT) + 1;
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
page_fp = (u_char *) malloc(vfe->ops->hash_len * npages,
|
2005-10-05 17:48:48 +04:00
|
|
|
M_TEMP, M_WAITOK|M_ZERO);
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vfe->page_fp = page_fp;
|
|
|
|
page_ctx = (void *) malloc(vfe->ops->context_size, M_TEMP,
|
2005-10-05 17:48:48 +04:00
|
|
|
M_WAITOK);
|
|
|
|
}
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
(vfe->ops->init)(ctx);
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-10-10 21:36:29 +04:00
|
|
|
len = 0;
|
|
|
|
error = 0;
|
2005-10-12 18:26:47 +04:00
|
|
|
pagen = 0;
|
2006-07-16 00:07:36 +04:00
|
|
|
for (offset = 0; offset < va.va_size; offset += PAGE_SIZE) {
|
|
|
|
len = ((va.va_size - offset) < PAGE_SIZE) ?
|
|
|
|
(va.va_size - offset) : PAGE_SIZE;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2006-05-25 15:23:11 +04:00
|
|
|
error = vn_rdwr(UIO_READ, vp, buf, len, offset,
|
2005-04-20 17:44:45 +04:00
|
|
|
UIO_SYSSPACE,
|
|
|
|
#ifdef __FreeBSD__
|
|
|
|
IO_NODELOCKED,
|
|
|
|
#else
|
|
|
|
0,
|
|
|
|
#endif
|
2006-07-24 02:06:03 +04:00
|
|
|
l->l_cred, &resid, NULL);
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-10-05 17:48:48 +04:00
|
|
|
if (error) {
|
2005-10-07 22:07:46 +04:00
|
|
|
if (do_perpage) {
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
free(vfe->page_fp, M_TEMP);
|
|
|
|
vfe->page_fp = NULL;
|
2005-10-05 17:48:48 +04:00
|
|
|
}
|
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
goto bad;
|
2005-10-05 17:48:48 +04:00
|
|
|
}
|
2005-04-20 17:44:45 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
(vfe->ops->update)(ctx, buf, (unsigned int) len);
|
2005-10-05 17:48:48 +04:00
|
|
|
|
2005-10-07 22:07:46 +04:00
|
|
|
if (do_perpage) {
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
(vfe->ops->init)(page_ctx);
|
|
|
|
(vfe->ops->update)(page_ctx, buf, (unsigned int)len);
|
|
|
|
(vfe->ops->final)(page_fp, page_ctx);
|
2005-10-10 21:36:29 +04:00
|
|
|
|
|
|
|
if (veriexec_verbose >= 2) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
printf("hash for page %d: ", pagen);
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
for (i = 0; i < vfe->ops->hash_len; i++)
|
2005-10-10 21:36:29 +04:00
|
|
|
printf("%02x", page_fp[i]);
|
|
|
|
printf("\n");
|
|
|
|
}
|
2005-10-12 18:26:47 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
page_fp += vfe->ops->hash_len;
|
2005-10-12 18:26:47 +04:00
|
|
|
pagen++;
|
2005-10-05 17:48:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (len != PAGE_SIZE)
|
|
|
|
break;
|
2005-04-20 17:44:45 +04:00
|
|
|
}
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
(vfe->ops->final)(fp, ctx);
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-10-07 22:07:46 +04:00
|
|
|
if (do_perpage) {
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vfe->last_page_size = len;
|
|
|
|
vfe->page_fp_status = PAGE_FP_READY;
|
|
|
|
vfe->npages = npages;
|
2005-10-07 22:07:46 +04:00
|
|
|
}
|
2005-10-05 17:48:48 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
bad:
|
2005-10-07 22:07:46 +04:00
|
|
|
if (do_perpage)
|
2005-10-05 17:48:48 +04:00
|
|
|
free(page_ctx, M_TEMP);
|
2005-04-20 17:44:45 +04:00
|
|
|
free(ctx, M_TEMP);
|
|
|
|
free(buf, M_TEMP);
|
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
2006-05-25 15:23:11 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
/* Compare two fingerprints of the same type. */
|
|
|
|
int
|
2005-05-29 20:07:10 +04:00
|
|
|
veriexec_fp_cmp(struct veriexec_fp_ops *ops, u_char *fp1, u_char *fp2)
|
2005-04-20 17:44:45 +04:00
|
|
|
{
|
2005-06-20 19:06:18 +04:00
|
|
|
if (veriexec_verbose >= 2) {
|
|
|
|
int i;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
|
|
|
printf("comparing hashes...\n");
|
2005-05-29 20:07:10 +04:00
|
|
|
printf("fp1: ");
|
|
|
|
for (i = 0; i < ops->hash_len; i++) {
|
2005-10-10 21:36:29 +04:00
|
|
|
printf("%02x", fp1[i]);
|
2005-04-20 17:44:45 +04:00
|
|
|
}
|
2005-05-29 20:07:10 +04:00
|
|
|
printf("\nfp2: ");
|
|
|
|
for (i = 0; i < ops->hash_len; i++) {
|
2005-10-10 21:36:29 +04:00
|
|
|
printf("%02x", fp2[i]);
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
2005-04-20 17:44:45 +04:00
|
|
|
printf("\n");
|
|
|
|
}
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2005-05-29 20:07:10 +04:00
|
|
|
return (memcmp(fp1, fp2, ops->hash_len));
|
2005-04-20 17:44:45 +04:00
|
|
|
}
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
struct veriexec_table_entry *
|
|
|
|
veriexec_tblfind(struct vnode *vp)
|
|
|
|
{
|
|
|
|
return (fileassoc_tabledata_lookup(vp->v_mount, veriexec_hook));
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
struct veriexec_file_entry *
|
|
|
|
veriexec_lookup(struct vnode *vp)
|
2002-10-29 15:31:20 +03:00
|
|
|
{
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
return (fileassoc_lookup(vp, veriexec_hook));
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-04-20 17:44:45 +04:00
|
|
|
* Add an entry to a hash table. If a collision is found, handle it.
|
|
|
|
* The passed entry is allocated in kernel memory.
|
2002-10-29 15:31:20 +03:00
|
|
|
*/
|
|
|
|
int
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
veriexec_hashadd(struct vnode *vp, struct veriexec_file_entry *vfe)
|
2002-10-29 15:31:20 +03:00
|
|
|
{
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
struct veriexec_table_entry *vte;
|
|
|
|
int error;
|
2002-10-29 15:31:20 +03:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
error = fileassoc_add(vp, veriexec_hook, vfe);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
2005-04-20 17:44:45 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vte = veriexec_tblfind(vp);
|
2006-10-25 02:38:41 +04:00
|
|
|
KASSERT(vte != NULL);
|
2005-04-20 17:44:45 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vte->vte_count++;
|
2005-05-23 02:34:01 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
return (0);
|
|
|
|
}
|
2002-10-29 15:31:20 +03:00
|
|
|
|
|
|
|
/*
|
2005-04-20 17:44:45 +04:00
|
|
|
* Verify the fingerprint of the given file. If we're called directly from
|
|
|
|
* sys_execve(), 'flag' will be VERIEXEC_DIRECT. If we're called from
|
|
|
|
* exec_script(), 'flag' will be VERIEXEC_INDIRECT. If we are called from
|
|
|
|
* vn_open(), 'flag' will be VERIEXEC_FILE.
|
2002-10-29 15:31:20 +03:00
|
|
|
*/
|
2005-04-20 17:44:45 +04:00
|
|
|
int
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
veriexec_verify(struct lwp *l, struct vnode *vp, const u_char *name, int flag,
|
|
|
|
struct veriexec_file_entry **ret)
|
2002-10-29 15:31:20 +03:00
|
|
|
{
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
struct veriexec_file_entry *vfe;
|
2005-10-10 21:36:29 +04:00
|
|
|
u_char *digest;
|
|
|
|
int error;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-06-19 22:22:36 +04:00
|
|
|
if (vp->v_type != VREG)
|
|
|
|
return (0);
|
2005-06-14 00:17:54 +04:00
|
|
|
|
2005-06-19 22:22:36 +04:00
|
|
|
/* Lookup veriexec table entry, save pointer if requested. */
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vfe = veriexec_lookup(vp);
|
2005-06-19 22:22:36 +04:00
|
|
|
if (ret != NULL)
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
*ret = vfe;
|
|
|
|
if (vfe == NULL)
|
2005-06-19 22:22:36 +04:00
|
|
|
goto out;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
2005-06-19 22:22:36 +04:00
|
|
|
/* Evaluate fingerprint if needed. */
|
2005-10-10 21:36:29 +04:00
|
|
|
error = 0;
|
|
|
|
digest = NULL;
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if ((vfe->status == FINGERPRINT_NOTEVAL) ||
|
|
|
|
(vfe->type & VERIEXEC_UNTRUSTED)) {
|
2005-06-19 22:22:36 +04:00
|
|
|
/* Calculate fingerprint for on-disk file. */
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
digest = (u_char *) malloc(vfe->ops->hash_len, M_TEMP,
|
2005-04-20 17:44:45 +04:00
|
|
|
M_WAITOK);
|
2006-07-16 00:07:36 +04:00
|
|
|
error = veriexec_fp_calc(l, vp, vfe, digest);
|
2005-04-20 17:44:45 +04:00
|
|
|
if (error) {
|
2005-06-20 19:06:18 +04:00
|
|
|
veriexec_report("Fingerprint calculation error.",
|
2006-07-25 01:15:05 +04:00
|
|
|
name, NULL, REPORT_ALWAYS);
|
2005-04-20 17:44:45 +04:00
|
|
|
free(digest, M_TEMP);
|
|
|
|
return (error);
|
|
|
|
}
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2005-06-19 22:22:36 +04:00
|
|
|
/* Compare fingerprint with loaded data. */
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if (veriexec_fp_cmp(vfe->ops, vfe->fp, digest) == 0) {
|
|
|
|
vfe->status = FINGERPRINT_VALID;
|
2005-04-20 17:44:45 +04:00
|
|
|
} else {
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vfe->status = FINGERPRINT_NOMATCH;
|
2005-04-20 17:44:45 +04:00
|
|
|
}
|
2005-06-17 21:46:18 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
free(digest, M_TEMP);
|
|
|
|
}
|
2005-02-27 00:34:55 +03:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if (!(vfe->type & flag)) {
|
2006-07-15 20:33:16 +04:00
|
|
|
veriexec_report("Incorrect access type.", name, l,
|
2006-07-25 01:15:05 +04:00
|
|
|
REPORT_ALWAYS|REPORT_ALARM);
|
2005-06-14 02:46:56 +04:00
|
|
|
|
2005-06-17 21:46:18 +04:00
|
|
|
/* IPS mode: Enforce access type. */
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict >= VERIEXEC_IPS)
|
2005-06-17 21:46:18 +04:00
|
|
|
return (EPERM);
|
2005-06-14 00:17:54 +04:00
|
|
|
}
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
out:
|
2005-06-19 22:22:36 +04:00
|
|
|
/* No entry in the veriexec tables. */
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if (vfe == NULL) {
|
2006-10-30 14:29:12 +03:00
|
|
|
veriexec_report("No entry.", name,
|
2006-07-25 01:15:05 +04:00
|
|
|
l, REPORT_VERBOSE);
|
2005-06-19 22:22:36 +04:00
|
|
|
|
2006-07-25 01:32:39 +04:00
|
|
|
/*
|
|
|
|
* Lockdown mode: Deny access to non-monitored files.
|
|
|
|
* IPS mode: Deny execution of non-monitored files.
|
2006-07-09 14:13:53 +04:00
|
|
|
*/
|
2006-07-25 01:32:39 +04:00
|
|
|
if ((veriexec_strict >= VERIEXEC_LOCKDOWN) ||
|
|
|
|
((veriexec_strict >= VERIEXEC_IPS) &&
|
|
|
|
(flag != VERIEXEC_FILE)))
|
2005-06-19 22:22:36 +04:00
|
|
|
return (EPERM);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
switch (vfe->status) {
|
2005-04-20 17:44:45 +04:00
|
|
|
case FINGERPRINT_NOTEVAL:
|
|
|
|
/* Should not happen. */
|
2006-10-30 14:29:12 +03:00
|
|
|
veriexec_report("Not-evaluated status "
|
2006-07-15 20:33:16 +04:00
|
|
|
"post evaluation; inconsistency detected.", name,
|
2006-07-25 01:15:05 +04:00
|
|
|
NULL, REPORT_ALWAYS|REPORT_PANIC);
|
2005-04-20 17:44:45 +04:00
|
|
|
|
|
|
|
case FINGERPRINT_VALID:
|
|
|
|
/* Valid fingerprint. */
|
2006-10-30 14:29:12 +03:00
|
|
|
veriexec_report("Match.", name, NULL,
|
2006-07-25 01:15:05 +04:00
|
|
|
REPORT_VERBOSE);
|
2005-05-20 00:16:19 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
break;
|
2005-02-27 00:34:55 +03:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
case FINGERPRINT_NOMATCH:
|
2005-06-17 21:46:18 +04:00
|
|
|
/* Fingerprint mismatch. */
|
2006-10-30 14:29:12 +03:00
|
|
|
veriexec_report("Mismatch.", name,
|
2006-07-25 01:15:05 +04:00
|
|
|
NULL, REPORT_ALWAYS|REPORT_ALARM);
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2005-06-17 21:46:18 +04:00
|
|
|
/* IDS mode: Deny access on fingerprint mismatch. */
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict >= VERIEXEC_IDS)
|
2005-04-20 17:44:45 +04:00
|
|
|
error = EPERM;
|
2005-05-20 00:16:19 +04:00
|
|
|
|
2005-04-20 17:44:45 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
/* Should never happen. */
|
2006-10-30 14:29:12 +03:00
|
|
|
veriexec_report("Invalid status "
|
2006-07-25 01:15:05 +04:00
|
|
|
"post evaluation.", name, NULL, REPORT_ALWAYS|REPORT_PANIC);
|
2005-04-20 17:44:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return (error);
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
|
|
|
|
2005-10-05 17:48:48 +04:00
|
|
|
/*
|
|
|
|
* Evaluate per-page fingerprints.
|
|
|
|
*/
|
|
|
|
int
|
2006-07-16 00:07:36 +04:00
|
|
|
veriexec_page_verify(struct veriexec_file_entry *vfe, struct vm_page *pg,
|
|
|
|
size_t idx, struct lwp *l)
|
2005-10-05 17:48:48 +04:00
|
|
|
{
|
2005-10-05 19:59:31 +04:00
|
|
|
void *ctx;
|
|
|
|
u_char *fp;
|
2005-10-05 17:48:48 +04:00
|
|
|
u_char *page_fp;
|
|
|
|
int error;
|
2005-10-10 21:36:29 +04:00
|
|
|
vaddr_t kva;
|
2005-10-05 17:48:48 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if (vfe->page_fp_status == PAGE_FP_NONE)
|
2005-10-05 17:48:48 +04:00
|
|
|
return (0);
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if (vfe->page_fp_status == PAGE_FP_FAIL)
|
2005-10-05 17:48:48 +04:00
|
|
|
return (EPERM);
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
if (idx >= vfe->npages)
|
2005-10-10 21:36:29 +04:00
|
|
|
return (0);
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
ctx = malloc(vfe->ops->context_size, M_TEMP, M_WAITOK);
|
|
|
|
fp = malloc(vfe->ops->hash_len, M_TEMP, M_WAITOK);
|
2006-03-30 08:05:05 +04:00
|
|
|
kva = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
|
2005-12-09 01:41:44 +03:00
|
|
|
pmap_kenter_pa(kva, VM_PAGE_TO_PHYS(pg), VM_PROT_READ);
|
2005-10-05 17:48:48 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
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
|
2005-10-07 22:07:46 +04:00
|
|
|
: PAGE_SIZE);
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
(vfe->ops->final)(fp, ctx);
|
2005-10-05 17:48:48 +04:00
|
|
|
|
|
|
|
pmap_kremove(kva, PAGE_SIZE);
|
2006-03-30 08:05:05 +04:00
|
|
|
uvm_km_free(kernel_map, kva, PAGE_SIZE, UVM_KMF_VAONLY);
|
2005-10-05 17:48:48 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
error = veriexec_fp_cmp(vfe->ops, page_fp, fp);
|
2005-10-05 17:48:48 +04:00
|
|
|
if (error) {
|
2005-10-10 21:36:29 +04:00
|
|
|
const char *msg;
|
2005-10-05 17:48:48 +04:00
|
|
|
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict > VERIEXEC_LEARNING) {
|
2005-10-05 17:48:48 +04:00
|
|
|
msg = "Pages modified: Killing process.";
|
|
|
|
} else {
|
|
|
|
msg = "Pages modified.";
|
|
|
|
error = 0;
|
|
|
|
}
|
|
|
|
|
2006-07-25 01:15:05 +04:00
|
|
|
veriexec_report(msg, "[page_in]", l, REPORT_ALWAYS|REPORT_ALARM);
|
2005-10-05 17:48:48 +04:00
|
|
|
|
|
|
|
if (error) {
|
|
|
|
ksiginfo_t ksi;
|
|
|
|
|
|
|
|
KSI_INIT(&ksi);
|
|
|
|
ksi.ksi_signo = SIGKILL;
|
2005-10-07 22:07:46 +04:00
|
|
|
ksi.ksi_code = SI_NOINFO;
|
2005-12-12 19:26:33 +03:00
|
|
|
ksi.ksi_pid = l->l_proc->p_pid;
|
2005-10-05 17:48:48 +04:00
|
|
|
ksi.ksi_uid = 0;
|
|
|
|
|
2005-12-12 19:26:33 +03:00
|
|
|
kpsignal(l->l_proc, &ksi, NULL);
|
2005-10-05 17:48:48 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-10-07 22:07:46 +04:00
|
|
|
free(ctx, M_TEMP);
|
|
|
|
free(fp, M_TEMP);
|
2005-10-05 17:48:48 +04:00
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2002-10-29 15:31:20 +03:00
|
|
|
/*
|
2005-06-17 21:46:18 +04:00
|
|
|
* Veriexec remove policy code.
|
2002-10-29 15:31:20 +03:00
|
|
|
*/
|
|
|
|
int
|
2006-07-26 20:34:07 +04:00
|
|
|
veriexec_removechk(struct vnode *vp, const char *pathbuf, struct lwp *l)
|
2002-10-29 15:31:20 +03:00
|
|
|
{
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
struct veriexec_file_entry *vfe;
|
|
|
|
struct veriexec_table_entry *vte;
|
2005-04-20 17:44:45 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vfe = veriexec_lookup(vp);
|
|
|
|
if (vfe == NULL) {
|
2005-06-18 02:39:08 +04:00
|
|
|
/* Lockdown mode: Deny access to non-monitored files. */
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict >= VERIEXEC_LOCKDOWN)
|
2005-06-18 02:39:08 +04:00
|
|
|
return (EPERM);
|
|
|
|
|
2005-06-17 21:46:18 +04:00
|
|
|
return (0);
|
2005-06-18 02:39:08 +04:00
|
|
|
}
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2006-07-25 01:15:05 +04:00
|
|
|
veriexec_report("Remove request.", pathbuf, l, REPORT_ALWAYS|REPORT_ALARM);
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2006-07-24 20:27:15 +04:00
|
|
|
/* IDS mode: Deny removal of monitored files. */
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict >= VERIEXEC_IDS)
|
2005-06-17 21:46:18 +04:00
|
|
|
return (EPERM);
|
2005-05-20 00:16:19 +04:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
fileassoc_clear(vp, veriexec_hook);
|
|
|
|
|
|
|
|
vte = veriexec_tblfind(vp);
|
2006-10-25 02:38:41 +04:00
|
|
|
KASSERT(vte != NULL);
|
2002-10-29 15:31:20 +03:00
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
vte->vte_count--;
|
2002-10-29 15:31:20 +03:00
|
|
|
|
2006-07-16 00:07:36 +04:00
|
|
|
return (0);
|
2002-10-29 15:31:20 +03:00
|
|
|
}
|
2005-05-20 00:16:19 +04:00
|
|
|
|
2005-08-19 16:30:02 +04:00
|
|
|
/*
|
|
|
|
* Veriexe rename policy.
|
|
|
|
*/
|
|
|
|
int
|
2006-07-26 20:34:07 +04:00
|
|
|
veriexec_renamechk(struct vnode *fromvp, const char *fromname,
|
|
|
|
struct vnode *tovp, const char *toname, struct lwp *l)
|
2005-08-19 16:30:02 +04:00
|
|
|
{
|
2006-07-19 16:45:19 +04:00
|
|
|
struct veriexec_file_entry *vfe, *tvfe;
|
2005-08-19 16:30:02 +04:00
|
|
|
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict >= VERIEXEC_LOCKDOWN) {
|
2006-07-15 20:33:16 +04:00
|
|
|
log(LOG_ALERT, "Veriexec: Preventing rename of `%s' to "
|
2006-07-26 20:34:07 +04:00
|
|
|
"`%s', uid=%u, pid=%u: Lockdown mode.\n", fromname, toname,
|
2006-07-24 02:06:03 +04:00
|
|
|
kauth_cred_geteuid(l->l_cred), l->l_proc->p_pid);
|
2005-08-19 16:30:02 +04:00
|
|
|
return (EPERM);
|
|
|
|
}
|
|
|
|
|
2006-07-26 20:34:07 +04:00
|
|
|
vfe = veriexec_lookup(fromvp);
|
2006-07-19 16:45:19 +04:00
|
|
|
tvfe = NULL;
|
2006-07-26 20:34:07 +04:00
|
|
|
if (tovp != NULL)
|
|
|
|
tvfe = veriexec_lookup(tovp);
|
2006-07-19 16:45:19 +04:00
|
|
|
|
|
|
|
if ((vfe != NULL) || (tvfe != NULL)) {
|
2006-07-25 01:32:39 +04:00
|
|
|
if (veriexec_strict >= VERIEXEC_IPS) {
|
2006-07-15 20:33:16 +04:00
|
|
|
log(LOG_ALERT, "Veriexec: Preventing rename of `%s' "
|
|
|
|
"to `%s', uid=%u, pid=%u: IPS mode, file "
|
2006-07-26 20:34:07 +04:00
|
|
|
"monitored.\n", fromname, toname,
|
2006-07-24 02:06:03 +04:00
|
|
|
kauth_cred_geteuid(l->l_cred),
|
2006-07-15 20:33:16 +04:00
|
|
|
l->l_proc->p_pid);
|
2005-08-19 16:30:02 +04:00
|
|
|
return (EPERM);
|
|
|
|
}
|
|
|
|
|
2006-07-15 20:33:16 +04:00
|
|
|
log(LOG_NOTICE, "Veriexec: Monitored file `%s' renamed to "
|
2006-07-26 20:34:07 +04:00
|
|
|
"`%s', uid=%u, pid=%u.\n", fromname, toname,
|
2006-07-24 02:06:03 +04:00
|
|
|
kauth_cred_geteuid(l->l_cred), l->l_proc->p_pid);
|
2005-08-19 16:30:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2005-05-20 00:16:19 +04:00
|
|
|
/*
|
|
|
|
* Routine for maintaining mostly consistent message formats in Verified
|
|
|
|
* Exec.
|
|
|
|
*/
|
|
|
|
void
|
2006-07-25 01:15:05 +04:00
|
|
|
veriexec_report(const u_char *msg, const u_char *filename, struct lwp *l, int f)
|
2005-05-20 00:16:19 +04:00
|
|
|
{
|
2006-07-15 20:33:16 +04:00
|
|
|
if (msg == NULL || filename == NULL)
|
2005-05-20 00:16:19 +04:00
|
|
|
return;
|
|
|
|
|
2006-07-25 01:15:05 +04:00
|
|
|
if (((f & REPORT_LOGMASK) >> 1) <= veriexec_verbose) {
|
2006-07-26 19:14:24 +04:00
|
|
|
if (!(f & REPORT_ALARM) || (l == NULL))
|
2006-07-15 20:33:16 +04:00
|
|
|
log(LOG_NOTICE, "Veriexec: %s [%s]\n", msg,
|
|
|
|
filename);
|
2005-05-20 00:16:19 +04:00
|
|
|
else
|
2006-07-26 19:14:24 +04:00
|
|
|
log(LOG_ALERT, "Veriexec: %s [%s, pid=%u, uid=%u, "
|
2006-07-15 20:33:16 +04:00
|
|
|
"gid=%u]\n", msg, filename, l->l_proc->p_pid,
|
2006-07-24 02:06:03 +04:00
|
|
|
kauth_cred_getuid(l->l_cred),
|
|
|
|
kauth_cred_getgid(l->l_cred));
|
2005-05-20 00:16:19 +04:00
|
|
|
}
|
2006-07-15 20:33:16 +04:00
|
|
|
|
2006-07-25 01:15:05 +04:00
|
|
|
if (f & REPORT_PANIC)
|
2006-07-15 20:33:16 +04:00
|
|
|
panic("Veriexec: Unrecoverable error.");
|
2005-05-20 00:16:19 +04:00
|
|
|
}
|
2006-07-15 20:43:35 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
veriexec_clear(void *data, int file_specific)
|
|
|
|
{
|
|
|
|
if (file_specific) {
|
|
|
|
struct veriexec_file_entry *vfe = data;
|
|
|
|
|
|
|
|
if (vfe != NULL) {
|
|
|
|
if (vfe->fp != NULL)
|
|
|
|
free(vfe->fp, M_TEMP);
|
|
|
|
if (vfe->page_fp != NULL)
|
|
|
|
free(vfe->page_fp, M_TEMP);
|
|
|
|
free(vfe, M_TEMP);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
struct veriexec_table_entry *vte = data;
|
|
|
|
|
|
|
|
if (vte != NULL)
|
|
|
|
free(vte, M_TEMP);
|
|
|
|
}
|
|
|
|
}
|
2006-08-11 23:17:47 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Invalidate a Veriexec file entry.
|
|
|
|
* XXX: This should be updated when per-page fingerprints are added.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
veriexec_purge(struct veriexec_file_entry *vfe)
|
|
|
|
{
|
|
|
|
vfe->status = FINGERPRINT_NOTEVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Enforce raw disk access policy.
|
|
|
|
*
|
|
|
|
* IDS mode: Invalidate fingerprints on a mount if it's opened for writing.
|
|
|
|
* IPS mode: Don't allow raw writing to disks we monitor.
|
|
|
|
* Lockdown mode: Don't allow raw writing to all disks.
|
2006-11-23 16:11:29 +03:00
|
|
|
*
|
|
|
|
* XXX: This is bogus. There's an obvious race condition between the time
|
|
|
|
* XXX: the disk is open for writing, in which an attacker can access a
|
|
|
|
* XXX: monitored file to get its signature cached again, and when the raw
|
|
|
|
* XXX: file is overwritten on disk.
|
|
|
|
* XXX:
|
|
|
|
* XXX: To solve this, we need something like the following:
|
|
|
|
* XXX: open raw disk:
|
|
|
|
* XXX: - raise refcount,
|
|
|
|
* XXX: - invalidate fingerprints,
|
|
|
|
* XXX: - mark all entries for that disk with "no cache" flag
|
|
|
|
* XXX:
|
|
|
|
* XXX: veriexec_verify:
|
|
|
|
* XXX: - if "no cache", don't cache evaluation result
|
|
|
|
* XXX:
|
|
|
|
* XXX: close raw disk:
|
|
|
|
* XXX: - lower refcount,
|
|
|
|
* XXX: - if refcount == 0, remove "no cache" flag from all entries
|
2006-08-11 23:17:47 +04:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
veriexec_rawchk(struct vnode *vp)
|
|
|
|
{
|
|
|
|
int monitored;
|
|
|
|
|
|
|
|
monitored = (vp && veriexec_tblfind(vp));
|
|
|
|
|
|
|
|
switch (veriexec_strict) {
|
|
|
|
case VERIEXEC_IDS:
|
|
|
|
if (monitored)
|
|
|
|
fileassoc_table_run(vp->v_mount, veriexec_hook,
|
|
|
|
(fileassoc_cb_t)veriexec_purge);
|
|
|
|
break;
|
|
|
|
case VERIEXEC_IPS:
|
|
|
|
if (monitored)
|
|
|
|
return (EPERM);
|
|
|
|
break;
|
|
|
|
case VERIEXEC_LOCKDOWN:
|
|
|
|
return (EPERM);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|