PERFORCE change 107196 for review

Todd Miller millert at FreeBSD.org
Tue Oct 3 09:35:20 PDT 2006


http://perforce.freebsd.org/chv.cgi?CH=107196

Change 107196 by millert at millert_macbook on 2006/10/03 16:34:57

	Add support for labelling file descriptors; adapted from SEBSD.
	We may want to change some of the entry points and add others
	(e.g. ones specifically for locking).
	
	Currently only the test and sedarwin modules use file descriptor labels.
	
	Note that fd passing had to be reworked somewhat since we need
	access to the label of the sender's descriptor for the label checks.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_descrip.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/sys_generic.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/uipc_usrreq.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/miscfs/fdesc/fdesc_vnops.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/file_internal.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_conf.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_syscalls.c#10 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/config/MACFramework.exports#7 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_file.c#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#6 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#12 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs.c#9 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#11 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/policy/Makefile.install#3 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/policy/rules#2 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#22 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/test/mac_test.c#10 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_descrip.c#3 (text+ko) ====

@@ -381,7 +381,7 @@
 	pop = &fdp->fd_ofileflags[fd];
 
 #ifdef MAC
-	error = mac_file_check_fcntl(fp->f_cred, fp, uap->cmd, uap->arg);
+	error = mac_file_check_fcntl(proc_ucred(p), fp, uap->cmd, uap->arg);
 	if (error)
 		goto out;
 #endif
@@ -401,22 +401,40 @@
 		goto out;
 
 	case F_GETFD:
-		*retval = (*pop & UF_EXCLOSE)? 1 : 0;
-		error = 0;
+#ifdef MAC
+		error = mac_file_check_get_ofileflags(proc_ucred(p), fp, *pop);
+		if (error == 0)
+#endif
+			*retval = (*pop & UF_EXCLOSE)? 1 : 0;
 		goto out;
 
 	case F_SETFD:
-		*pop = (*pop &~ UF_EXCLOSE) |
-			(uap->arg & 1)? UF_EXCLOSE : 0;
-		error = 0;
+#ifdef MAC
+		error = mac_file_check_change_ofileflags(proc_ucred(p),
+		    fp, *pop, (*pop &~ UF_EXCLOSE) |
+		    ((uap->arg & 1) ? UF_EXCLOSE : 0));
+		if (error == 0)
+#endif
+			*pop = (*pop &~ UF_EXCLOSE) |
+				(uap->arg & 1)? UF_EXCLOSE : 0;
 		goto out;
 
 	case F_GETFL:
-		*retval = OFLAGS(fp->f_flag);
-		error = 0;
+#ifdef MAC
+		error = mac_file_check_get_flags(proc_ucred(p), fp, fp->f_flag);
+		if (error == 0)
+#endif
+			*retval = OFLAGS(fp->f_flag);
 		goto out;
 
 	case F_SETFL:
+#ifdef MAC
+		error = mac_file_check_change_flags(proc_ucred(p),
+		    fp, fp->f_flag, (fp->f_flag & ~FCNTLFLAGS) |
+		    (FFLAGS(CAST_DOWN(int, uap->arg)) & FCNTLFLAGS));
+		if (error)
+			goto out;
+#endif
 		fp->f_flag &= ~FCNTLFLAGS;
 		tmp = CAST_DOWN(int, uap->arg);
 		fp->f_flag |= FFLAGS(tmp) & FCNTLFLAGS;
