From owner-p4-projects Fri Jan 24 15:33: 4 2003 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5D94637B405; Fri, 24 Jan 2003 15:32:40 -0800 (PST) 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 07E1937B401 for ; Fri, 24 Jan 2003 15:32:40 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2144A43E4A for ; Fri, 24 Jan 2003 15:32:39 -0800 (PST) (envelope-from green@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h0ONWdbv023252 for ; Fri, 24 Jan 2003 15:32:39 -0800 (PST) (envelope-from green@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h0ONWcZJ023249 for perforce@freebsd.org; Fri, 24 Jan 2003 15:32:38 -0800 (PST) Date: Fri, 24 Jan 2003 15:32:38 -0800 (PST) Message-Id: <200301242332.h0ONWcZJ023249@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to green@freebsd.org using -f From: Brian Feldman Subject: PERFORCE change 24154 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://perforce.freebsd.org/chv.cgi?CH=24154 Change 24154 by green@green_laptop_2 on 2003/01/24 15:32:28 Add the set of struct file MAC entry points, and enforce them in SEBSD (largely untested, other than not crashing). Affected files ... .. //depot/projects/trustedbsd/sebsd/sys/compat/linux/linux_file.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_filio.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_misc.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/i386/ibcs2/ibcs2_misc.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/kern/kern_descrip.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/kern/kern_mac.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/kern/sys_generic.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/kern/uipc_usrreq.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/kern/vfs_syscalls.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/kern/vfs_vnops.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd.c#2 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_labels.h#2 edit .. //depot/projects/trustedbsd/sebsd/sys/sys/file.h#2 edit .. //depot/projects/trustedbsd/sebsd/sys/sys/mac.h#2 edit .. //depot/projects/trustedbsd/sebsd/sys/sys/mac_policy.h#2 edit Differences ... ==== //depot/projects/trustedbsd/sebsd/sys/compat/linux/linux_file.c#2 (text+ko) ==== @@ -269,6 +269,13 @@ fdrop(fp, td); return (EBADF); } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (EBADF); + } +#endif vp = (struct vnode *) fp->f_data; if (vp->v_type != VDIR) { ==== //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_filio.c#2 (text+ko) ==== @@ -28,6 +28,8 @@ * $FreeBSD: src/sys/compat/svr4/svr4_filio.c,v 1.22 2002/12/14 01:56:24 alfred Exp $ */ +#include "opt_mac.h" + #include #include #include @@ -186,18 +188,31 @@ struct filedesc *fdp = td->td_proc->p_fd; *retval = 0; + error = 0; FILEDESC_LOCK(fdp); switch (cmd) { case SVR4_FIOCLEX: - fdp->fd_ofileflags[fd] |= UF_EXCLOSE; +#ifdef MAC + error = mac_check_file_change_ofileflags(td->td_ucred, + fp, fdp->fd_ofileflags[uap->fd], + fdp->fd_ofileflags[uap->fd] | UF_EXCLOSE); + if (error == 0) +#endif + fdp->fd_ofileflags[fd] |= UF_EXCLOSE; FILEDESC_UNLOCK(fdp); - return 0; + return (error); case SVR4_FIONCLEX: - fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE; +#ifdef MAC + error = mac_check_file_change_ofileflags(td->td_ucred, + fp, fdp->fd_ofileflags[uap->fd], + fdp->fd_ofileflags[uap->fd] & ~UF_EXCLOSE); + if (error == 0) +#endif + fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE; FILEDESC_UNLOCK(fdp); - return 0; + return (error); case SVR4_FIOGETOWN: case SVR4_FIOSETOWN: ==== //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_misc.c#2 (text+ko) ==== @@ -283,6 +283,14 @@ return error; } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif + nbytes = uap->nbytes; if (nbytes == 1) { nbytes = sizeof (struct svr4_dirent64); @@ -450,6 +458,13 @@ fdrop(fp, td); return (EBADF); } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif vp = (struct vnode *)fp->f_data; if (vp->v_type != VDIR) { ==== //depot/projects/trustedbsd/sebsd/sys/i386/ibcs2/ibcs2_misc.c#2 (text+ko) ==== @@ -323,6 +323,13 @@ fdrop(fp, td); return (EBADF); } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif vp = (struct vnode *)fp->f_data; if (vp->v_type != VDIR) { /* XXX vnode readdir op should do this */ fdrop(fp, td); @@ -480,6 +487,13 @@ fdrop(fp, td); return (EBADF); } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif vp = (struct vnode *)fp->f_data; if (vp->v_type != VDIR) { fdrop(fp, td); ==== //depot/projects/trustedbsd/sebsd/sys/kern/kern_descrip.c#2 (text+ko) ==== @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -282,20 +283,36 @@ break; case F_GETFD: - td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0; +#ifdef MAC + error = mac_check_file_get_ofileflags(td->td_ucred, fp, + *pop); + if (error == 0) +#endif + td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0; FILEDESC_UNLOCK(fdp); break; case F_SETFD: - *pop = (*pop &~ UF_EXCLOSE) | - (arg & FD_CLOEXEC ? UF_EXCLOSE : 0); +#ifdef MAC + error = mac_check_file_change_ofileflags(td->td_ucred, fp, + *pop, (*pop &~ UF_EXCLOSE) | + (arg & FD_CLOEXEC ? UF_EXCLOSE : 0)); + if (error == 0) +#endif + *pop = (*pop &~ UF_EXCLOSE) | + (arg & FD_CLOEXEC ? UF_EXCLOSE : 0); FILEDESC_UNLOCK(fdp); break; case F_GETFL: FILE_LOCK(fp); FILEDESC_UNLOCK(fdp); - td->td_retval[0] = OFLAGS(fp->f_flag); +#ifdef MAC + error = mac_check_file_get_flags(td->td_ucred, fp, + fp->f_flag); + if (error == 0) +#endif + td->td_retval[0] = OFLAGS(fp->f_flag); FILE_UNLOCK(fp); break; @@ -332,6 +349,15 @@ } #endif /* MAC */ #endif +#ifdef MAC + error = mac_check_file_change_flags(td->td_ucred, fp, + fp->f_flag, (fp->f_flag & ~FCNTLFLAGS) | + (FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS)); + if (error) { + fdrop(fp, td); + break; + } +#endif fp->f_flag &= ~FCNTLFLAGS; fp->f_flag |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS; tmp = fp->f_flag & FNONBLOCK; @@ -530,6 +556,14 @@ } if (type == DUP_VARIABLE) new = newfd; +#ifdef MAC + error = mac_check_file_dup(td->td_ucred, fp, new); + if (error) { + FILEDESC_UNLOCK(fdp); + fdrop(fp, td); + return (error); + } +#endif /* * If the old file changed out from under us then treat it as a @@ -1205,6 +1239,10 @@ fp->f_cred = crhold(td->td_ucred); fp->f_ops = &badfileops; fp->f_seqcount = 1; +#ifdef MAC + mac_init_file(fp); + mac_create_file(fp->f_cred, fp); +#endif FILEDESC_LOCK(p->p_fd); if ((fq = p->p_fd->fd_ofiles[0])) { LIST_INSERT_AFTER(fq, fp, f_list); @@ -1239,6 +1277,9 @@ LIST_REMOVE(fp, f_list); nfiles--; sx_xunlock(&filelist_lock); +#ifdef MAC + mac_destroy_file(fp); +#endif crfree(fp->f_cred); uma_zfree(file_zone, fp); } @@ -1551,8 +1592,14 @@ * may block and rip them out from under us. */ for (i = 0; i <= fdp->fd_lastfile; i++) { +#ifdef MAC + if (fdp->fd_ofiles[i] != NULL && + ((fdp->fd_ofileflags[i] & UF_EXCLOSE) || + mac_check_file_inherit(td->td_ucred, fdp->fd_ofiles[i]))) { +#else if (fdp->fd_ofiles[i] != NULL && (fdp->fd_ofileflags[i] & UF_EXCLOSE)) { +#endif struct file *fp; #if 0 @@ -1936,6 +1983,14 @@ if (uap->how & LOCK_UN) { lf.l_type = F_UNLCK; FILE_LOCK(fp); +#ifdef MAC + error = mac_check_file_change_flags(td->td_ucred, fp, + fp->f_flag, fp->f_flag & ~FHASLOCK); + if (error) { + FILE_UNLOCK(fp); + goto done2; + } +#endif fp->f_flag &= ~FHASLOCK; FILE_UNLOCK(fp); error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); @@ -1950,6 +2005,14 @@ goto done2; } FILE_LOCK(fp); +#ifdef MAC + error = mac_check_file_change_flags(td->td_ucred, fp, fp->f_flag, + fp->f_flag | FHASLOCK); + if (error) { + FILE_UNLOCK(fp); + goto done2; + } +#endif fp->f_flag |= FHASLOCK; FILE_UNLOCK(fp); error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, @@ -2013,6 +2076,13 @@ FILEDESC_UNLOCK(fdp); return (EBADF); } +#ifdef MAC + error = mac_check_file_dup(td->td_ucred, wfp, dfd); + if (error) { + FILEDESC_UNLOCK(fdp); + return (error); + } +#endif /* * There are two cases of interest here. ==== //depot/projects/trustedbsd/sebsd/sys/kern/kern_mac.c#2 (text+ko) ==== @@ -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_file = 1; +SYSCTL_INT(_security_mac, OID_AUTO, enforce_file, CTLFLAG_RW, + &mac_enforce_file, 0, "Enforce MAC policy on file descriptors"); +TUNABLE_INT("security.mac.enforce_file", &mac_enforce_file); + 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"); @@ -183,7 +188,7 @@ SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, "TrustedBSD MAC object counters"); -static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, +static unsigned int nmacmbufs, nmaccreds, nmacfiles, nmacifnets, nmacbpfdescs, nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, nmacipqs, nmacpipes, nmacprocs; @@ -191,6 +196,8 @@ &nmacmbufs, 0, "number of mbufs in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, &nmaccreds, 0, "number of ucreds in use"); +SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, files, CTLFLAG_RD, + &nmacfiles, 0, "number of files in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, &nmacifnets, 0, "number of ifnets in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, @@ -678,6 +685,17 @@ #endif } +void +mac_init_file(struct file *fp) +{ + + mac_init_label(&fp->f_label); + MAC_PERFORM(init_file_label, &fp->f_label); +#ifdef MAC_DEBUG + atomic_add_int(&nmacfiles, 1); +#endif +} + static void mac_init_ifnet_label(struct label *label) { @@ -886,6 +904,17 @@ #endif } +void +mac_destroy_file(struct file *fp) +{ + + MAC_PERFORM(destroy_file_label, &fp->f_label); + mac_destroy_label(&fp->f_label); +#ifdef MAC_DEBUG + atomic_subtract_int(&nmacfiles, 1); +#endif +} + static void mac_destroy_ifnet_label(struct label *label) { @@ -1381,6 +1410,131 @@ } int +mac_check_file_create(struct ucred *cred) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_create, cred); + return (error); +} + +int +mac_check_file_dup(struct ucred *cred, struct file *fp, int newfd) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_dup, cred, fp, &fp->f_label, newfd); + return (error); +} + +int +mac_check_file_ioctl(struct ucred *cred, struct file *fp, u_long com) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_ioctl, cred, fp, &fp->f_label, com); + return (error); +} + +int +mac_check_file_inherit(struct ucred *cred, struct file *fp) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_inherit, cred, fp, &fp->f_label); + return (error); +} + +int +mac_check_file_receive(struct ucred *cred, struct file *fp) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_receive, cred, fp, &fp->f_label); + return (error); +} + +int +mac_check_file_get_flags(struct ucred *cred, struct file *fp, u_int flags) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_get_flags, cred, fp, &fp->f_label, flags); + return (error); +} + +int +mac_check_file_get_ofileflags(struct ucred *cred, struct file *fp, char flags) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_get_ofileflags, cred, fp, &fp->f_label, flags); + return (error); +} + +int +mac_check_file_change_flags(struct ucred *cred, struct file *fp, + u_int oldflags, u_int newflags) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_change_flags, cred, fp, &fp->f_label, oldflags, + newflags); + return (error); +} + +int +mac_check_file_change_ofileflags(struct ucred *cred, struct file *fp, + char oldflags, char newflags) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_change_ofileflags, cred, fp, &fp->f_label, + oldflags, newflags); + return (error); +} + +int +mac_check_file_get_offset(struct ucred *cred, struct file *fp) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_get_offset, cred, fp, &fp->f_label); + return (error); +} + +int +mac_check_file_change_offset(struct ucred *cred, struct file *fp) +{ + int error; + + if (!mac_enforce_file) + return (0); + MAC_CHECK(check_file_change_offset, cred, fp, &fp->f_label); + return (error); +} + +int mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) { int error; @@ -2044,6 +2198,13 @@ } void +mac_create_file(struct ucred *cred, struct file *fp) +{ + + MAC_PERFORM(create_file, cred, fp, &fp->f_label); +} + +void mac_create_socket(struct ucred *cred, struct socket *socket) { ==== //depot/projects/trustedbsd/sebsd/sys/kern/sys_generic.c#2 (text+ko) ==== @@ -40,6 +40,7 @@ */ #include "opt_ktrace.h" +#include "opt_mac.h" #include #include @@ -66,6 +67,7 @@ #ifdef KTRACE #include #endif +#include #include #include @@ -591,18 +593,30 @@ switch (com = uap->com) { case FIONCLEX: FILEDESC_LOCK(fdp); - fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; +#ifdef MAC + error = mac_check_file_change_ofileflags(td->td_ucred, + fp, fdp->fd_ofileflags[uap->fd], + fdp->fd_ofileflags[uap->fd] & ~UF_EXCLOSE); +#endif + if (error == 0) + fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; FILEDESC_UNLOCK(fdp); fdrop(fp, td); mtx_unlock(&Giant); - return (0); + return (error); case FIOCLEX: FILEDESC_LOCK(fdp); - fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; +#ifdef MAC + error = mac_check_file_change_ofileflags(td->td_ucred, + fp, fdp->fd_ofileflags[uap->fd], + fdp->fd_ofileflags[uap->fd] | UF_EXCLOSE); +#endif + if (error == 0) + fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; FILEDESC_UNLOCK(fdp); fdrop(fp, td); mtx_unlock(&Giant); - return (0); + return (error); } /* @@ -649,6 +663,15 @@ case FIONBIO: FILE_LOCK(fp); +#ifdef MAC + error = mac_check_file_change_flags(td->td_ucred, fp, + fp->f_flag, *(int *)data ? fp->f_flag | FNONBLOCK : + fp->f_flag & ~FNONBLOCK); + if (error) { + FILE_UNLOCK(fp); + break; + } +#endif if ((tmp = *(int *)data)) fp->f_flag |= FNONBLOCK; else @@ -659,6 +682,15 @@ case FIOASYNC: FILE_LOCK(fp); +#ifdef MAC + error = mac_check_file_change_flags(td->td_ucred, fp, + fp->f_flag, *(int *)data ? fp->f_flag | FASYNC : + fp->f_flag & ~FASYNC); + if (error) { + FILE_UNLOCK(fp); + break; + } +#endif if ((tmp = *(int *)data)) fp->f_flag |= FASYNC; else ==== //depot/projects/trustedbsd/sebsd/sys/kern/uipc_usrreq.c#2 (text+ko) ==== @@ -1040,6 +1040,21 @@ fdp = (int *) CMSG_DATA(mtod(*controlp, struct cmsghdr *)); for (i = 0; i < newfds; i++) { +#ifdef MAC + /* + * Don't pass an error message along, but + * do decrease the message header length + * by the file descriptor's size. + */ + if (mac_check_file_receive(td->td_ucred, *rp)) { + fp = *rp; + *rp++ = 0; + unp_discard(fp); + mtod(*controlp, struct cmsghdr *)-> + cmsg_len -= sizeof(int); + continue; + } +#endif if (fdalloc(td, 0, &f)) panic("unp_externalize fdalloc failed"); fp = *rp++; ==== //depot/projects/trustedbsd/sebsd/sys/kern/vfs_syscalls.c#2 (text+ko) ==== @@ -742,6 +742,12 @@ type = F_FLOCK; if ((flags & FNONBLOCK) == 0) type |= F_WAIT; +#ifdef MAC + error = mac_check_file_change_flags(td->td_ucred, fp, + fp->f_flag, fp->f_flag | FHASLOCK); + if (error) + goto bad; +#endif if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) goto bad; @@ -1320,6 +1326,16 @@ fdrop(fp, td); return (ESPIPE); } +#ifdef MAC + if (uap->whence == L_INCR && uap->offset == 0) + error = mac_check_file_get_offset(cred, fp); + else + error = mac_check_file_change_offset(cred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif vp = (struct vnode *)fp->f_data; noneg = (vp->v_type != VCHR); offset = uap->offset; @@ -3068,6 +3084,13 @@ fdrop(fp, td); return (EBADF); } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif vp = (struct vnode *)fp->f_data; unionread: if (vp->v_type != VDIR) { @@ -3222,6 +3245,13 @@ fdrop(fp, td); return (EINVAL); } +#ifdef MAC + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) { + fdrop(fp, td); + return (error); + } +#endif aiov.iov_base = uap->buf; aiov.iov_len = uap->count; auio.uio_iov = &aiov; ==== //depot/projects/trustedbsd/sebsd/sys/kern/vfs_vnops.c#2 (text+ko) ==== @@ -504,6 +504,13 @@ struct vnode *vp; int error, ioflag; +#ifdef MAC + if ((flags & FOF_OFFSET) == 0) { + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) + return (error); + } +#endif mtx_lock(&Giant); KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); @@ -552,6 +559,13 @@ struct mount *mp; int error, ioflag; +#ifdef MAC + if ((flags & FOF_OFFSET) == 0) { + error = mac_check_file_change_offset(td->td_ucred, fp); + if (error) + return (error); + } +#endif mtx_lock(&Giant); KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd.c#2 (text+ko) ==== @@ -267,6 +267,16 @@ } static void +sebsd_init_file_label(struct label *label) +{ + struct file_security_struct *new_fsec; + + new_fsec = malloc(sizeof(*new_fsec), M_SEBSD, M_ZERO | M_WAITOK); + new_fsec->sid = new_fsec->sid = SECINITSID_UNLABELED; + SLOT(label) = new_fsec; +} + +static void sebsd_init_mount_label(struct label *label) { struct mount_security_struct *sbsec; @@ -425,6 +435,18 @@ } static void +sebsd_create_file(struct ucred *cred, struct file *fp, struct label *label) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(label); + + fsec->sid = tsec->sid; +} + +static void sebsd_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *devfs_dirent, struct label *label, const char *fullpath) @@ -631,7 +653,7 @@ break; default: printf("%s: security_fs_use(%s) returned unrecognized " - "behavior %d\n", __FUNCTION__, mp->mnt_vfc->vfc_name, + "behavior %d\n", __FUNCTION__, mp->mnt_vfc->vfc_name, behavior); behavior = SECURITY_FS_USE_NONE; break; @@ -838,7 +860,7 @@ if (strcmp("sebsd", element_name) != 0) return (0); - (*claimed)++; + (*claimed)++; if (strlcpy(context, element_data, sizeof(context)) >= sizeof(context)) @@ -1061,7 +1083,7 @@ AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.vp = vp; - if (newsid == task->sid) { + if (newsid == task->sid) { rc = avc_has_perm_audit(task->sid, file->sid, SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); @@ -1438,9 +1460,9 @@ { security_context_t context; u_int32_t context_len; - int error; + int error; - if (strcmp("sebsd", element_name) != 0) + if (strcmp("sebsd", element_name) != 0) return (0); (*claimed)++; @@ -1536,11 +1558,95 @@ CAPABILITY__SYS_MODULE, NULL)); } +/* + * Simplify all fd permissions to just "use" for now. The ones we implement + * in SEBSD roughly correlate to the SELinux FD__USE permissions, and not + * the fine-grained FLASK permissions. + */ +static int +sebsd_check_file_get_flags(struct ucred *cred, struct file *fp, + struct label *fplabel, u_int flags) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(fplabel); + return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE, + FD__USE, NULL)); +} + +static int +sebsd_check_file_get_ofileflags(struct ucred *cred, struct file *fp, + struct label *fplabel, char flags) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(fplabel); + return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE, + FD__USE, NULL)); +} + +static int +sebsd_check_file_change_flags(struct ucred *cred, struct file *fp, + struct label *fplabel, u_int oldflags, u_int newflags) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(fplabel); + return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE, + FD__USE, NULL)); +} + +static int +sebsd_check_file_change_ofileflags(struct ucred *cred, struct file *fp, + struct label *fplabel, char oldflags, char newflags) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(fplabel); + return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE, + FD__USE, NULL)); +} + +static int +sebsd_check_file_get_offset(struct ucred *cred, struct file *fp, + struct label *fplabel) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(fplabel); + return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE, + FD__USE, NULL)); +} + +static int +sebsd_check_file_change_offset(struct ucred *cred, struct file *fp, + struct label *fplabel) +{ + struct task_security_struct *tsec; + struct file_security_struct *fsec; + + tsec = SLOT(&cred->cr_label); + fsec = SLOT(fplabel); + return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE, + FD__USE, NULL)); +} + static struct mac_policy_ops sebsd_ops = { /* Init Labels */ .mpo_init = sebsd_init, .mpo_init_cred_label = sebsd_init_cred_label, .mpo_init_devfsdirent_label = sebsd_init_vnode_label, + .mpo_init_file_label = sebsd_init_file_label, .mpo_init_mount_label = sebsd_init_mount_label, .mpo_init_mount_fs_label = sebsd_init_mount_fs_label, .mpo_init_vnode_label = sebsd_init_vnode_label, @@ -1549,6 +1655,7 @@ .mpo_destroy = sebsd_destroy, .mpo_destroy_cred_label = sebsd_destroy_label, .mpo_destroy_devfsdirent_label = sebsd_destroy_label, + .mpo_destroy_file_label = sebsd_destroy_label, .mpo_destroy_mount_label = sebsd_destroy_label, .mpo_destroy_mount_fs_label = sebsd_destroy_label, .mpo_destroy_vnode_label = sebsd_destroy_label, @@ -1567,6 +1674,7 @@ .mpo_create_devfs_device = sebsd_create_devfs_device, .mpo_create_devfs_directory = sebsd_create_devfs_directory, .mpo_create_devfs_symlink = sebsd_create_devfs_symlink, + .mpo_create_file = sebsd_create_file, .mpo_create_proc0 = sebsd_create_proc0, .mpo_create_proc1 = sebsd_create_proc1, .mpo_create_mount = sebsd_create_mount, @@ -1578,6 +1686,12 @@ /* Check Labels */ .mpo_check_cred_relabel = sebsd_check_cred_relabel, + .mpo_check_file_get_flags = sebsd_check_file_get_flags, + .mpo_check_file_get_ofileflags = sebsd_check_file_get_ofileflags, + .mpo_check_file_get_offset = sebsd_check_file_get_offset, + .mpo_check_file_change_flags = sebsd_check_file_change_flags, + .mpo_check_file_change_ofileflags = sebsd_check_file_change_ofileflags, + .mpo_check_file_change_offset = sebsd_check_file_change_offset, .mpo_check_kld_stat = sebsd_check_kld_stat, .mpo_check_kld_load = sebsd_check_kld_load, .mpo_check_kld_unload = sebsd_check_kld_unload, ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_labels.h#2 (text+ko) ==== @@ -48,6 +48,10 @@ avc_entry_ref_t avcr; }; +struct file_security_struct { + security_id_t sid; +}; + struct vnode_security_struct { security_id_t task_sid; security_id_t sid; ==== //depot/projects/trustedbsd/sebsd/sys/sys/file.h#2 (text+ko) ==== @@ -45,6 +45,7 @@ #include #include #include +#include struct stat; struct thread; @@ -109,6 +110,7 @@ void *f_data; /* vnode or socket */ u_int f_flag; /* see fcntl.h */ struct mtx *f_mtxp; /* mutex to protect data */ + struct label f_label; /* MAC label */ }; #endif /* _KERNEL */ ==== //depot/projects/trustedbsd/sebsd/sys/sys/mac.h#2 (text+ko) ==== @@ -113,6 +113,7 @@ struct bpf_d; struct componentname; struct devfs_dirent; +struct file; struct ifnet; struct ifreq; struct image_params; @@ -140,6 +141,7 @@ void mac_init_bpfdesc(struct bpf_d *); void mac_init_cred(struct ucred *); void mac_init_devfsdirent(struct devfs_dirent *); +void mac_init_file(struct file *); void mac_init_ifnet(struct ifnet *); void mac_init_ipq(struct ipq *); int mac_init_socket(struct socket *, int flag); @@ -153,6 +155,7 @@ void mac_destroy_bpfdesc(struct bpf_d *); void mac_destroy_cred(struct ucred *); void mac_destroy_devfsdirent(struct devfs_dirent *); +void mac_destroy_file(struct file *); void mac_destroy_ifnet(struct ifnet *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); @@ -178,6 +181,7 @@ void mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct devfs_dirent *de, const char *fullpath); >>> TRUNCATED FOR MAIL (1000 lines) <<< To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message