Subject: Getting rid of /dev/veriexec
To: None <tech-kern@netbsd.org>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 12/02/2005 14:24:37
This is a multi-part message in MIME format.
--------------080801030804080008050308
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Hi,
The attached patch does the following:
- Veriexec loading is done via sysctl() and not ioctl().
- Adds ability to delete entries from a Veriexec table.
This will allow us to remove /dev/veriexec.
Please have a look; if no one object I'll commit this next
week.
-e.
--
Elad Efrat
--------------080801030804080008050308
Content-Type: text/plain;
name="veriexec_sysctl.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="veriexec_sysctl.diff"
Index: sbin/veriexecctl/veriexecctl.8
===================================================================
RCS file: /cvsroot/src/sbin/veriexecctl/veriexecctl.8,v
retrieving revision 1.19
diff -u -p -r1.19 veriexecctl.8
--- sbin/veriexecctl/veriexecctl.8 5 Oct 2005 13:58:49 -0000 1.19
+++ sbin/veriexecctl/veriexecctl.8 2 Dec 2005 11:27:53 -0000
@@ -31,7 +31,7 @@
.\"
.\" $Id: veriexecctl.8,v 1.19 2005/10/05 13:58:49 wiz Exp $
.\"
-.Dd October 4, 2005
+.Dd December 1, 2005
.Dt VERIEXECCTL 8
.Os
.Sh NAME
@@ -134,13 +134,10 @@ If no options are specified, both direct
are implied.
.Sh FILES
.Bl -tag -width /etc/signatures -compact
-.It Pa /dev/veriexec
-veriexec device node
.It Pa /etc/signatures
default signatures file
.El
.Sh SEE ALSO
-.Xr veriexec 4 ,
.Pa /usr/share/examples/veriexecctl/fpgen.sh ,
.Pa /usr/share/examples/veriexecctl/gen_md5 ,
.Pa /usr/share/examples/veriexecctl/gen_rmd160 ,
@@ -153,6 +150,6 @@ first appeared in
.Nm
requires the kernel to have been configured with the
.Dv VERIFIED_EXEC
-option and the veriexec pseudo-device.
+option.
.Sh BUGS
There must be no whitespace in the path field of a fingerprint entry.
Index: sbin/veriexecctl/veriexecctl.c
===================================================================
RCS file: /cvsroot/src/sbin/veriexecctl/veriexecctl.c,v
retrieving revision 1.17
diff -u -p -r1.17 veriexecctl.c
--- sbin/veriexecctl/veriexecctl.c 5 Oct 2005 13:48:48 -0000 1.17
+++ sbin/veriexecctl/veriexecctl.c 2 Dec 2005 11:27:53 -0000
@@ -30,9 +30,9 @@
*
*/
-#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/queue.h>
+#include <sys/sysctl.h>
#include <sys/verified_exec.h>
#include <stdio.h>
@@ -45,12 +45,10 @@
#include "veriexecctl.h"
-#define VERIEXEC_DEVICE "/dev/veriexec"
-
-extern struct veriexec_params params; /* in veriexecctl_parse.y */
+extern struct veriexec_load_params params; /* in veriexecctl_parse.y */
extern char *filename; /* in veriexecctl_conf.l */
extern int yynerrs;
-int gfd, verbose = 0, phase;
+int verbose = 0, phase;
size_t line;
/*
@@ -104,19 +102,25 @@ dev_add(dev_t d)
static void
phase1_preload(void)
{
+ int mib[3];
+ size_t len;
+
if (verbose)
printf("Phase 1: Calculating hash table sizes:\n");
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_VERIEXEC;
+ mib[2] = VERIEXEC_TABLESIZE;
+ len = sizeof(struct veriexec_tablesize_params);
+
while (!CIRCLEQ_EMPTY(¶ms_list)) {
struct veriexec_up *vup;
vup = CIRCLEQ_FIRST(¶ms_list);
- if (ioctl(gfd, VERIEXEC_TABLESIZE, &(vup->vu_param)) == -1) {
- if (errno != EEXIST)
- err(1, "Error in phase 1: Can't "
- "set hash table size for device %d",
- vup->vu_param.dev);
+ if (sysctl(mib, 3, NULL, NULL, &vup->vu_param, len) == -1) {
+ err(1, "Error in phase 1: Can't set hash table size "
+ "for device %d", vup->vu_param.dev);
}
if (verbose) {
@@ -131,19 +135,28 @@ phase1_preload(void)
}
/*
- * Load the fingerprint. Assumes that the fingerprint pseudo-device is
- * opened and the file handle is in gfd.
+ * Load the fingerprint.
*/
void
phase2_load(void)
{
+ int mib[3];
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_VERIEXEC;
+ mib[2] = VERIEXEC_LOAD;
+ len = sizeof(struct veriexec_load_params);
+
/*
* If there's no access type specified, use the default.
*/
if (!(params.type & (VERIEXEC_DIRECT|VERIEXEC_INDIRECT|VERIEXEC_FILE)))
params.type |= VERIEXEC_DIRECT;
- if (ioctl(gfd, VERIEXEC_LOAD, ¶ms) == -1)
+
+ if (sysctl(mib, 3, NULL, NULL, ¶ms, len) == -1)
warn("Cannot load params from `%s'", params.file);
+
free(params.fingerprint);
}
@@ -227,18 +240,44 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
- if ((gfd = open(VERIEXEC_DEVICE, O_RDWR, 0)) == -1)
- err(1, "Cannot open `%s'", VERIEXEC_DEVICE);
-
/*
* Handle the different commands we can do.
*/
if (argc == 2 && strcasecmp(argv[0], "load") == 0) {
filename = argv[1];
fingerprint_load(argv[1]);
+ } else if (argc == 2 && strcasecmp(argv[0], "delete") == 0) {
+ struct veriexec_delete_params dp;
+ struct stat sb;
+ size_t len;
+ int mib[3];
+
+ /* Stat the file to get its inode, device. */
+ if (stat(argv[1], &sb) == -1)
+ err(1, "Can't stat `%s'", argv[1]);
+
+ /*
+ * If it's a regular file, remove it. If it's a directory,
+ * remove the entire table. If it's neither, abort.
+ */
+ if (S_ISDIR(sb.st_mode))
+ dp.ino = 0;
+ else if (S_ISREG(sb.st_mode))
+ dp.ino = sb.st_ino;
+ else
+ errx(1, "`%s' is not a regular file or directory.", argv[1]);
+
+ dp.dev = sb.st_dev;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_VERIEXEC;
+ mib[2] = VERIEXEC_DELETE;
+ len = sizeof(struct veriexec_delete_params);
+
+ if (sysctl(mib, 3, NULL, NULL, &dp, len) == -1)
+ err(1, "Can't delete for `%s'", argv[1]);
} else
usage();
- (void)close(gfd);
return 0;
}
Index: sbin/veriexecctl/veriexecctl.h
===================================================================
RCS file: /cvsroot/src/sbin/veriexecctl/veriexecctl.h,v
retrieving revision 1.4
diff -u -p -r1.4 veriexecctl.h
--- sbin/veriexecctl/veriexecctl.h 20 May 2005 20:06:34 -0000 1.4
+++ sbin/veriexecctl/veriexecctl.h 2 Dec 2005 11:27:53 -0000
@@ -35,11 +35,11 @@
CIRCLEQ_HEAD(veriexec_ups, veriexec_up) params_list;
struct veriexec_up {
- struct veriexec_sizing_params vu_param;
+ struct veriexec_tablesize_params vu_param;
CIRCLEQ_ENTRY(veriexec_up) vu_list;
};
-extern int gfd, verbose, phase;
+extern int verbose, phase;
extern size_t line;
extern char *infile;
extern FILE *yyin;
Index: sbin/veriexecctl/veriexecctl_conf.l
===================================================================
RCS file: /cvsroot/src/sbin/veriexecctl/veriexecctl_conf.l,v
retrieving revision 1.6
diff -u -p -r1.6 veriexecctl_conf.l
--- sbin/veriexecctl/veriexecctl_conf.l 13 Jun 2005 15:18:44 -0000 1.6
+++ sbin/veriexecctl/veriexecctl_conf.l 2 Dec 2005 11:27:53 -0000
@@ -74,7 +74,7 @@ STRING [0-9a-zA-Z]+
#.*\n |
^\n { line++; }
- /* eol on a line with data. need a call to ioctl, return eol */
+ /* eol on a line with data. need a call to sysctl, return eol */
\n {
line++;
return EOL;
Index: sbin/veriexecctl/veriexecctl_parse.y
===================================================================
RCS file: /cvsroot/src/sbin/veriexecctl/veriexecctl_parse.y,v
retrieving revision 1.13
diff -u -p -r1.13 veriexecctl_parse.y
--- sbin/veriexecctl/veriexecctl_parse.y 5 Oct 2005 13:48:48 -0000 1.13
+++ sbin/veriexecctl/veriexecctl_parse.y 2 Dec 2005 11:27:55 -0000
@@ -32,7 +32,6 @@
*/
#include <sys/param.h>
-#include <sys/ioctl.h>
#include <sys/statvfs.h>
#include <sys/mount.h>
@@ -45,7 +44,7 @@
#include "veriexecctl.h"
-struct veriexec_params params;
+struct veriexec_load_params params;
static int convert(u_char *, u_char *);
%}
Index: sys/arch/i386/conf/GENERIC_VERIEXEC
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/conf/GENERIC_VERIEXEC,v
retrieving revision 1.3
diff -u -p -r1.3 GENERIC_VERIEXEC
--- sys/arch/i386/conf/GENERIC_VERIEXEC 29 Jul 2005 14:57:30 -0000 1.3
+++ sys/arch/i386/conf/GENERIC_VERIEXEC 2 Dec 2005 11:27:55 -0000
@@ -13,5 +13,3 @@ options VERIFIED_EXEC_FP_SHA384
options VERIFIED_EXEC_FP_SHA512
options VERIFIED_EXEC_FP_SHA1
options VERIFIED_EXEC_FP_MD5
-#
-pseudo-device veriexec 1
Index: sys/conf/files
===================================================================
RCS file: /cvsroot/src/sys/conf/files,v
retrieving revision 1.745
diff -u -p -r1.745 files
--- sys/conf/files 27 Nov 2005 22:44:35 -0000 1.745
+++ sys/conf/files 2 Dec 2005 11:27:56 -0000
@@ -1113,10 +1113,8 @@ defpseudo ippp: isdndev, sppp, ifnet
defpseudo kttcp
file dev/kttcp.c kttcp needs-flag
-# Verified exec fingerprint loader pseudo-device
-defpseudo veriexec
-file kern/kern_verifiedexec.c veriexec needs-flag
-file dev/verified_exec.c veriexec needs-flag
+# Veriexec
+file kern/kern_verifiedexec.c verified_exec
# isochronous pseudo device for IEEE 1394, i.LINK or FireWire
defpseudo fwiso: ieee1394
Index: sys/conf/majors
===================================================================
RCS file: /cvsroot/src/sys/conf/majors,v
retrieving revision 1.17
diff -u -p -r1.17 majors
--- sys/conf/majors 27 Sep 2005 02:41:10 -0000 1.17
+++ sys/conf/majors 2 Dec 2005 11:27:56 -0000
@@ -19,7 +19,7 @@ device-major atabus char 166 atabus
device-major drvctl char 167 drvctl
device-major dk char 168 block 168
device-major tap char 169 tap
-device-major veriexec char 170 veriexec
+# 170 - unused (was veriexec)
device-major fw char 171 ieee1394if
device-major ucycom char 172 ucycom
device-major gpio char 173 gpio
Index: sys/kern/init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.56
diff -u -p -r1.56 init_sysctl.c
--- sys/kern/init_sysctl.c 8 Oct 2005 06:35:56 -0000 1.56
+++ sys/kern/init_sysctl.c 2 Dec 2005 11:28:00 -0000
@@ -784,6 +784,24 @@ SYSCTL_SETUP(sysctl_kern_setup, "sysctl
SYSCTL_DESCR("Number of fingerprints on device(s)"),
NULL, 0, NULL, 0,
CTL_KERN, KERN_VERIEXEC, VERIEXEC_COUNT, CTL_EOL);
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_INT, "tablesize",
+ SYSCTL_DESCR("Initialize a Veriexec hash table"),
+ sysctl_kern_veriexec, 0, NULL, 0,
+ CTL_KERN, KERN_VERIEXEC, VERIEXEC_TABLESIZE, CTL_EOL);
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_INT, "load",
+ SYSCTL_DESCR("Load an entry to the table"),
+ sysctl_kern_veriexec, 0, NULL, 0,
+ CTL_KERN, KERN_VERIEXEC, VERIEXEC_LOAD, CTL_EOL);
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_INT, "delete",
+ SYSCTL_DESCR("Delete an entry from the table"),
+ sysctl_kern_veriexec, 0, NULL, 0,
+ CTL_KERN, KERN_VERIEXEC, VERIEXEC_DELETE, CTL_EOL);
#endif /* VERIFIED_EXEC */
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
@@ -2481,36 +2499,94 @@ static int
sysctl_kern_veriexec(SYSCTLFN_ARGS)
{
int newval, error;
- int *var = NULL, raise_only = 0;
+ int *var, raise_only;
struct sysctlnode node;
+ var = NULL;
+ raise_only = 0;
node = *rnode;
+ error = 0;
+
+ switch (rnode->sysctl_num) {
+ case VERIEXEC_TABLESIZE:
+ case VERIEXEC_LOAD:
+ case VERIEXEC_DELETE:
+ if (newp == NULL || newlen == 0)
+ return (EOPNOTSUPP);
+
+ if (veriexec_strict > 0) {
+ printf("Veriexec: sysctl_kern_veriexec: Strict mode, "
+ "modifying tables is not permitted.\n");
+
+ return (EPERM);
+ }
+ }
switch (rnode->sysctl_num) {
case VERIEXEC_STRICT:
raise_only = 1;
var = &veriexec_strict;
break;
+
case VERIEXEC_ALGORITHMS:
node.sysctl_data = veriexec_fp_names;
node.sysctl_size = strlen(veriexec_fp_names) + 1;
return (sysctl_lookup(SYSCTLFN_CALL(&node)));
+
+ case VERIEXEC_TABLESIZE: {
+ struct veriexec_tablesize_params pr;
+
+ error = copyin(newp, &pr, sizeof(pr));
+ if (error)
+ return (error);
+
+ error = veriexec_newtable(&pr, 1);
+
+ break;
+ }
+
+ case VERIEXEC_LOAD: {
+ struct veriexec_load_params pr;
+
+ error = copyin(newp, &pr, sizeof(pr));
+ if (error)
+ return (error);
+
+ error = veriexec_load(&pr);
+
+ break;
+ }
+
+ case VERIEXEC_DELETE: {
+ struct veriexec_delete_params pr;
+
+ error = copyin(newp, &pr, sizeof(pr));
+ if (error)
+ return (error);
+
+ error = veriexec_delete(&pr, 1);
+
+ break;
+ }
+
default:
return (EINVAL);
}
- newval = *var;
+ if (var != NULL) {
+ newval = *var;
- node.sysctl_data = &newval;
- error = sysctl_lookup(SYSCTLFN_CALL(&node));
- if (error || newp == NULL) {
- return (error);
- }
+ node.sysctl_data = &newval;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL) {
+ return (error);
+ }
- if (raise_only && (newval < *var))
- return (EPERM);
+ if (raise_only && (newval < *var))
+ return (EPERM);
- *var = newval;
+ *var = newval;
+ }
return (error);
}
Index: sys/kern/kern_verifiedexec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_verifiedexec.c,v
retrieving revision 1.46
diff -u -p -r1.46 kern_verifiedexec.c
--- sys/kern/kern_verifiedexec.c 25 Nov 2005 12:02:09 -0000 1.46
+++ sys/kern/kern_verifiedexec.c 2 Dec 2005 11:28:02 -0000
@@ -723,3 +723,218 @@ veriexec_report(const u_char *msg, const
p->p_cred->p_rgid, die ? "]" : "]\n");
}
}
+
+int veriexec_newtable(struct veriexec_tablesize_params *pr, int sysctl_locked)
+{
+ struct lwp *l = curlwp;
+ struct veriexec_hashtbl *tbl;
+ u_char node_name[16];
+ u_long hashmask;
+
+ /* Check for existing table for device. */
+ if (veriexec_tblfind(pr->dev) != NULL)
+ return (EEXIST);
+
+ /* Allocate and initialize a Veriexec hash table. */
+ tbl = malloc(sizeof(*tbl), M_TEMP, M_WAITOK);
+ tbl->hash_size = pr->hash_size;
+ tbl->hash_dev = pr->dev;
+ tbl->hash_count = 0;
+ tbl->hash_tbl = hashinit(pr->hash_size, HASH_LIST, M_TEMP,
+ M_WAITOK, &hashmask);
+
+ LIST_INSERT_HEAD(&veriexec_tables, tbl, hash_list);
+
+ /*
+ * We're called after a sysctl_lock(), so we can't just
+ * call sysctl_createv() and have it working. We unlock
+ * and then create the node, and to satisfy our caller,
+ * we sysctl_lock() again.
+ */
+ snprintf(node_name, sizeof(node_name), "dev_%u",
+ tbl->hash_dev);
+ if (sysctl_locked)
+ sysctl_unlock(l);
+ sysctl_createv(NULL, 0, &veriexec_count_node, NULL,
+ CTLFLAG_READONLY, CTLTYPE_QUAD, node_name,
+ NULL, NULL, 0, &tbl->hash_count, 0,
+ tbl->hash_dev, CTL_EOL);
+ if (sysctl_locked)
+ sysctl_lock(l, NULL, 0);
+
+ return (0);
+}
+
+int veriexec_load(struct veriexec_load_params *pr)
+{
+ struct proc *p = curlwp->l_proc;
+ struct veriexec_hashtbl *tbl;
+ struct veriexec_hash_entry *e;
+ struct nameidata nid;
+ struct vattr va;
+ int error;
+
+ NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, pr->file, p);
+ error = namei(&nid);
+ if (error)
+ return (error);
+
+ /* Add only regular files. */
+ if (nid.ni_vp->v_type != VREG) {
+ printf("Veriexec: sysctl_kern_veriexec: Not adding \"%s\": "
+ "Not a regular file.\n", pr->file);
+ vrele(nid.ni_vp);
+ return (EINVAL);
+ }
+
+ /* Get attributes (for the device and inode). */
+ error = VOP_GETATTR(nid.ni_vp, &va, p->p_ucred, p);
+ if (error)
+ return (error);
+
+ /* Release our reference to the vnode. (namei) */
+ vrele(nid.ni_vp);
+
+ /* Get table for the device. */
+ tbl = veriexec_tblfind(va.va_fsid);
+ if (tbl == NULL)
+ return (EINVAL); /* XXX - better errno? */
+
+ e = veriexec_lookup(va.va_fsid, va.va_fileid);
+ if (e != NULL) {
+ /*
+ * Duplicate entry means something is wrong in
+ * the signature file. Just give collision info
+ * and return.
+ */
+ printf("veriexec: Duplicate entry. [%s, %ld:%llu] "
+ "old[type=0x%02x, algorithm=%s], "
+ "new[type=0x%02x, algorithm=%s] "
+ "(%s fingerprint)\n",
+ pr->file, va.va_fsid,
+ (unsigned long long)va.va_fileid,
+ e->type, e->ops->type,
+ pr->type, pr->fp_type,
+ (((e->ops->hash_len != pr->size) ||
+ (memcmp(e->fp, pr->fingerprint,
+ min(e->ops->hash_len, pr->size))
+ != 0)) ? "different" : "same"));
+
+ return (0);
+ }
+
+ e = malloc(sizeof(*e), M_TEMP, M_WAITOK);
+ e->inode = va.va_fileid;
+ e->type = pr->type;
+ e->status = FINGERPRINT_NOTEVAL;
+ e->page_fp = NULL;
+ e->page_fp_status = PAGE_FP_NONE;
+ e->npages = 0;
+ e->last_page_size = 0;
+ if ((e->ops = veriexec_find_ops(pr->fp_type)) == NULL) {
+ free(e, M_TEMP);
+ printf("Veriexec: sysctl_kern_veriexec: Invalid or "
+ "unknown fingerprint type \"%s\" for file "
+ "\"%s\" (dev=%ld, inode=%llu)\n",
+ pr->fp_type, pr->file, va.va_fsid,
+ (unsigned long long)va.va_fileid);
+ return(EINVAL);
+ }
+
+ /*
+ * Just a bit of a sanity check - require the size of
+ * the fp to be passed in, check this against the expected
+ * size. Of course userland could lie deliberately, this
+ * really only protects against the obvious fumble of
+ * changing the fp type but not updating the fingerprint
+ * string.
+ */
+ if (e->ops->hash_len != pr->size) {
+ printf("Veriexec: veriexec_load: Inconsistent "
+ "fingerprint size for type \"%s\" for file "
+ "\"%s\" (dev=%ld, inode=%llu), size was %u "
+ "was expecting %zu\n", pr->fp_type,
+ pr->file, va.va_fsid,
+ (unsigned long long)va.va_fileid,
+ pr->size, e->ops->hash_len);
+ free(e, M_TEMP);
+ return(EINVAL);
+ }
+
+ e->fp = malloc(e->ops->hash_len, M_TEMP, M_WAITOK);
+ memcpy(e->fp, pr->fingerprint, e->ops->hash_len);
+ veriexec_report("New entry.", pr->file, &va, NULL,
+ REPORT_VERBOSE_HIGH, REPORT_NOALARM,
+ REPORT_NOPANIC);
+
+ error = veriexec_hashadd(tbl, e);
+
+ return (0);
+}
+
+int veriexec_delete(struct veriexec_delete_params *pr, int sysctl_locked)
+{
+ /*
+ * If the inode is zero, we need to remove the entire table.
+ * Otherwise just remove a single entry.
+ */
+ if (pr->dev == 0) {
+ if (pr->ino != 0) {
+ struct veriexec_hashtbl *tbl;
+ struct veriexec_hash_entry *vhe;
+
+ tbl = veriexec_tblfind(pr->dev);
+ if (tbl == NULL)
+ return (0);
+
+ vhe = veriexec_lookup(pr->dev, pr->ino);
+ if (vhe != NULL) {
+ if (vhe->fp != NULL)
+ free(vhe->fp, M_TEMP);
+ if (vhe->page_fp != NULL)
+ free(vhe->page_fp, M_TEMP);
+ LIST_REMOVE(vhe, entries);
+ free(vhe, M_TEMP);
+
+ tbl->hash_count--;
+ }
+ }
+ } else {
+ struct lwp *l = curlwp;
+ struct veriexec_hashtbl *tbl;
+ struct veriexec_hashhead *tbl_list;
+ u_long i;
+
+ tbl = veriexec_tblfind(pr->dev);
+ if (tbl == NULL)
+ return (ENOENT);
+
+ tbl_list = tbl->hash_tbl;
+ for (i = 0; i < tbl->hash_size; i++) {
+ while (LIST_FIRST(&tbl_list[i]) != NULL) {
+ struct veriexec_hash_entry *vhe;
+
+ vhe = LIST_FIRST(&tbl_list[i]);
+ if (vhe->fp != NULL)
+ free(vhe->fp, M_TEMP);
+ if (vhe->page_fp != NULL)
+ free(vhe->page_fp, M_TEMP);
+ LIST_REMOVE(vhe, entries);
+ memset(vhe, 0, sizeof(*vhe));
+ free(vhe, M_TEMP);
+ }
+ }
+
+ hashdone(tbl->hash_tbl, M_TEMP);
+ LIST_REMOVE(tbl, hash_list);
+
+ if (sysctl_locked)
+ sysctl_unlock(l);
+ sysctl_destroyv(__UNCONST(veriexec_count_node),
+ pr->dev, CTL_EOL);
+ if (sysctl_locked)
+ sysctl_lock(l, NULL, 0);
+ }
+
+ return (0);
+}
Index: sys/sys/verified_exec.h
===================================================================
RCS file: /cvsroot/src/sys/sys/verified_exec.h,v
retrieving revision 1.21
diff -u -p -r1.21 verified_exec.h
--- sys/sys/verified_exec.h 7 Oct 2005 18:07:46 -0000 1.21
+++ sys/sys/verified_exec.h 2 Dec 2005 11:28:02 -0000
@@ -47,7 +47,7 @@
/* Max length of the fingerprint type string, including terminating \0 char */
#define VERIEXEC_TYPE_MAXLEN 9
-struct veriexec_params {
+struct veriexec_load_params {
unsigned char type;
unsigned char fp_type[VERIEXEC_TYPE_MAXLEN];
char file[MAXPATHLEN];
@@ -55,11 +55,16 @@ struct veriexec_params {
unsigned char *fingerprint;
};
-struct veriexec_sizing_params {
+struct veriexec_tablesize_params {
dev_t dev;
size_t hash_size;
};
+struct veriexec_delete_params {
+ dev_t dev;
+ ino_t ino;
+};
+
/*
* Types of veriexec inodes we can have. Ordered from less strict to
* most strict -- this is enforced if a duplicate entry is loaded.
@@ -69,14 +74,14 @@ struct veriexec_sizing_params {
#define VERIEXEC_FILE 0x04 /* Plain file (open) */
#define VERIEXEC_UNTRUSTED 0x10 /* Untrusted storage */
-#define VERIEXEC_LOAD _IOW('S', 0x1, struct veriexec_params)
-#define VERIEXEC_TABLESIZE _IOW('S', 0x2, struct veriexec_sizing_params)
-
/* Verified exec sysctl objects. */
#define VERIEXEC_VERBOSE 1 /* Verbosity level. */
#define VERIEXEC_STRICT 2 /* Strict mode level. */
#define VERIEXEC_ALGORITHMS 3 /* Supported hashing algorithms. */
#define VERIEXEC_COUNT 4 /* # of fingerprinted files on device. */
+#define VERIEXEC_LOAD 5 /* Load an entry. */
+#define VERIEXEC_TABLESIZE 6 /* Initialize a hash table. */
+#define VERIEXEC_DELETE 7 /* Delete an entry or a table. */
#ifdef _KERNEL
void veriexecattach(struct device *, struct device *, void *);
@@ -113,10 +118,6 @@ struct veriexec_fp_ops {
LIST_ENTRY(veriexec_fp_ops) entries;
};
-/*
- * list structure definitions - needed in kern_exec.c
- */
-
/* An entry in the per-device hash table. */
struct veriexec_hash_entry {
ino_t inode; /* Inode number. */
@@ -145,11 +146,11 @@ LIST_HEAD(veriexec_hashhead, veriexec_ha
/* Veriexec hash table information. */
struct veriexec_hashtbl {
- struct veriexec_hashhead *hash_tbl;
- size_t hash_size; /* Number of slots in the table. */
- dev_t hash_dev; /* Device ID the hash table refers to. */
+ struct veriexec_hashhead *hash_tbl;
+ size_t hash_size; /* Number of slots in the table. */
+ dev_t hash_dev; /* Device ID the hash table refers to. */
uint64_t hash_count; /* # of fingerprinted files in table. */
- LIST_ENTRY(veriexec_hashtbl) hash_list;
+ LIST_ENTRY(veriexec_hashtbl) hash_list;
};
/* Global list of hash tables. */
@@ -205,6 +206,9 @@ int veriexec_renamechk(struct vnode *, c
void veriexec_init_fp_ops(void);
void veriexec_report(const u_char *, const u_char *, struct vattr *,
struct proc *, int, int, int);
+int veriexec_newtable(struct veriexec_tablesize_params *, int);
+int veriexec_load(struct veriexec_load_params *);
+int veriexec_delete(struct veriexec_delete_params *, int);
#endif /* _KERNEL */
--------------080801030804080008050308--