@@ -955,6 +973,9 @@
 {
 	struct fileproc *nfp;
 	struct fileproc *ofp;
+#ifdef MAC
+	int error;
+#endif
 
 	if ((ofp = fdp->fd_ofiles[old]) == NULL ||
 			(fdp->fd_ofileflags[old] & UF_RESERVED)) {
@@ -962,6 +983,17 @@
 		return (EBADF);
 	}
 	fg_ref(ofp);
+
+#ifdef MAC
+	error = mac_file_check_dup(proc_ucred(p), ofp, new);
+	if (error) {
+		fg_drop(ofp);
+		_fdrelse(fdp, new);
+		proc_fdunlock(p);
+		return (error);
+	}
+#endif
+
 	proc_fdunlock(p);
 
 	MALLOC_ZONE(nfp, struct fileproc *, sizeof(struct fileproc), M_FILEPROC, M_WAITOK);
@@ -971,6 +1003,10 @@
 	nfp->f_flags = ofp->f_flags;
 	nfp->f_fglob = ofp->f_fglob;
 	nfp->f_iocount = 0;
+#ifdef MAC
+	mac_file_label_init(nfp);
+	mac_file_label_copy(ofp->f_label, nfp->f_label);
+#endif
 
 	fdp->fd_ofiles[new] = nfp;
 	fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
@@ -1087,6 +1123,9 @@
 	if (!locked)
 		proc_fdunlock(p);
 
+#ifdef MAC
+	mac_file_label_destroy(fp);
+#endif
 	FREE_ZONE(fp, sizeof *fp, M_FILEPROC);	
 	return(error);
 }
@@ -1438,6 +1477,9 @@
 			fdp->fd_ofiles[fd] == NULL &&
 			!(fdp->fd_ofileflags[fd] & UF_RESERVED))
 		fdp->fd_lastfile--;
+#ifdef MAC
+	mac_file_label_destroy(fp);
+#endif
 	FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
 }
 
@@ -1889,6 +1931,12 @@
 	 */
 	proc_fdunlock(p);
 
+#ifdef MAC
+	error = mac_file_check_create(proc_ucred(p));
+	if (error)
+		return (error);
+#endif
+
 	MALLOC_ZONE(fp, struct fileproc *, sizeof(struct fileproc), M_FILEPROC, M_WAITOK);
 	MALLOC_ZONE(fg, struct fileglob *, sizeof(struct fileglob), M_FILEGLOB, M_WAITOK);
 	bzero(fp, sizeof(struct fileproc));
@@ -1898,10 +1946,16 @@
 	fp->f_iocount = 1;
 	fg->fg_count = 1;
 	fp->f_fglob = fg;
+#ifdef MAC
+	mac_file_label_init(fp);
+#endif
 
 	proc_fdlock(p);
 
 	fp->f_cred = kauth_cred_proc_ref(p);
+#ifdef MAC
+	mac_file_label_associate(fp->f_cred, fp);
+#endif
 
 	lck_mtx_lock(file_flist_lock);
 
@@ -1965,9 +2019,13 @@
 	proc_fdlock(p);
 
 	while (i >= 0) {
-		if ((*flags & (UF_RESERVED|UF_EXCLOSE)) == UF_EXCLOSE) {
-			struct fileproc *fp = *fpp;
+		struct fileproc *fp = *fpp;
 
+		if ((*flags & UF_RESERVED) == 0 && ((*flags & UF_EXCLOSE) != 0
+#ifdef MAC
+		    || (fp && mac_file_check_inherit(proc_ucred(p), fp))
+#endif
+		)) {
                         if (i < fdp->fd_knlistsize)
                                 knote_fdclose(p, i);
 
@@ -1975,8 +2033,15 @@
 			if (i == fdp->fd_lastfile && i > 0)
 				fdp->fd_lastfile--;
 			closef_locked(fp, fp->f_fglob, p);
+#ifdef MAC
+			mac_file_label_destroy(fp);
+#endif
 			FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
 		}
+#ifdef MAC
+		else if ((*flags & UF_RESERVED) == 0 && fp != NULL)
+			mac_file_label_update(proc_ucred(p), fp);
+#endif
 
 		i--; fpp--; flags--;
 	}
@@ -2137,6 +2202,10 @@
 				fp->f_iocount = 0;
 				fp->f_fglob = ofp->f_fglob;
 				(void)fg_ref(fp);
+#ifdef MAC
+				mac_file_label_init(fp);
+				mac_file_label_copy(ofp->f_label, fp->f_label);
+#endif
 				*fpp = fp;
 			} else {
 				*fpp = NULL;
@@ -2192,6 +2261,9 @@
 				if (fp->f_flags & FP_WAITEVENT) 
 					(void)waitevent_close(p, fp);
 				(void) closef_locked(fp, fp->f_fglob, p);
+#ifdef MAC
+				mac_file_label_destroy(fp);
+#endif
 				FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
 			}
 		}
