Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Oct 2003 19:19:20 -0700 (PDT)
From:      Chris Vance <cvance@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 39493 for review
Message-ID:  <200310110219.h9B2JKGR050289@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39493

Change 39493 by cvance@cvance_osx_laptop on 2003/10/10 19:18:22

	Update MAC framework:
		- Add "module" registration
		- Add some additional process hooks
		- Add some vnode hooks
	This is a work in progress, so the framework is unstable (at best)
	and major pieces are ifdef'd out (including the MAC_CHECK macro)

Affected files ...

.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/bsd_init.c#4 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_exit.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_fork.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_mac.c#18 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/namei.h#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_lookup.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_subr.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_syscalls.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_vnops.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/bsd_init.c#4 (text+ko) ====

@@ -351,7 +351,7 @@
 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
 
 #ifdef MAC
-/* 	mac_create_proc0(kernproc->p_ucred); */
+	mac_create_proc0(p->p_ucred);
 #endif
 
 	/* Create the file descriptor table. */
@@ -575,6 +575,9 @@
 	init_task_failure_data[0] = 0;
 	shared_region_mapping_ref(system_shared_region);
 	vm_set_shared_region(get_threadtask(th_act), system_shared_region);
+#ifdef MAC
+	mac_create_proc1(p->p_ucred);
+#endif
 	load_init_program(p);
 	/* turn on app-profiling i.e. pre-heating */
 	app_profile = 1;

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_exit.c#3 (text+ko) ====

@@ -660,6 +660,9 @@
 			if (tvp)
 				vrele(tvp);
 
+#ifdef MAC
+			mac_destroy_proc(p);
+#endif
 			/*
 			 * Finally finished with old proc entry.
 			 * Unlink it from its process group and free it.

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_fork.c#2 (text+ko) ====

@@ -358,7 +358,6 @@
 
 	p2 = (struct proc *)forkproc(p1,lock);
 
-
 	th = procdup(p2, p1);	/* child, parent */
 
 	LIST_INSERT_AFTER(p1, p2, p_pglist);
@@ -395,6 +394,10 @@
 	MALLOC_ZONE(newproc->p_sigacts, struct sigacts *,
 			sizeof *newproc->p_sigacts, M_SUBPROC, M_WAITOK);
 
+#ifdef MAC
+	mac_init_proc(newproc);
+#endif
+
 	/*
 	 * Find an unused process ID.  We remember a range of unused IDs
 	 * ready to use (from nextpid+1 through pidchecked-1).

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_mac.c#18 (text+ko) ====

@@ -93,9 +93,12 @@
 #define	PROC_LOCK_ASSERT(x, y)
 #define M_ASSERTPKTHDR(x)
 
+#if 0
 #define ASSERT_VOP_LOCKED(vp,msg) \
 	if (vp && !VOP_ISLOCKED(vp)) \
-		Debugger("vnode lock violation.\n");
+		printf("Error: vnode lock violation.\n");
+#endif
+#define ASSERT_VOP_LOCKED(vp,msg) 
 
 #define atomic_add_int(P, V)         (*(u_int*)(P) += (V))
 #define atomic_subtract_int(P, V)    (*(u_int*)(P) -= (V))
@@ -367,7 +370,11 @@
  * request.  Note that it returns its value via 'error' in the scope
  * of the caller.
  */
-#define	MAC_CHECK(check, args...) do {					\
+#define MAC_CHECK(check, args...) do {					\
+	error = 0;							\
+} while (0)
+	
+#define	oMAC_CHECK(check, args...) do {					\
 	struct mac_policy_conf *mpc;					\
 	int entrycount;							\
 									\
@@ -506,6 +513,15 @@
 	}								\
 } while (0)
 
+
+static void
+mac_register_module(struct mac_policy_conf *mpconf)
+{
+
+	printf("MAC Framework registering policy: %s\n", mpconf->mpc_name);
+}
+	
+
 /*
  * Initialize the MAC subsystem, including appropriate SMP locks.
  */
@@ -549,6 +565,7 @@
 	sysctl_register_oid(&sysctl__security_mac_debug_counters_vnodes);
 	sysctl_register_oid(&sysctl__security_mac_debug_counters_devfsdirents);
 #endif
+	printf("MAC Framework successfully initialized\n");
 }
 
 /*
@@ -559,6 +576,13 @@
 void
 mac_late_init(void)
 {
+	extern struct mac_policy_conf test_mac_policy_conf;
+	extern struct mac_policy_conf sebsd_mac_policy_conf;
+
+	printf("MAC: init mac_test\n");
+	mac_policy_register(&test_mac_policy_conf);
+	printf("MAC: init sebsd\n");
+	mac_register_module(&sebsd_mac_policy_conf);
 
 	mac_late = 1;
 }
@@ -1384,12 +1408,17 @@
 mac_create_proc0(struct ucred *cred)
 {
 
-/*	MAC_PERFORM(create_proc0, cred); */
+	MAC_PERFORM(create_proc0, cred);
 }
 
 /*
  * Initialize MAC label for the first userland process, from which other
  * userland processes and threads are spawned.
+ * 
+ * On Darwin, proc0 forks and the child process becomes init, though
+ * indirectly.  The kernel starts /sbin/mach_init, which subsequently
+ * forks and the *parent* execs /sbin/init.  This leaves proc1 as
+ * /sbin/init and proc2 as /sbin/mach_init.
  */
 void
 mac_create_proc1(struct ucred *cred)
