From owner-p4-projects@FreeBSD.ORG Fri Oct 10 19:19:22 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5C99616A4C0; Fri, 10 Oct 2003 19:19:22 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2196616A4B3 for ; Fri, 10 Oct 2003 19:19:22 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4FAB443F85 for ; Fri, 10 Oct 2003 19:19:21 -0700 (PDT) (envelope-from cvance@nailabs.com) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.9/8.12.9) with ESMTP id h9B2JLXJ050292 for ; Fri, 10 Oct 2003 19:19:21 -0700 (PDT) (envelope-from cvance@nailabs.com) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.9/8.12.9/Submit) id h9B2JKGR050289 for perforce@freebsd.org; Fri, 10 Oct 2003 19:19:20 -0700 (PDT) (envelope-from cvance@nailabs.com) Date: Fri, 10 Oct 2003 19:19:20 -0700 (PDT) Message-Id: <200310110219.h9B2JKGR050289@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to cvance@nailabs.com using -f From: Chris Vance To: Perforce Change Reviews Subject: PERFORCE change 39493 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Oct 2003 02:19:22 -0000 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) ====