@@ -2371,6 +2443,9 @@
         proc_fdunlock(p);
 
 	fg_free(fp->f_fglob);
+#ifdef MAC
+	mac_file_label_destroy(fp);
+#endif
 	FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
 }
 
@@ -2409,6 +2484,12 @@
 	lf.l_len = 0;
 	if (how & LOCK_UN) {
 		lf.l_type = F_UNLCK;
+#ifdef MAC
+		error = mac_file_check_change_flags(proc_ucred(p), fp,
+		    fp->f_flag, fp->f_flag & ~FHASLOCK);
+		if (error)
+			goto out;
+#endif
 		fp->f_flag &= ~FHASLOCK;
 		error = VNOP_ADVLOCK(vp, (caddr_t)fp->f_fglob, F_UNLCK, &lf, F_FLOCK, &context);
 		goto out;
@@ -2421,6 +2502,12 @@
 	        error = EBADF;
 		goto out;
 	}
+#ifdef MAC
+	error = mac_file_check_change_flags(proc_ucred(p), fp,
+	    fp->f_flag, fp->f_flag | FHASLOCK);
+	if (error)
+		goto out;
+#endif
 	fp->f_flag |= FHASLOCK;
 	if (how & LOCK_NB) {
 		error = VNOP_ADVLOCK(vp, (caddr_t)fp->f_fglob, F_SETLK, &lf, F_FLOCK, &context);
@@ -2471,6 +2558,9 @@
 {
 	struct fileproc *wfp;
 	struct fileproc *fp;
+#ifdef MAC
+	int myerror;
+#endif
 	struct proc * p = current_proc();
 
 	/*
@@ -2490,6 +2580,13 @@
 	        proc_fdunlock(p);
 		return (EBADF);
 	}
+#ifdef MAC
+	myerror = mac_file_check_dup(proc_ucred(p), wfp, dfd);
+	if (myerror) {
+		proc_fdunlock(p);
+		return (myerror);
+	}
+#endif
 	/*
 	 * There are two cases of interest here.
 	 *
@@ -2541,6 +2638,9 @@
 
 	        proc_fdunlock(p);
 
+#ifdef MAC
+		mac_file_label_destroy(wfp);
+#endif
 		FREE_ZONE(wfp, sizeof *fp, M_FILEPROC);	
 
 		return (0);

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/sys_generic.c#2 (text+ko) ====

@@ -737,6 +737,13 @@
 			error = EBADF;
 			goto out;
 	}
+
+#ifdef MAC
+	error = mac_file_check_ioctl(proc_ucred(p), fp, uap->com,
+	    (void *)uap->data);
+	if (error)
+		goto out;
+#endif
 		
 #if NETAT
 	/*
@@ -762,12 +769,22 @@
 
 	switch (com = uap->com) {
 	case FIONCLEX:
-		*fdflags(p, uap->fd) &= ~UF_EXCLOSE;
-		error =0;
+#ifdef MAC
+		error = mac_file_check_change_ofileflags(proc_ucred(p),
+		    fp, *fdflags(p, uap->fd),
+		    *fdflags(p, uap->fd) & ~UF_EXCLOSE);
+		if (error == 0)
+#endif
+			*fdflags(p, uap->fd) &= ~UF_EXCLOSE;
 		goto out;
 	case FIOCLEX:
-		*fdflags(p, uap->fd) |= UF_EXCLOSE;
-		error =0;
+#ifdef MAC
+		error = mac_file_check_change_ofileflags(proc_ucred(p),
+		    fp, *fdflags(p, uap->fd),
+		    *fdflags(p, uap->fd) | UF_EXCLOSE);
+		if (error == 0)
+#endif
+			*fdflags(p, uap->fd) |= UF_EXCLOSE;
 		goto out;
 	}
 
@@ -831,6 +848,13 @@
 	switch (com) {
 
 	case FIONBIO:
+#ifdef MAC
+		error = mac_file_check_change_flags(proc_ucred(p), fp,
+		    fp->f_flag, *(int *)datap ? fp->f_flag | FNONBLOCK :
+		    fp->f_flag & ~FNONBLOCK);
+		if (error)
+			goto out;
+#endif
 		if ( (tmp = *(int *)datap) )
 			fp->f_flag |= FNONBLOCK;
 		else
@@ -839,6 +863,13 @@
 		break;
 
 	case FIOASYNC:
+#ifdef MAC
+		error = mac_file_check_change_flags(proc_ucred(p), fp,
+		    fp->f_flag, *(int *)datap ? fp->f_flag | FASYNC :
+		    fp->f_flag & ~FASYNC);
+		if (error)
+			goto out;
+#endif
 		if ( (tmp = *(int *)datap) )
 			fp->f_flag |= FASYNC;
 		else

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/uipc_usrreq.c#6 (text+ko) ====

@@ -129,8 +129,8 @@
 static void    unp_gc(void);
 static void    unp_scan(struct mbuf *, void (*)(struct fileglob *));
 static void    unp_mark(struct fileglob *);
-static void    unp_discard(struct fileglob *);
-static void    unp_discard_fdlocked(struct fileglob *, struct proc *);
+static void    unp_discard(struct fileproc *);
+static void    unp_discard_fdlocked(struct fileproc *, struct proc *);
 static int     unp_internalize(struct mbuf *, struct proc *);
 static int     unp_listen(struct unpcb *, struct proc *);
 
@@ -1059,9 +1059,8 @@
 	struct proc *p = current_proc();		/* XXX */
 	int i;
 	struct cmsghdr *cm = mtod(rights, struct cmsghdr *);
-	struct fileglob **rp = (struct fileglob **)(cm + 1);
+	struct fileproc **rp = (struct fileproc **)(cm + 1);
 	struct fileproc *fp;
-	struct fileglob *fg;
 	int newfds = (cm->cmsg_len - sizeof(*cm)) / sizeof (int);
 	int f;
 
@@ -1072,8 +1071,8 @@
 	 */
 	if (!fdavail(p, newfds)) {
 		for (i = 0; i < newfds; i++) {
-			fg = *rp;
-			unp_discard_fdlocked(fg, p);
+			fp = *rp;
+			unp_discard_fdlocked(fp, p);
 			*rp++ = 0;
 		}
 		proc_fdunlock(p);
@@ -1087,15 +1086,26 @@
 	 * XXX this assumes a pointer and int are the same size...!
 	 */
 	for (i = 0; i < newfds; i++) {
+		fp = *rp;
+#ifdef MAC
+		/*
+		 * If receive access is denied, don't pass along
+		 * and error message, just discard the descriptor.
+		 */
+		if (mac_file_check_receive(proc_ucred(p), fp)) {
+			*rp++ = 0;
+			unp_discard_fdlocked(fp, p);
+			continue;
+		}
+#endif
 		if (fdalloc(p, 0, &f))
 			panic("unp_externalize");
-		fg = *rp;
-		MALLOC_ZONE(fp, struct fileproc *, sizeof(struct fileproc), M_FILEPROC, M_WAITOK);
-		bzero(fp, sizeof(struct fileproc));
 		fp->f_iocount = 0;
-		fp->f_fglob = fg;
+#ifdef MAC
+		mac_file_label_update(proc_ucred(p), fp);
+#endif
 		p->p_fd->fd_ofiles[f] = fp;
-		fg_removeuipc(fg);
+		fg_removeuipc(fp->f_fglob);
 		*fdflags(p, f) &= ~UF_RESERVED;
 		unp_rights--;
 		*(int *)rp++ = f;
@@ -1140,8 +1150,8 @@
 	struct proc *p)
 {
 	struct cmsghdr *cm = mtod(control, struct cmsghdr *);
-	struct fileglob **rp;
-	struct fileproc *fp;
+	struct fileproc **rp;
+	struct fileproc *fp, *ofp;
 	register int i, error;
 	int oldfds;
 	int fdgetf_noref(proc_t, struct fileglob **, struct fileproc **);
@@ -1153,20 +1163,28 @@
 	oldfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int);
 
 	proc_fdlock(p);
-	rp = (struct fileglob **)(cm + 1);
+	rp = (struct fileproc **)(cm + 1);
 
 	for (i = 0; i < oldfds; i++) {
-	     if (error = fdgetf_noref(p, *(int *)rp++, (struct fileglob **)0)) {
+	     if (error = fdgetf_noref(p, *(int *)rp++, (struct fileproc **)0)) {
 	             proc_fdunlock(p);
 		     return (error);
 	     }
 	}
-	rp = (struct fileglob **)(cm + 1);
+	rp = (struct fileproc **)(cm + 1);
 
 	for (i = 0; i < oldfds; i++) {
-		(void) fdgetf_noref(p, *(int *)rp, &fp);
+		(void) fdgetf_noref(p, *(int *)rp, &ofp);
+		MALLOC_ZONE(fp, struct fileproc *, sizeof(struct fileproc),
+		    M_FILEPROC, M_WAITOK);
+		bzero(fp, sizeof(struct fileproc));
+		fp->f_fglob = ofp->f_fglob;
+#ifdef MAC
+		mac_file_label_init(fp);
+		mac_file_label_copy(ofp->f_label, fp->f_label);
+#endif
 		fg_insertuipc(fp->f_fglob);
-		*rp++ = fp->f_fglob;
+		*rp++ = fp;
 		unp_rights++;
 	}
 	proc_fdunlock(p);
@@ -1375,7 +1393,7 @@
 {
 
 	if (m) {
-		unp_scan(m, unp_discard);
+		unp_scan(m, (void (*)(struct fileglob *))unp_discard);
 	}
 }
 
@@ -1440,23 +1458,27 @@
 
 /* should run under kernel funnel */
 static void
-unp_discard(fg)
-	struct fileglob *fg;
+unp_discard(fp)
+	struct fileproc *fp;
 {
 	struct proc *p = current_proc();		/* XXX */
 
 	proc_fdlock(p);
-	unp_discard_fdlocked(fg, p);
+	unp_discard_fdlocked(fp, p);
 	proc_fdunlock(p);
 }
 static void
-unp_discard_fdlocked(fg, p)
-	struct fileglob *fg;
+unp_discard_fdlocked(fp, p)
+	struct fileproc *fp;
 	struct proc *p;
 {
 
-	fg_removeuipc(fg);
+	fg_removeuipc(fp->f_fglob);
 
 	unp_rights--;
-	(void) closef_locked((struct fileproc *)0, fg, p);
+	(void) closef_locked((struct fileproc *)0, fp->f_fglob, p);
+#ifdef MAC
+	mac_file_label_destroy(fp);
+#endif
+	FREE(fp, M_FILEPROC);
 }

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/miscfs/fdesc/fdesc_vnops.c#2 (text+ko) ====

@@ -226,6 +226,10 @@
 	struct componentname *cnp = ap->a_cnp;
 	char *pname = cnp->cn_nameptr;
 	struct proc *p = vfs_context_proc(ap->a_context);
+#ifdef MAC
+	struct filedesc *fdp = p->p_fd;
+	struct fileproc *fp;
+#endif
 	int numfiles = p->p_fd->fd_nfiles;
 	int fd;
 	int error;
@@ -322,6 +326,11 @@
 		if (error)
 			goto bad;
 		VTOFDESC(fvp)->fd_fd = fd;
+#ifdef MAC
+		fp = fdp->fd_ofiles[fd];
+		mac_vnode_label_associate_file(vfs_context_ucred(ap->a_context),
+		    fp, fvp);
+#endif
 		*vpp = fvp;
 		return (0);
 	}

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/file_internal.h#3 (text+ko) ====

@@ -86,6 +86,7 @@
 	int32_t f_iocount;
 	struct fileglob * f_fglob;
 	void *	f_waddr;
+	struct label *f_label;
 };
 
 #define FILEPROC_NULL (struct fileproc *)0

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_conf.c#2 (text+ko) ====

@@ -141,7 +141,7 @@
 
 	/* File Descriptor Filesystem */
 #if FDESC
-	{ &fdesc_vfsops, "fdesc", 7, 0, 0, NULL, NULL, 0, {0}, VFC_VFSGENERICARGS|VFC_VFSNOMACLABEL , 0, 0},
+	{ &fdesc_vfsops, "fdesc", 7, 0, 0, NULL, NULL, 0, {0}, VFC_VFSGENERICARGS , 0, 0},
 #endif
 
 	/* Volume ID Filesystem */

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_syscalls.c#10 (text+ko) ====

@@ -1737,6 +1737,12 @@
 		type = F_FLOCK;
 		if ((flags & FNONBLOCK) == 0)
 			type |= F_WAIT;
+#ifdef MAC
+		error = mac_file_check_change_flags(vfs_context_ucred(ctx),
+		    fp, fp->f_fglob->fg_flag, fp->f_fglob->fg_flag | FHASLOCK);
+		if (error)
+			goto bad;
+#endif
 		if ((error = VNOP_ADVLOCK(vp, (caddr_t)fp->f_fglob, F_SETLK, &lf, type, ctx)))
 			goto bad;
 		fp->f_fglob->fg_flag |= FHASLOCK;
@@ -2461,6 +2467,21 @@
 		file_drop(uap->fd);
 		return(ESPIPE);
 	}
+
+	context.vc_proc = p;
+	context.vc_ucred = kauth_cred_get();
+#ifdef MAC
+	if (uap->whence == L_INCR && uap->offset == 0)
+		error = mac_file_check_get_offset(vfs_context_ucred(&context),
+		    fp);
+	else
+		error = mac_file_check_change_offset(vfs_context_ucred(&context),
+		    fp);
+	if (error) {
+		file_drop(uap->fd);
+		return (error);
+	}
+#endif
 	if ( (error = vnode_getwithref(vp)) ) {
 		file_drop(uap->fd);
 		return(error);
@@ -2471,8 +2492,6 @@
 		offset += fp->f_fglob->fg_offset;
 		break;
 	case L_XTND:
-		context.vc_proc = p;
-		context.vc_ucred = kauth_cred_get();
 		if ((error = vnode_size(vp, &file_size, &context)) != 0)
 			break;
 		offset += file_size;
@@ -4468,6 +4487,15 @@
 		error = EBADF;
 		goto out;
 	}
+
+	context.vc_proc = p;
+	context.vc_ucred = fp->f_fglob->fg_cred;
+
+#ifdef MAC
+	error = mac_file_check_change_offset(kauth_cred_get(), fp);
+	if (error)
+		goto out;
+#endif
 	if ( (error = vnode_getwithref(vp)) ) {
 		goto out;
 	}
@@ -4481,9 +4509,6 @@
 		goto out;
 	}
 
