--- //depot/projects/trustedbsd/base/sys/kern/kern_mac.c	2002/11/14 22:24:46
+++ //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c	2002/11/16 20:27:56
@@ -125,6 +125,11 @@
     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
 TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
 
+static int	mac_enforce_kld = 1;
+SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
+    &mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
+TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
+
 static int	mac_enforce_network = 1;
 SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
     &mac_enforce_network, 0, "Enforce MAC policy on network packets");
@@ -2293,6 +2322,47 @@
 }
 
 int
+mac_check_kld_load(struct ucred *cred, struct vnode *vp)
+{
+	int error;
+
+	ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
+
+	if (!mac_enforce_kld)
+		return (0);
+
+	MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
+
+	return (error);
+}
+
+int
+mac_check_kld_stat(struct ucred *cred)
+{
+	int error;
+
+	if (!mac_enforce_kld)
+		return (0);
+
+	MAC_CHECK(check_kld_stat, cred);
+
+	return (error);
+}
+
+int
+mac_check_kld_unload(struct ucred *cred)
+{
+	int error;
+
+	if (!mac_enforce_kld)
+		return (0);
+
+	MAC_CHECK(check_kld_unload, cred);
+
+	return (error);
+}
+
+int
 mac_check_mount_stat(struct ucred *cred, struct mount *mount)
 {
 	int error;
--- //depot/projects/trustedbsd/base/sys/sys/mac.h	2002/11/13 06:53:14
+++ //depot/projects/trustedbsd/mac/sys/sys/mac.h	2002/11/16 20:22:03
@@ -237,6 +239,9 @@
 int	mac_check_kenv_get(struct ucred *cred, char *name);
 int	mac_check_kenv_set(struct ucred *cred, char *name, char *value);
 int	mac_check_kenv_unset(struct ucred *cred, char *name);
+int	mac_check_kld_load(struct ucred *cred, struct vnode *vp);
+int	mac_check_kld_stat(struct ucred *cred);
+int	mac_check_kld_unload(struct ucred *cred);
 int	mac_check_mount_stat(struct ucred *cred, struct mount *mp);
 int	mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
 	    unsigned long cmd, void *data);
--- //depot/projects/trustedbsd/base/sys/sys/mac_policy.h	2002/11/13 06:53:14
+++ //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h	2002/11/16 20:22:03
@@ -272,6 +274,10 @@
 	int	(*mpo_check_kenv_set)(struct ucred *cred, char *name,
 		    char *value);
 	int	(*mpo_check_kenv_unset)(struct ucred *cred, char *name);
+	int	(*mpo_check_kld_load)(struct ucred *cred, struct vnode *vp,
+		    struct label *vlabel);
+	int	(*mpo_check_kld_stat)(struct ucred *cred);
+	int	(*mpo_check_kld_unload)(struct ucred *cred);
 	int	(*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp,
 		    struct label *mntlabel);
 	int	(*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipe *pipe,
--- //depot/projects/trustedbsd/base/sys/kern/kern_linker.c	2002/10/18 12:15:19
+++ //depot/projects/trustedbsd/mac/sys/kern/kern_linker.c	2002/11/16 21:48:47
@@ -27,6 +27,7 @@
  */
 
 #include "opt_ddb.h"
+#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -38,6 +39,7 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/sx.h>
+#include <sys/mac.h>
 #include <sys/module.h>
 #include <sys/linker.h>
 #include <sys/fcntl.h>
@@ -474,6 +476,11 @@
 	/* Refuse to unload modules if securelevel raised. */
 	if (securelevel > 0)
 		return (EPERM);
+#ifdef MAC
+	error = mac_check_kld_unload(curthread->td_ucred);
+	if (error)
+		return (error);
+#endif
 
 	KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
 	if (file->refs == 1) {
@@ -824,6 +831,12 @@
 	linker_file_t lf;
 	int error = 0;
 
+#ifdef MAC
+	error = mac_check_kld_stat(td->td_ucred);
+	if (error)
+		return (error);
+#endif
+
 	mtx_lock(&Giant);
 	td->td_retval[0] = -1;
 
@@ -854,6 +867,12 @@
 	linker_file_t lf;
 	int error = 0;
 
+#ifdef MAC
+	error = mac_check_kld_stat(td->td_ucred);
+	if (error)
+		return (error);
+#endif
+
 	mtx_lock(&Giant);
 
 	if (SCARG(uap, fileid) == 0) {
@@ -889,6 +908,12 @@
 	int namelen, version;
 	struct kld_file_stat *stat;
 
+#ifdef MAC
+	error = mac_check_kld_stat(td->td_ucred);
+	if (error)
+		return (error);
+#endif
+
 	mtx_lock(&Giant);
 
 	lf = linker_find_file_by_id(SCARG(uap, fileid));
@@ -938,6 +963,12 @@
 	module_t mp;
 	int error = 0;
 
+#ifdef MAC
+	error = mac_check_kld_stat(td->td_ucred);
+	if (error)
+		return (error);
+#endif
+
 	mtx_lock(&Giant);
 	lf = linker_find_file_by_id(SCARG(uap, fileid));
 	if (lf) {
@@ -967,6 +998,12 @@
 	struct kld_sym_lookup lookup;
 	int error = 0;
 
+#ifdef MAC
+	error = mac_check_kld_stat(td->td_ucred);
+	if (error)
+		return (error);
+#endif
+
 	mtx_lock(&Giant);
 
 	if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0)
@@ -1800,6 +1837,11 @@
 	linker_file_t lf;
 	int error;
 
+#ifdef MAC
+	error = mac_check_kld_stat(req->td->td_ucred);
+	if (error)
+		return (error);
+#endif
 	sysctl_wire_old_buffer(req, 0);
 	mtx_lock(&kld_mtx);
 	TAILQ_FOREACH(lf, &linker_files, link) {
--- //depot/projects/trustedbsd/base/sys/kern/link_elf.c	2002/10/19 19:36:20
+++ //depot/projects/trustedbsd/mac/sys/kern/link_elf.c	2002/11/16 20:16:05
@@ -27,11 +27,13 @@
  */
 
 #include "opt_ddb.h"
+#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
+#include <sys/mac.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
@@ -556,6 +558,13 @@
     if (error)
 	return error;
     NDFREE(&nd, NDF_ONLY_PNBUF);
+#ifdef MAC
+    error = mac_check_kld_load(curthread->td_ucred, nd.ni_vp);
+    if (error) {
+	firstpage = NULL;
+	goto out;
+    }
+#endif
 
     /*
      * Read the elf header from the file.
