Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sys/kern Pull up revision 1.10 (requested by elad in tick...



details:   https://anonhg.NetBSD.org/src/rev/68f0322856fc
branches:  netbsd-3
changeset: 576087:68f0322856fc
user:      tron <tron%NetBSD.org@localhost>
date:      Fri Jun 10 14:47:17 2005 +0000

description:
Pull up revision 1.10 (requested by elad in ticket #389):
Rototill of the verified exec functionality.
* We now use hash tables instead of a list to store the in kernel
fingerprints.
* Fingerprint methods handling has been made more flexible, it is now
even simpler to add new methods.
* the loader no longer passes in magic numbers representing the
fingerprint method so veriexecctl is not longer kernel specific.
* fingerprint methods can be tailored out using options in the kernel
config file.
* more fingerprint methods added - rmd160, sha256/384/512
* veriexecctl can now report the fingerprint methods supported by the
running kernel.
* regularised the naming of some portions of veriexec.

diffstat:

 sys/kern/kern_verifiedexec.c |  733 +++++++++++++++++++++++++++---------------
 1 files changed, 465 insertions(+), 268 deletions(-)

diffs (truncated from 825 to 300 lines):

diff -r 0212f391b141 -r 68f0322856fc sys/kern/kern_verifiedexec.c
--- a/sys/kern/kern_verifiedexec.c      Fri Jun 10 14:47:10 2005 +0000
+++ b/sys/kern/kern_verifiedexec.c      Fri Jun 10 14:47:17 2005 +0000
@@ -1,25 +1,18 @@
-/*     $NetBSD: kern_verifiedexec.c,v 1.9 2005/02/26 21:34:55 perry Exp $      */
+/*     $NetBSD: kern_verifiedexec.c,v 1.9.2.1 2005/06/10 14:47:17 tron Exp $   */
 
 /*-
- * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
+ * Copyright 2005 Elad Efrat <elad%bsd.org.il@localhost>
+ * Copyright 2005 Brett Lymn <blymn%netbsd.org@localhost>
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Brett Lymn and Jason R Fink
+ * by Brett Lymn and Elad Efrat
  *
  * 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.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * 2. Neither the name of The NetBSD Foundation nor the names of its
  *    contributors may be used to endorse or promote products derived
  *    from this software without specific prior written permission.
  *
@@ -37,330 +30,534 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.9 2005/02/26 21:34:55 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.9.2.1 2005/06/10 14:47:17 tron Exp $");
 
 #include <sys/param.h>
 #include <sys/mount.h>
 #include <sys/malloc.h>
 #include <sys/vnode.h>
+#include <sys/namei.h>
 #include <sys/exec.h>
-#include <sys/md5.h>
-#include <sys/sha1.h>
+#include <sys/proc.h>
+#include <sys/syslog.h>
 #include <sys/verified_exec.h>
+#if defined(__FreeBSD__)
+# include <sys/systm.h>
+# include <sys/imgact.h>
+# include <crypto/sha1.h>
+#else
+# include <sys/sha1.h>
+#endif
+#include "crypto/sha2/sha2.h"
+#include "crypto/ripemd160/rmd160.h"
+#include <sys/md5.h>
 
-/* Set the buffer to a single page for md5 and sha1 */
-#define BUF_SIZE PAGE_SIZE
+/*int security_veriexec = 0;*/
+int security_veriexec_verbose = 0;
+int security_veriexec_strict = 0;
+
+char *veriexec_fp_names;
+int veriexec_name_max;
+
+/* prototypes */
+static void
+veriexec_add_fp_name(char *name);
+
+/* Veriexecs table of hash types and their associated information. */
+LIST_HEAD(veriexec_ops_head, veriexec_fp_ops) veriexec_ops_list;
+
+struct veriexec_fp_ops veriexec_default_ops[] = {
+#ifdef VERIFIED_EXEC_FP_RMD160
+       { "RMD160", RMD160_DIGEST_LENGTH, sizeof(RMD160_CTX),
+         (VERIEXEC_INIT_FN) RMD160Init,
+         (VERIEXEC_UPDATE_FN) RMD160Update,
+         (VERIEXEC_FINAL_FN) RMD160Final, {NULL, NULL}},
+#endif
 
-extern LIST_HEAD(veriexec_devhead, veriexec_dev_list) veriexec_dev_head;
+#ifdef VERIFIED_EXEC_FP_SHA256
+       { "SHA256", SHA256_DIGEST_LENGTH, sizeof(SHA256_CTX),
+         (VERIEXEC_INIT_FN) SHA256_Init,
+         (VERIEXEC_UPDATE_FN) SHA256_Update,
+         (VERIEXEC_FINAL_FN) SHA256_Final, {NULL, NULL}},
+#endif
+       
+#ifdef VERIFIED_EXEC_FP_SHA384
+       { "SHA384", SHA384_DIGEST_LENGTH, sizeof(SHA384_CTX),
+         (VERIEXEC_INIT_FN) SHA384_Init,
+         (VERIEXEC_UPDATE_FN) SHA384_Update,
+         (VERIEXEC_FINAL_FN) SHA384_Final, {NULL, NULL}},
+#endif
+       
+#ifdef VERIFIED_EXEC_FP_SHA512
+       { "SHA512", SHA512_DIGEST_LENGTH, sizeof(SHA512_CTX),
+         (VERIEXEC_INIT_FN) SHA512_Init,
+         (VERIEXEC_UPDATE_FN) SHA512_Update,
+         (VERIEXEC_FINAL_FN) SHA512_Final, {NULL, NULL}},
+#endif
+       
+#ifdef VERIFIED_EXEC_FP_SHA1
+       { "SHA1", SHA1_DIGEST_LENGTH, sizeof(SHA1_CTX),
+         (VERIEXEC_INIT_FN) SHA1Init,
+         (VERIEXEC_UPDATE_FN) SHA1Update, (VERIEXEC_FINAL_FN) SHA1Final,
+         {NULL, NULL}},
+#endif
+       
+#ifdef VERIFIED_EXEC_FP_MD5
+       { "MD5", MD5_DIGEST_LENGTH, sizeof(MD5_CTX),
+         (VERIEXEC_INIT_FN) MD5Init,
+         (VERIEXEC_UPDATE_FN) MD5Update, (VERIEXEC_FINAL_FN) MD5Final,
+         {NULL, NULL}},
+#endif
+};
 
-static int
-md5_fingerprint(struct vnode *vp, struct veriexec_inode_list *ip,
-               struct proc *p, u_quad_t file_size, char *fingerprint);
+static unsigned default_ops_count =
+        sizeof(veriexec_default_ops) / sizeof(struct veriexec_fp_ops);
 
-static int
-sha1_fingerprint(struct vnode *vp, struct veriexec_inode_list *ip,
-               struct proc *p, u_quad_t file_size, char *fingerprint);
-
+#define        VERIEXEC_BUFSIZE        PAGE_SIZE
 
 /*
- * md5_fingerprint:
- *   Evaluate the md5 fingerprint of the given file.
- *
+ * Add fingerprint names to the global list.
  */
-static int
-md5_fingerprint(struct vnode *vp, struct veriexec_inode_list *ip,
-               struct proc *p, u_quad_t file_size, char *fingerprint)
+static void
+veriexec_add_fp_name(char *name)
 {
-        u_quad_t        j;
-        MD5_CTX         md5context;
-       char            *filebuf;
-       size_t          resid;
-       int             count, error;
+       char *newp;
+       unsigned new_max;
 
-       filebuf = malloc(BUF_SIZE, M_TEMP, M_WAITOK);
-       MD5Init(&md5context);
-
-       for (j = 0; j < file_size; j+= BUF_SIZE) {
-               if ((j + BUF_SIZE) > file_size) {
-                       count = file_size - j;
-               } else
-                       count = BUF_SIZE;
-
-               error = vn_rdwr(UIO_READ, vp, filebuf, count, j,
-                                UIO_SYSSPACE, 0, p->p_ucred, &resid, NULL);
-
-               if (error) {
-                       free(filebuf, M_TEMP);
-                       return error;
+       if ((strlen(veriexec_fp_names) + VERIEXEC_TYPE_MAXLEN + 1) >=
+           veriexec_name_max) {
+               new_max = veriexec_name_max + 4 * (VERIEXEC_TYPE_MAXLEN + 1);
+               if ((newp = realloc(veriexec_fp_names, new_max,
+                                   M_TEMP, M_WAITOK)) == NULL) {
+                       printf("veriexec: cannot grow storage to add new "
+                             "fingerprint name to name list.  Not adding\n");
+                       return;
                }
 
-               MD5Update(&md5context, filebuf, (unsigned int) count);
-
+               veriexec_fp_names = newp;
+               veriexec_name_max = new_max;
        }
 
-       MD5Final(fingerprint, &md5context);
-       free(filebuf, M_TEMP);
-       return 0;
-}
-
-static int
-sha1_fingerprint(struct vnode *vp, struct veriexec_inode_list *ip,
-                struct proc *p, u_quad_t file_size, char *fingerprint)
-{
-        u_quad_t        j;
-        SHA1_CTX        sha1context;
-       char            *filebuf;
-       size_t          resid;
-       int             count, error;
-
-       filebuf = malloc(BUF_SIZE, M_TEMP, M_WAITOK);
-       SHA1Init(&sha1context);
-
-       for (j = 0; j < file_size; j+= BUF_SIZE) {
-               if ((j + BUF_SIZE) > file_size) {
-                       count = file_size - j;
-               } else
-                       count = BUF_SIZE;
-
-               error = vn_rdwr(UIO_READ, vp, filebuf, count, j,
-                               UIO_SYSSPACE, 0, p->p_ucred, &resid, NULL);
-
-               if (error) {
-                       free(filebuf, M_TEMP);
-                       return error;
-               }
-
-               SHA1Update(&sha1context, filebuf, (unsigned int) count);
-
-       }
-
-       SHA1Final(fingerprint, &sha1context);
-       free(filebuf, M_TEMP);
-       return 0;
+       strlcat(veriexec_fp_names, name, veriexec_name_max);
+       strlcat(veriexec_fp_names, " ", veriexec_name_max);
 }
 
 /*
- * evaluate_fingerprint:
- *   Check the fingerprint type for the given file and evaluate the
- * fingerprint for that file.  It is assumed that fingerprint has sufficient
- * storage to hold the resulting fingerprint string.
- *
+ * Initialise the internal "default" fingerprint ops vector list.
  */
-int
-evaluate_fingerprint(struct vnode *vp, struct veriexec_inode_list *ip,
-                    struct proc *p, u_quad_t file_size, char *fingerprint)
+void
+veriexec_init_fp_ops(void)
 {
-       int error;
+       unsigned int i;
+
+       veriexec_name_max = default_ops_count * (VERIEXEC_TYPE_MAXLEN + 1) + 1;
+       veriexec_fp_names = malloc(veriexec_name_max, M_TEMP, M_WAITOK);
+       veriexec_fp_names[0] = '\0';
+       
+       LIST_INIT(&veriexec_ops_list);
 
-       switch (ip->fp_type) {
-       case FINGERPRINT_TYPE_MD5:
-               error = md5_fingerprint(vp, ip, p, file_size, fingerprint);
-               break;
+       for (i = 0; i < default_ops_count; i++) {
+               LIST_INSERT_HEAD(&veriexec_ops_list, &veriexec_default_ops[i],
+                                entries);
+               veriexec_add_fp_name(veriexec_default_ops[i].type);
+       }
+}
 
-       case FINGERPRINT_TYPE_SHA1:
-               error = sha1_fingerprint(vp, ip, p, file_size, fingerprint);
-               break;
+struct veriexec_fp_ops *
+veriexec_find_ops(u_char *name)
+{
+       struct veriexec_fp_ops *ops;
 
-       default:
-               error = EINVAL;
-               break;
+       name[VERIEXEC_TYPE_MAXLEN] = '\0';
+       
+       LIST_FOREACH(ops, &veriexec_ops_list, entries) {
+               if ((strlen(name) == strlen(ops->type)) &&
+                   (strncasecmp(name, ops->type, sizeof(ops->type) - 1)
+                    == 0))
+                       return (ops);
        }
 
-       return error;
-}
-
-/*
- * fingerprintcmp:
- *    Compare the two given fingerprints to see if they are the same
- * Differing fingerprint methods may have differing lengths which
- * is handled by this routine.  This function follows the convention
- * of other cmp functions and returns 0 if the fingerprints match and
- * 1 if they don't.
- */
-int
-fingerprintcmp(struct veriexec_inode_list *ip, unsigned char *digest)
-{
-       switch(ip->fp_type) {
-       case FINGERPRINT_TYPE_MD5:



Home | Main Index | Thread Index | Old Index