-	context.vc_proc = p;
-	context.vc_ucred = fp->f_fglob->fg_cred;
-
 #ifdef MAC
 	error = mac_vnode_check_readdir(vfs_context_ucred(&context), vp);
 	if (error != 0) {
@@ -4780,6 +4805,15 @@
 		error = EBADF;
 		goto out;
 	}
+
+	context.vc_proc = p;
+	context.vc_ucred = kauth_cred_get();
+
+#ifdef MAC
+	error = mac_file_check_change_offset(vfs_context_ucred(&context), fp);
+	if (error)
+		goto out;
+#endif
 	if ( (error = vnode_getwithref(vp)) )
 		goto out;
 
@@ -4791,9 +4825,6 @@
 		goto out;
 	}
 
-	context.vc_proc = p;
-	context.vc_ucred = kauth_cred_get();
-
 #ifdef MAC
 	error = mac_vnode_check_readdir(vfs_context_ucred(&context), vp);
 	if (error != 0) {

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/config/MACFramework.exports#7 (text+ko) ====

@@ -24,6 +24,8 @@
 _kauth_cred_dup
 _kauth_cred_dup_add
 
+_sotoxsocket
+
 _mac_kalloc
 _mac_kfree
 _mac_wire

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#3 (text+ko) ====

@@ -24,3 +24,4 @@
 security/mac_net.c					optional mac
 security/mac_pipe.c					optional mac
 security/mac_iokit.c					optional mac
+security/mac_file.c					optional mac

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#6 (text+ko) ====

@@ -89,6 +89,7 @@
  */
 void	mac_cred_label_init(struct ucred *);
 void	mac_devfs_label_init(struct devnode *);
+void	mac_file_label_init(struct fileproc *fp);
 int	mac_mbuf_label_init(struct mbuf *, int);
 int	mac_mbuf_tag_init(struct m_tag *, int);
 void	mac_mount_label_init(struct mount *);
@@ -104,11 +105,15 @@
 void	mac_vnode_label_init(struct vnode *vp);
 void	mac_vnode_label_copy(struct label *, struct label *label);
 void	mac_devfs_label_copy(struct label *, struct label *label);
+void	mac_file_label_copy(struct label *, struct label *label);
 void	mac_mbuf_tag_copy(struct m_tag *, struct m_tag *);
 void	mac_mbuf_label_copy(struct mbuf *m_from, struct mbuf *m_to);
 void	mac_socket_label_copy(struct label *from, struct label *to);
+void	mac_file_label_associate(struct ucred *cred, struct fileproc *fp);
+void	mac_file_label_update(struct ucred *cred, struct fileproc *fp);
 void	mac_cred_label_destroy(struct ucred *);
 void	mac_devfs_label_destroy(struct devnode *);
+void	mac_file_label_destroy(struct fileproc *fp);
 void	mac_mbuf_label_destroy(struct mbuf *);
 void	mac_mbuf_tag_destroy(struct m_tag *);
 void	mac_mount_label_destroy(struct mount *);
@@ -286,11 +291,25 @@
 int	mac_sysvsem_check_semctl(struct ucred *cred,
 	    struct semid_kernel *semakptr, int cmd);
 int	mac_file_check_fcntl(struct ucred *cred, struct fileproc *fp, int cmd,
-	    int arg);
+	    long arg);
 int	mac_file_check_get(struct ucred *cred, struct fileproc *fp,
 	    char *elements, int len);