@@ -1772,12 +1801,17 @@
     struct componentname *cnp)
 {
 	int error;
+	static int count = 0;
 
+	if (++count < 100)
+		printf("MAC:mac_check_vnode_lookup\n");
+
 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
 
 	if (!mac_enforce_fs)
 		return (0);
 
+
 	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
 	return (error);
 }

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/namei.h#2 (text+ko) ====

@@ -166,6 +166,7 @@
 #define	ISWHITEOUT	0x020000 /* found whiteout */
 #define	DOWHITEOUT	0x040000 /* do whiteouts */
 #define	WILLBEDIR	0x080000 /* new files will be dirs; allow trailing / */
+#define NOMACCHECK	0x100000 /* do not perform MAC checks */
 #define	NODELETEBUSY	0x800000 /* donot delete busy files (Carbon semantic) */
 #define	PARAMASK	0x0fff00 /* mask of parameter descriptors */
 /*

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_lookup.c#2 (text+ko) ====

@@ -199,6 +199,18 @@
 			error = ELOOP;
 			break;
 		}
+#ifdef MAC
+		if ((cnp->cn_flags & NOMACCHECK) == 0) {
+			if (p) {
+				error = mac_check_vnode_readlink(p->p_ucred,
+				    ndp->ni_vp);
+				if (error)
+					break;
+			} else {
+				printf("mac_check_vnode_readlink: NULL process!\n");
+			}
+		}
+#endif
 		if (ndp->ni_pathlen > 1) {
 			MALLOC_ZONE(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
 		} else {
@@ -443,6 +455,19 @@
 	 * We now have a segment name to search for, and a directory to search.
 	 */
 unionlookup:
