PERFORCE change 39493 for review
Chris Vance
cvance at FreeBSD.org
Sat Oct 11 02:19:20 GMT 2003
http://perforce.freebsd.org/chv.cgi?CH=39493
Change 39493 by cvance at 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) ====
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list