+int	mac_file_check_create(struct ucred *cred);
+int	mac_file_check_dup(struct ucred *cred, struct fileproc *fp, int newfd);
 int	mac_file_check_ioctl(struct ucred *cred, struct fileproc *fp,
-	    int com, void *data);
+	    u_long com, void *data);
+int	mac_file_check_inherit(struct ucred *cred, struct fileproc *fp);
+int	mac_file_check_receive(struct ucred *cred, struct fileproc *fp);
+int	mac_file_check_get_flags(struct ucred *cred, struct fileproc *fp,
+	    u_int flags);
+int	mac_file_check_get_ofileflags(struct ucred *cred, struct fileproc *fp,
+	    char flags);
+int	mac_file_check_change_flags(struct ucred *cred, struct fileproc *fp,
+	    u_int oldflags, u_int newflags);
+int	mac_file_check_change_ofileflags(struct ucred *cred,
+	    struct fileproc *fp, char oldflags, char newflags);
+int	mac_file_check_get_offset(struct ucred *cred, struct fileproc *fp);
+int	mac_file_check_change_offset(struct ucred *cred, struct fileproc *fp);
 int	mac_file_check_set(struct ucred *cred, struct fileproc *fp,
 	    char *buf, int buflen);
 int	mac_sysvsem_check_semget(struct ucred *cred,

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#12 (text+ko) ====

@@ -287,6 +287,14 @@
 );
 
 /**
+  @brief Initialize file label
+  @param label New label to initialize
+*/
+typedef void mpo_file_label_init_t(
+	struct label *label
+);
+
+/**
   @brief Initialize Login Context label
   @param label New label to initialize
 */