+#ifdef MAC
+	if ((cnp->cn_flags & NOMACCHECK) == 0) {
+		if (p) {
+			error = mac_check_vnode_lookup(p->p_ucred, dp, cnp);
+			if (error) {
+				printf("MAC_check_vnode_lookup: failed with error %d!\n", error);
+/* 				goto bad; */
+			}
+		} else {
+			printf("MAC_check_vnode_lookup: NULL process!\n");
+		}
+	}
+#endif
 	ndp->ni_dvp = dp;
 	ndp->ni_vp = NULL;
 	if (error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) {

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_subr.c#2 (text+ko) ====

@@ -588,6 +588,9 @@
 	else
 		vp->v_ubcinfo = 0;
 
+#ifdef MAC
+	mac_destroy_vnode(vp);
+#endif
 	vp->v_lastr = -1;
 	vp->v_ralen = 0;
 	vp->v_maxra = 0;
@@ -602,6 +605,17 @@
 	vp->v_type = VNON;
 	vp->v_tag = tag;
 	vp->v_op = vops;
+#ifdef MAC
+	mac_init_vnode(vp);
+	/*
+	 * NULL mp indicates that this vnode is being used for the
+	 * mount device for the root file system.
+	 */
+	if (mp != NULL && (mp->mnt_flag & MNT_MULTILABEL) == 0)
+		mac_associate_vnode_singlelabel(mp, vp);
+	else if (mp == NULL)
+		printf("NULL mp in getnewvnode()\n");
+#endif
 	insmntque(vp, mp);
 	*vpp = vp;
 	vp->v_usecount = 1;

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_syscalls.c#2 (text+ko) ====

@@ -867,6 +867,10 @@
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	if (vp->v_type != VDIR)
 		error = ENOTDIR;
+#ifdef MAC
+	else if ((error = mac_check_vnode_chdir(p->p_ucred, vp)) != 0) {
+        }
+#endif
 	else
 		error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
 	while (!error && (mp = vp->v_mountedhere) != NULL) {
@@ -944,7 +948,10 @@
 	    uap->path, p);
 	if (error = change_dir(&nd, p))
 		return (error);
-
+#ifdef MAC
+	if (error = mac_check_vnode_chroot(p->p_ucred, nd.ni_vp))
+		return error;
+#endif
 	if(p->p_flag & P_NOSHLIB) {
 		shared_regions_active = FALSE;
 	} else {
@@ -1248,6 +1255,11 @@
 				VOP_LEASE(nd.ni_dvp, p, p->p_ucred,
 				    LEASE_WRITE);
 				VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+#ifdef MAC
+				error = mac_check_vnode_link(p->p_ucred, 
+				    nd.ni_dvp, vp, &nd.ni_cnd);
+				if (error == 0)
+#endif
 				error = VOP_LINK(vp, nd.ni_dvp, &nd.ni_cnd);
 			} else {
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
@@ -1551,6 +1563,9 @@
 		if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
 			error = VOP_ACCESS(vp, flags, cred, p);
 	}
+#ifdef MAC
+	error = mac_check_vnode_access(cred, vp, flags);
+#endif
 	vput(vp);
 out1:
 	cred->cr_uid = t_uid;
@@ -1826,6 +1841,13 @@
 	if (error = namei(&nd))
 		return (error);
 	vp = nd.ni_vp;
+#ifdef MAC
+	error = mac_check_vnode_readlink(p->p_ucred, vp);
+	if (error) {
+		vput(vp);
+		return (error);
+	}
+#endif
 	if (vp->v_type != VLNK)
 		error = EINVAL;
 	else {
@@ -1872,6 +1894,10 @@
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	VATTR_NULL(&vattr);
 	vattr.va_flags = uap->flags;
+#ifdef MAC
+	error = mac_check_vnode_setflags(p->p_ucred, vp, vattr.va_flags);
+	if (error == 0)
+#endif
 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 	vput(vp);
 	return (error);
@@ -1903,6 +1929,10 @@
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	VATTR_NULL(&vattr);
 	vattr.va_flags = uap->flags;
+#ifdef MAC
+	error = mac_check_vnode_setflags(p->p_ucred, vp, vattr.va_flags);
+	if (error == 0)
+#endif
 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 	VOP_UNLOCK(vp, 0, p);
 	return (error);
@@ -2011,6 +2041,11 @@
 	VATTR_NULL(&vattr);
 	vattr.va_uid = uap->uid;
 	vattr.va_gid = uap->gid;
+#ifdef MAC
+	error = mac_check_vnode_setowner(p->p_ucred, vp, vattr.va_uid,
+	    vattr.va_gid);
+	if (error == 0)
+#endif
 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 	vput(vp);
 	return (error);
@@ -2044,6 +2079,11 @@
 	VATTR_NULL(&vattr);
 	vattr.va_uid = uap->uid;
 	vattr.va_gid = uap->gid;
+#ifdef MAC
+	error = mac_check_vnode_setowner(p->p_ucred, vp, vattr.va_uid,
+	    vattr.va_gid);
+	if (error == 0)
+#endif
 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 	VOP_UNLOCK(vp, 0, p);
 	return (error);
@@ -2089,6 +2129,11 @@
 	vattr.va_mtime = ts[1];
 	if (nullflag)
 		vattr.va_vaflags |= VA_UTIMES_NULL;
+#ifdef MAC
+	error = mac_check_vnode_setutimes(p->p_ucred, vp, vattr.va_atime,
+					  vattr.va_mtime);
+	if (error == 0)
+#endif
 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 	VOP_UNLOCK(vp, 0, p);
 out:
@@ -2751,6 +2796,13 @@
 	auio.uio_resid = uap->count;
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	loff = auio.uio_offset = fp->f_offset;
+#ifdef MAC
+	error = mac_check_vnode_readdir(p->p_ucred, vp);
+	if (error) {
+		VOP_UNLOCK(vp, 0, p);
+		return (error);
+	}
+#endif
 #	if (BYTE_ORDER != LITTLE_ENDIAN)
 		if (vp->v_mount->mnt_maxsymlinklen <= 0) {
 			error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
@@ -2908,6 +2960,10 @@
 	auio.uio_resid = uap->count;
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	loff = auio.uio_offset = fp->f_offset;
+#ifdef MAC
+	error = mac_check_vnode_readdir(p->p_ucred, vp);
+	if (error == 0)
+#endif
 	error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
 			    (int *)0, (u_long *)0);
 	fp->f_offset = auio.uio_offset;
@@ -3019,6 +3075,11 @@
 	if (error = namei(&nd))
 		return (error);
 	vp = nd.ni_vp;
+#ifdef MAC
+	error = mac_check_vnode_revoke(p->p_ucred, vp);
+	if (error)
+		goto out;
+#endif
 	if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
 		goto out;
 	if (p->p_ucred->cr_uid != vattr.va_uid &&
@@ -3387,6 +3448,11 @@
         auio.uio_resid = uap->buffersize;
         
         loff = auio.uio_offset = fp->f_offset;
+#ifdef MAC
+	error = mac_check_vnode_readdir(p->p_ucred, vp);
+	if (error)
+		return (error);
+#endif
         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
         error = VOP_READDIRATTR (vp, &attributelist, &auio,
                    actualcount, uap->options, &newstate, &eofflag,

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_vnops.c#2 (text+ko) ====



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310110219.h9B2JKGR050289>