diff --git a/sbin/veriexecctl/veriexecctl.8 b/sbin/veriexecctl/veriexecctl.8 index e173a517ed14..371edf8601ee 100644 --- a/sbin/veriexecctl/veriexecctl.8 +++ b/sbin/veriexecctl/veriexecctl.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: veriexecctl.8,v 1.19 2005/10/05 13:58:49 wiz Exp $ +.\" $NetBSD: veriexecctl.8,v 1.20 2005/12/10 02:10:00 elad Exp $ .\" .\" Copyright (c) 1999 .\" Brett Lymn - blymn@baea.com.au, brett_lymn@yahoo.com.au @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: veriexecctl.8,v 1.19 2005/10/05 13:58:49 wiz Exp $ +.\" $Id: veriexecctl.8,v 1.20 2005/12/10 02:10:00 elad Exp $ .\" -.Dd October 4, 2005 +.Dd December 10, 2005 .Dt VERIEXECCTL 8 .Os .Sh NAME @@ -40,6 +40,8 @@ .Sh SYNOPSIS .Nm .Cm load Ar signatures +.Nm +.Cm delete Op file | mount_point .Sh DESCRIPTION The .Nm @@ -56,6 +58,11 @@ This operation is only available if kern.veriexec.strict is zero. Once loaded the kernel can then validate executed programs or files against the loaded fingerprints and report when fingerprints do not match. +.It Cm delete Op file | mount_point +Delete the specified file from the Veriexec table it is stored in. +If the argument is a mount_point (or a directory), the device id for +it is fetched and the entire Veriexec table that refers to it is +removed. .El .Sh SIGNATURES The diff --git a/sbin/veriexecctl/veriexecctl.c b/sbin/veriexecctl/veriexecctl.c index 4a367c161871..ddee36428739 100644 --- a/sbin/veriexecctl/veriexecctl.c +++ b/sbin/veriexecctl/veriexecctl.c @@ -1,4 +1,4 @@ -/* $NetBSD: veriexecctl.c,v 1.17 2005/10/05 13:48:48 elad Exp $ */ +/* $NetBSD: veriexecctl.c,v 1.18 2005/12/10 02:10:00 elad Exp $ */ /*- * Copyright 2005 Elad Efrat @@ -236,6 +236,29 @@ main(int argc, char **argv) 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; + + /* Get device and inode */ + 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; + + if (ioctl(gfd, VERIEXEC_DELETE, &dp) == -1) + err(1, "Error deleting `%s'", argv[1]); } else usage(); diff --git a/share/man/man4/veriexec.4 b/share/man/man4/veriexec.4 index 746be9d1b15b..1a9911a8b267 100644 --- a/share/man/man4/veriexec.4 +++ b/share/man/man4/veriexec.4 @@ -1,4 +1,4 @@ -.\" $NetBSD: veriexec.4,v 1.8 2005/10/05 13:48:48 elad Exp $ +.\" $NetBSD: veriexec.4,v 1.9 2005/12/10 02:10:00 elad Exp $ .\" .\" Copyright 2005 Elad Efrat .\" Copyright 2005 Brett Lymn @@ -26,9 +26,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: veriexec.4,v 1.8 2005/10/05 13:48:48 elad Exp $ +.\" $Id: veriexec.4,v 1.9 2005/12/10 02:10:00 elad Exp $ .\" -.Dd October 4, 2005 +.Dd December 10, 2005 .Dt VERIEXEC 4 .Sh NAME .Nm veriexec @@ -100,12 +100,18 @@ fingerprint, this is used by the kernel to provide a simple sanity check on the fingerprint passed. Lastly, the fingerprint is a pointer to an array of characters that comprise the fingerprint for the file. +.It Dv VERIEXEC_DELETE Fa struct veriexec_delete_params +Removes either an entry or an entire table from Veriexec. +To remove a single entry, both device id and inode number must be provided. +If only a device id is provided and inode is zero, the entire table for +the specified device will be removed. .El .Pp Note that the requests -.Dv VERIEXEC_TABLESIZE +.Dv VERIEXEC_TABLESIZE , +.Dv VERIEXEC_LOAD , and -.Dv VERIEXEC_LOAD +.Dv VERIEXEC_DELETE are not permitted once the veriexec strict level has been raised past 0 by setting .Dv kern.veriexec.strict diff --git a/sys/dev/verified_exec.c b/sys/dev/verified_exec.c index bfaef37520ed..dfb7def2fb14 100644 --- a/sys/dev/verified_exec.c +++ b/sys/dev/verified_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: verified_exec.c,v 1.27 2005/12/10 01:04:17 elad Exp $ */ +/* $NetBSD: verified_exec.c,v 1.28 2005/12/10 02:10:00 elad Exp $ */ /*- * Copyright 2005 Elad Efrat @@ -31,9 +31,9 @@ #include #if defined(__NetBSD__) -__KERNEL_RCSID(0, "$NetBSD: verified_exec.c,v 1.27 2005/12/10 01:04:17 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: verified_exec.c,v 1.28 2005/12/10 02:10:00 elad Exp $"); #else -__RCSID("$Id: verified_exec.c,v 1.27 2005/12/10 01:04:17 elad Exp $\n$NetBSD: verified_exec.c,v 1.27 2005/12/10 01:04:17 elad Exp $"); +__RCSID("$Id: verified_exec.c,v 1.28 2005/12/10 02:10:00 elad Exp $\n$NetBSD: verified_exec.c,v 1.28 2005/12/10 02:10:00 elad Exp $"); #endif #include @@ -175,6 +175,10 @@ veriexecioctl(dev_t dev __unused, u_long cmd, caddr_t data, error = veriexec_load((struct veriexec_params *)data, p); break; + case VERIEXEC_DELETE: + error = veriexec_delete((struct veriexec_delete_params *)data); + break; + default: /* Invalid operation. */ error = ENODEV; @@ -338,3 +342,58 @@ veriexec_load(struct veriexec_params *params, struct proc *p) return (error); } + +int +veriexec_delete(struct veriexec_delete_params *params) +{ + struct veriexec_hashtbl *tbl; + struct veriexec_hash_entry *vhe; + + /* Delete an entire table */ + if (params->ino == 0) { + struct veriexec_hashhead *tbl_list; + u_long i; + + tbl = veriexec_tblfind(params->dev); + if (tbl == NULL) + return (ENOENT); + + /* Remove all entries from the table and lists */ + tbl_list = tbl->hash_tbl; + for (i = 0; i < tbl->hash_size; i++) { + while (LIST_FIRST(&tbl_list[i]) != NULL) { + 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); + free(vhe, M_TEMP); + } + } + + /* Remove hash table and sysctl node */ + hashdone(tbl->hash_tbl, M_TEMP); + LIST_REMOVE(tbl, hash_list); + sysctl_destroyv(__UNCONST(veriexec_count_node), params->dev, + CTL_EOL); + } else { + tbl = veriexec_tblfind(params->dev); + if (tbl == NULL) + return (ENOENT); + + vhe = veriexec_lookup(params->dev, params->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--; + } + } + + return (0); +} diff --git a/sys/sys/verified_exec.h b/sys/sys/verified_exec.h index 6a61105048f7..1d3c310c0e6b 100644 --- a/sys/sys/verified_exec.h +++ b/sys/sys/verified_exec.h @@ -1,4 +1,4 @@ -/* $NetBSD: verified_exec.h,v 1.22 2005/12/10 01:04:17 elad Exp $ */ +/* $NetBSD: verified_exec.h,v 1.23 2005/12/10 02:10:00 elad Exp $ */ /*- * Copyright 2005 Elad Efrat @@ -60,6 +60,11 @@ struct veriexec_sizing_params { 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. @@ -71,6 +76,7 @@ struct veriexec_sizing_params { #define VERIEXEC_LOAD _IOW('S', 0x1, struct veriexec_params) #define VERIEXEC_TABLESIZE _IOW('S', 0x2, struct veriexec_sizing_params) +#define VERIEXEC_DELETE _IOW('S', 0x3, struct veriexec_delete_params) /* Verified exec sysctl objects. */ #define VERIEXEC_VERBOSE 1 /* Verbosity level. */ @@ -207,6 +213,7 @@ void veriexec_report(const u_char *, const u_char *, struct vattr *, struct proc *, int, int, int); int veriexec_newtable(struct veriexec_sizing_params *); int veriexec_load(struct veriexec_params *, struct proc *); +int veriexec_delete(struct veriexec_delete_params *); #endif /* _KERNEL */