@@ -530,6 +538,38 @@
 );
 
 /**
+  @brief Create file label
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+*/
+typedef void mpo_file_label_associate_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label
+);
+
+/**
+  @brief Update file label
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label New policy label for fp
+*/
+typedef void mpo_file_label_update_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label
+);
+
+/**
+ @brief Destroy file label
+ @param label The label to be destroyed
+*/
+typedef void mpo_file_label_destroy_t(
+	struct label *label
+);
+
+/**
   @brief Destroy devfs label
   @param label The label to be destroyed
 
@@ -947,6 +987,19 @@
 );
 
 /**
+  @brief Copy a file label
+  @param src Source file label
+  @param dest Destination file label
+
+  Copy the file label information from src to dest.  This is
+  used when duplicating, passing or inheriting file descriptors.
+*/
+typedef void mpo_file_label_copy_t(
+	struct label *src,
+	struct label *dest
+);
+
+/**
   @brief Externalize a user credential label
   @param label Label to be externalized
   @param element_name Name of the label namespace for which labels should be
@@ -2727,7 +2780,7 @@
 	struct ucred *cred,
 	struct fileproc *fp,
 	int cmd,
-	int arg
+	long arg
 );
 
 /**
@@ -3537,6 +3590,41 @@
 );
 
 /**
+  @brief Access control for creating a file descriptor
+  @param cred Subject credential
+
+  Determine whether the subject identified by the credential can
+  allocate a new file descriptor.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_create_t(
+	struct ucred *cred
+);
+
+/**
+  @brief Access control for duplicating a file descriptor
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+  @param newfd New file descriptor number
+
+  Determine whether the subject identified by the credential can
+  duplicate the file structure represented by fp and as file
+  descriptor number newfd.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_dup_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label,
+	int newfd
+);
+
+/**
   @brief Access control check for file ioctl
   @param cred Subject credential
   @param fp Fileproc structure
@@ -3558,11 +3646,167 @@
 	struct ucred *cred,
 	struct fileproc *fp,
 	struct label *label,
-	unsigned int cmd,
+	unsigned long cmd,
 	void *data
 );
 
 /**
+  @brief Access control for inheriting a file descriptor
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+
+  Determine whether the subject identified by the credential can
+  inherit the file structure represented by fp.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_inherit_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label
+);
+
+/**
+  @brief Access control for receiving a file descriptor
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+
+  Determine whether the subject identified by the credential can
+  receive the file structure represented by fp.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_receive_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label
+);
+
+/**
+  @brief Access control for getting file descriptor flags
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+  @param flags Requested flags
+
+  Determine whether the subject identified by the credential can
+  get the specified flags for the file structure represented by fp.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_get_flags_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label,
+	u_int flags
+);
+
+/**
+  @brief Access control for getting open file flags
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+  @param flags Requested flags
+
+  Determine whether the subject identified by the credential can
+  get the open file flags for the file structure represented by fp.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_get_ofileflags_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label,
+	char flags
+);
+
+/**
+  @brief Access control for changing file descriptor flags
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+  @param oldflags Old fd flags
+  @param newflags New fd flags
+
+  Determine whether the subject identified by the credential can
+  change the specified flags for the file structure represented by fp.
+
+  @return Return 0 if access if granted, otherwise an appropriate
+  value for errno should be returned.
+*/
+typedef int mpo_file_check_change_flags_t(
+	struct ucred *cred,
+	struct fileproc *fp,
+	struct label *label,
+	u_int oldflags,
+	u_int newflags
+);
+
+/**
+  @brief Access control for changing open file flags
+  @param cred Subject credential
+  @param fp Fileproc structure
+  @param label Policy label for fp
+  @param flags Old flags
+  @param flags New flags
+

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the trustedbsd-cvs mailing list