Index: head/sys/kern/sys_socket.c =================================================================== --- head/sys/kern/sys_socket.c (revision 145166) +++ head/sys/kern/sys_socket.c (revision 145167) @@ -1,302 +1,320 @@ /*- * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93 */ #include __FBSDID("$FreeBSD$"); #include "opt_mac.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /* XXX */ #include #include #include #include #include #include struct fileops socketops = { .fo_read = soo_read, .fo_write = soo_write, .fo_ioctl = soo_ioctl, .fo_poll = soo_poll, .fo_kqfilter = soo_kqfilter, .fo_stat = soo_stat, .fo_close = soo_close, .fo_flags = DFLAG_PASSABLE }; /* ARGSUSED */ int soo_read(fp, uio, active_cred, flags, td) struct file *fp; struct uio *uio; struct ucred *active_cred; struct thread *td; int flags; { struct socket *so = fp->f_data; int error; NET_LOCK_GIANT(); #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_receive(active_cred, so); SOCK_UNLOCK(so); if (error) { NET_UNLOCK_GIANT(); return (error); } #endif error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0); NET_UNLOCK_GIANT(); return (error); } /* ARGSUSED */ int soo_write(fp, uio, active_cred, flags, td) struct file *fp; struct uio *uio; struct ucred *active_cred; struct thread *td; int flags; { struct socket *so = fp->f_data; int error; NET_LOCK_GIANT(); #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_send(active_cred, so); SOCK_UNLOCK(so); if (error) { NET_UNLOCK_GIANT(); return (error); } #endif error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0, uio->uio_td); if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { PROC_LOCK(uio->uio_td->td_proc); psignal(uio->uio_td->td_proc, SIGPIPE); PROC_UNLOCK(uio->uio_td->td_proc); } NET_UNLOCK_GIANT(); return (error); } int soo_ioctl(fp, cmd, data, active_cred, td) struct file *fp; u_long cmd; void *data; struct ucred *active_cred; struct thread *td; { struct socket *so = fp->f_data; int error = 0; NET_LOCK_GIANT(); switch (cmd) { case FIONBIO: SOCK_LOCK(so); if (*(int *)data) so->so_state |= SS_NBIO; else so->so_state &= ~SS_NBIO; SOCK_UNLOCK(so); break; case FIOASYNC: /* * XXXRW: This code separately acquires SOCK_LOCK(so) * and SOCKBUF_LOCK(&so->so_rcv) even though they are * the same mutex to avoid introducing the assumption * that they are the same. */ if (*(int *)data) { SOCK_LOCK(so); so->so_state |= SS_ASYNC; SOCK_UNLOCK(so); SOCKBUF_LOCK(&so->so_rcv); so->so_rcv.sb_flags |= SB_ASYNC; SOCKBUF_UNLOCK(&so->so_rcv); SOCKBUF_LOCK(&so->so_snd); so->so_snd.sb_flags |= SB_ASYNC; SOCKBUF_UNLOCK(&so->so_snd); } else { SOCK_LOCK(so); so->so_state &= ~SS_ASYNC; SOCK_UNLOCK(so); SOCKBUF_LOCK(&so->so_rcv); so->so_rcv.sb_flags &= ~SB_ASYNC; SOCKBUF_UNLOCK(&so->so_rcv); SOCKBUF_LOCK(&so->so_snd); so->so_snd.sb_flags &= ~SB_ASYNC; SOCKBUF_UNLOCK(&so->so_snd); } break; case FIONREAD: /* Unlocked read. */ *(int *)data = so->so_rcv.sb_cc; break; case FIOSETOWN: error = fsetown(*(int *)data, &so->so_sigio); break; case FIOGETOWN: *(int *)data = fgetown(&so->so_sigio); break; case SIOCSPGRP: error = fsetown(-(*(int *)data), &so->so_sigio); break; case SIOCGPGRP: *(int *)data = -fgetown(&so->so_sigio); break; case SIOCATMARK: /* Unlocked read. */ *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0; break; default: /* * Interface/routing/protocol specific ioctls: * interface and routing ioctls should have a * different entry since a socket's unnecessary */ if (IOCGROUP(cmd) == 'i') error = ifioctl(so, cmd, data, td); else if (IOCGROUP(cmd) == 'r') error = rtioctl(cmd, data); else error = ((*so->so_proto->pr_usrreqs->pru_control) (so, cmd, data, 0, td)); break; } NET_UNLOCK_GIANT(); return(error); } int soo_poll(fp, events, active_cred, td) struct file *fp; int events; struct ucred *active_cred; struct thread *td; { struct socket *so = fp->f_data; int error; NET_LOCK_GIANT(); +#ifdef MAC + SOCK_LOCK(so); + error = mac_check_socket_poll(active_cred, so); + SOCK_UNLOCK(so); + if (error) { + NET_UNLOCK_GIANT(); + return (error); + } +#endif error = (so->so_proto->pr_usrreqs->pru_sopoll) (so, events, fp->f_cred, td); NET_UNLOCK_GIANT(); return (error); } int soo_stat(fp, ub, active_cred, td) struct file *fp; struct stat *ub; struct ucred *active_cred; struct thread *td; { struct socket *so = fp->f_data; int error; bzero((caddr_t)ub, sizeof (*ub)); ub->st_mode = S_IFSOCK; NET_LOCK_GIANT(); +#ifdef MAC + SOCK_LOCK(so); + error = mac_check_socket_stat(active_cred, so); + SOCK_UNLOCK(so); + if (error) { + NET_UNLOCK_GIANT(); + return (error); + } +#endif /* * If SBS_CANTRCVMORE is set, but there's still data left in the * receive buffer, the socket is still readable. * * XXXRW: perhaps should lock socket buffer so st_size result * is consistent. */ /* Unlocked read. */ if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 || so->so_rcv.sb_cc != 0) ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0) ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; ub->st_uid = so->so_cred->cr_uid; ub->st_gid = so->so_cred->cr_gid; error = (*so->so_proto->pr_usrreqs->pru_sense)(so, ub); NET_UNLOCK_GIANT(); return (error); } /* * API socket close on file pointer. We call soclose() to close the * socket (including initiating closing protocols). soclose() will * sorele() the file reference but the actual socket will not go away * until the socket's ref count hits 0. */ /* ARGSUSED */ int soo_close(fp, td) struct file *fp; struct thread *td; { int error = 0; struct socket *so; NET_LOCK_GIANT(); so = fp->f_data; fp->f_ops = &badfileops; fp->f_data = NULL; if (so) error = soclose(so); NET_UNLOCK_GIANT(); return (error); } Index: head/sys/kern/uipc_syscalls.c =================================================================== --- head/sys/kern/uipc_syscalls.c (revision 145166) +++ head/sys/kern/uipc_syscalls.c (revision 145167) @@ -1,2121 +1,2128 @@ /*- * Copyright (c) 1982, 1986, 1989, 1990, 1993 * The Regents of the University of California. All rights reserved. * * sendfile(2) and related extensions: * Copyright (c) 1998, David Greenman. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 */ #include __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include "opt_ktrace.h" #include "opt_mac.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KTRACE #include #endif #include #include #include #include #include #include static int sendit(struct thread *td, int s, struct msghdr *mp, int flags); static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp); static int accept1(struct thread *td, struct accept_args *uap, int compat); static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat); static int getsockname1(struct thread *td, struct getsockname_args *uap, int compat); static int getpeername1(struct thread *td, struct getpeername_args *uap, int compat); /* * NSFBUFS-related variables and associated sysctls */ int nsfbufs; int nsfbufspeak; int nsfbufsused; SYSCTL_DECL(_kern_ipc); SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufs, CTLFLAG_RDTUN, &nsfbufs, 0, "Maximum number of sendfile(2) sf_bufs available"); SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufspeak, CTLFLAG_RD, &nsfbufspeak, 0, "Number of sendfile(2) sf_bufs at peak usage"); SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0, "Number of sendfile(2) sf_bufs in use"); /* * Convert a user file descriptor to a kernel file entry. A reference on the * file entry is held upon returning. This is lighter weight than * fgetsock(), which bumps the socket reference drops the file reference * count instead, as this approach avoids several additional mutex operations * associated with the additional reference count. */ static int getsock(struct filedesc *fdp, int fd, struct file **fpp) { struct file *fp; int error; fp = NULL; if (fdp == NULL) error = EBADF; else { FILEDESC_LOCK_FAST(fdp); fp = fget_locked(fdp, fd); if (fp == NULL) error = EBADF; else if (fp->f_type != DTYPE_SOCKET) { fp = NULL; error = ENOTSOCK; } else { fhold(fp); error = 0; } FILEDESC_UNLOCK_FAST(fdp); } *fpp = fp; return (error); } /* * System call interface to the socket abstraction. */ #if defined(COMPAT_43) #define COMPAT_OLDSOCK #endif /* * MPSAFE */ int socket(td, uap) struct thread *td; register struct socket_args /* { int domain; int type; int protocol; } */ *uap; { struct filedesc *fdp; struct socket *so; struct file *fp; int fd, error; fdp = td->td_proc->p_fd; error = falloc(td, &fp, &fd); if (error) return (error); /* An extra reference on `fp' has been held for us by falloc(). */ NET_LOCK_GIANT(); error = socreate(uap->domain, &so, uap->type, uap->protocol, td->td_ucred, td); NET_UNLOCK_GIANT(); if (error) { fdclose(fdp, fp, fd, td); } else { FILEDESC_LOCK_FAST(fdp); fp->f_data = so; /* already has ref count */ fp->f_flag = FREAD|FWRITE; fp->f_ops = &socketops; fp->f_type = DTYPE_SOCKET; FILEDESC_UNLOCK_FAST(fdp); td->td_retval[0] = fd; } fdrop(fp, td); return (error); } /* * MPSAFE */ /* ARGSUSED */ int bind(td, uap) struct thread *td; register struct bind_args /* { int s; caddr_t name; int namelen; } */ *uap; { struct sockaddr *sa; int error; if ((error = getsockaddr(&sa, uap->name, uap->namelen)) != 0) return (error); return (kern_bind(td, uap->s, sa)); } int kern_bind(td, fd, sa) struct thread *td; int fd; struct sockaddr *sa; { struct socket *so; struct file *fp; int error; NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, fd, &fp); if (error) goto done2; so = fp->f_data; #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_bind(td->td_ucred, so, sa); SOCK_UNLOCK(so); if (error) goto done1; #endif error = sobind(so, sa, td); #ifdef MAC done1: #endif fdrop(fp, td); done2: NET_UNLOCK_GIANT(); FREE(sa, M_SONAME); return (error); } /* * MPSAFE */ /* ARGSUSED */ int listen(td, uap) struct thread *td; register struct listen_args /* { int s; int backlog; } */ *uap; { struct socket *so; struct file *fp; int error; NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, uap->s, &fp); if (error == 0) { so = fp->f_data; #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_listen(td->td_ucred, so); SOCK_UNLOCK(so); if (error) goto done; #endif error = solisten(so, uap->backlog, td); #ifdef MAC done: #endif fdrop(fp, td); } NET_UNLOCK_GIANT(); return(error); } /* * accept1() * MPSAFE */ static int accept1(td, uap, compat) struct thread *td; register struct accept_args /* { int s; struct sockaddr * __restrict name; socklen_t * __restrict anamelen; } */ *uap; int compat; { struct filedesc *fdp; struct file *nfp = NULL; struct sockaddr *sa = NULL; socklen_t namelen; int error; struct socket *head, *so; int fd; u_int fflag; pid_t pgid; int tmp; fdp = td->td_proc->p_fd; if (uap->name) { error = copyin(uap->anamelen, &namelen, sizeof (namelen)); if(error) return (error); if (namelen < 0) return (EINVAL); } NET_LOCK_GIANT(); error = fgetsock(td, uap->s, &head, &fflag); if (error) goto done2; if ((head->so_options & SO_ACCEPTCONN) == 0) { error = EINVAL; goto done; } +#ifdef MAC + SOCK_LOCK(head); + error = mac_check_socket_accept(td->td_ucred, head); + SOCK_UNLOCK(head); + if (error != 0) + goto done; +#endif error = falloc(td, &nfp, &fd); if (error) goto done; ACCEPT_LOCK(); if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) { ACCEPT_UNLOCK(); error = EWOULDBLOCK; goto noconnection; } while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) { if (head->so_rcv.sb_state & SBS_CANTRCVMORE) { head->so_error = ECONNABORTED; break; } error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH, "accept", 0); if (error) { ACCEPT_UNLOCK(); goto noconnection; } } if (head->so_error) { error = head->so_error; head->so_error = 0; ACCEPT_UNLOCK(); goto noconnection; } so = TAILQ_FIRST(&head->so_comp); KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP")); KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP")); /* * Before changing the flags on the socket, we have to bump the * reference count. Otherwise, if the protocol calls sofree(), * the socket will be released due to a zero refcount. */ SOCK_LOCK(so); /* soref() and so_state update */ soref(so); /* file descriptor reference */ TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; so->so_state |= (head->so_state & SS_NBIO); so->so_qstate &= ~SQ_COMP; so->so_head = NULL; SOCK_UNLOCK(so); ACCEPT_UNLOCK(); /* An extra reference on `nfp' has been held for us by falloc(). */ td->td_retval[0] = fd; /* connection has been removed from the listen queue */ KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0); pgid = fgetown(&head->so_sigio); if (pgid != 0) fsetown(pgid, &so->so_sigio); FILE_LOCK(nfp); nfp->f_data = so; /* nfp has ref count from falloc */ nfp->f_flag = fflag; nfp->f_ops = &socketops; nfp->f_type = DTYPE_SOCKET; FILE_UNLOCK(nfp); /* Sync socket nonblocking/async state with file flags */ tmp = fflag & FNONBLOCK; (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td); tmp = fflag & FASYNC; (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td); sa = 0; error = soaccept(so, &sa); if (error) { /* * return a namelen of zero for older code which might * ignore the return value from accept. */ if (uap->name != NULL) { namelen = 0; (void) copyout(&namelen, uap->anamelen, sizeof(*uap->anamelen)); } goto noconnection; } if (sa == NULL) { namelen = 0; if (uap->name) goto gotnoname; error = 0; goto done; } if (uap->name) { /* check sa_len before it is destroyed */ if (namelen > sa->sa_len) namelen = sa->sa_len; #ifdef COMPAT_OLDSOCK if (compat) ((struct osockaddr *)sa)->sa_family = sa->sa_family; #endif error = copyout(sa, uap->name, (u_int)namelen); if (!error) gotnoname: error = copyout(&namelen, uap->anamelen, sizeof (*uap->anamelen)); } noconnection: if (sa) FREE(sa, M_SONAME); /* * close the new descriptor, assuming someone hasn't ripped it * out from under us. */ if (error) fdclose(fdp, nfp, fd, td); /* * Release explicitly held references before returning. */ done: if (nfp != NULL) fdrop(nfp, td); fputsock(head); done2: NET_UNLOCK_GIANT(); return (error); } /* * MPSAFE (accept1() is MPSAFE) */ int accept(td, uap) struct thread *td; struct accept_args *uap; { return (accept1(td, uap, 0)); } #ifdef COMPAT_OLDSOCK /* * MPSAFE (accept1() is MPSAFE) */ int oaccept(td, uap) struct thread *td; struct accept_args *uap; { return (accept1(td, uap, 1)); } #endif /* COMPAT_OLDSOCK */ /* * MPSAFE */ /* ARGSUSED */ int connect(td, uap) struct thread *td; register struct connect_args /* { int s; caddr_t name; int namelen; } */ *uap; { struct sockaddr *sa; int error; error = getsockaddr(&sa, uap->name, uap->namelen); if (error) return (error); return (kern_connect(td, uap->s, sa)); } int kern_connect(td, fd, sa) struct thread *td; int fd; struct sockaddr *sa; { struct socket *so; struct file *fp; int error; int interrupted = 0; NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, fd, &fp); if (error) goto done2; so = fp->f_data; if (so->so_state & SS_ISCONNECTING) { error = EALREADY; goto done1; } #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_connect(td->td_ucred, so, sa); SOCK_UNLOCK(so); if (error) goto bad; #endif error = soconnect(so, sa, td); if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EINPROGRESS; goto done1; } SOCK_LOCK(so); while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH, "connec", 0); if (error) { if (error == EINTR || error == ERESTART) interrupted = 1; break; } } if (error == 0) { error = so->so_error; so->so_error = 0; } SOCK_UNLOCK(so); bad: if (!interrupted) so->so_state &= ~SS_ISCONNECTING; if (error == ERESTART) error = EINTR; done1: fdrop(fp, td); done2: NET_UNLOCK_GIANT(); FREE(sa, M_SONAME); return (error); } /* * MPSAFE */ int socketpair(td, uap) struct thread *td; register struct socketpair_args /* { int domain; int type; int protocol; int *rsv; } */ *uap; { register struct filedesc *fdp = td->td_proc->p_fd; struct file *fp1, *fp2; struct socket *so1, *so2; int fd, error, sv[2]; NET_LOCK_GIANT(); error = socreate(uap->domain, &so1, uap->type, uap->protocol, td->td_ucred, td); if (error) goto done2; error = socreate(uap->domain, &so2, uap->type, uap->protocol, td->td_ucred, td); if (error) goto free1; /* On success extra reference to `fp1' and 'fp2' is set by falloc. */ error = falloc(td, &fp1, &fd); if (error) goto free2; sv[0] = fd; fp1->f_data = so1; /* so1 already has ref count */ error = falloc(td, &fp2, &fd); if (error) goto free3; fp2->f_data = so2; /* so2 already has ref count */ sv[1] = fd; error = soconnect2(so1, so2); if (error) goto free4; if (uap->type == SOCK_DGRAM) { /* * Datagram socket connection is asymmetric. */ error = soconnect2(so2, so1); if (error) goto free4; } FILE_LOCK(fp1); fp1->f_flag = FREAD|FWRITE; fp1->f_ops = &socketops; fp1->f_type = DTYPE_SOCKET; FILE_UNLOCK(fp1); FILE_LOCK(fp2); fp2->f_flag = FREAD|FWRITE; fp2->f_ops = &socketops; fp2->f_type = DTYPE_SOCKET; FILE_UNLOCK(fp2); error = copyout(sv, uap->rsv, 2 * sizeof (int)); fdrop(fp1, td); fdrop(fp2, td); goto done2; free4: fdclose(fdp, fp2, sv[1], td); fdrop(fp2, td); free3: fdclose(fdp, fp1, sv[0], td); fdrop(fp1, td); free2: (void)soclose(so2); free1: (void)soclose(so1); done2: NET_UNLOCK_GIANT(); return (error); } static int sendit(td, s, mp, flags) register struct thread *td; int s; register struct msghdr *mp; int flags; { struct mbuf *control; struct sockaddr *to; int error; if (mp->msg_name != NULL) { error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); if (error) { to = NULL; goto bad; } mp->msg_name = to; } else { to = NULL; } if (mp->msg_control) { if (mp->msg_controllen < sizeof(struct cmsghdr) #ifdef COMPAT_OLDSOCK && mp->msg_flags != MSG_COMPAT #endif ) { error = EINVAL; goto bad; } error = sockargs(&control, mp->msg_control, mp->msg_controllen, MT_CONTROL); if (error) goto bad; #ifdef COMPAT_OLDSOCK if (mp->msg_flags == MSG_COMPAT) { register struct cmsghdr *cm; M_PREPEND(control, sizeof(*cm), M_TRYWAIT); if (control == 0) { error = ENOBUFS; goto bad; } else { cm = mtod(control, struct cmsghdr *); cm->cmsg_len = control->m_len; cm->cmsg_level = SOL_SOCKET; cm->cmsg_type = SCM_RIGHTS; } } #endif } else { control = NULL; } error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE); bad: if (to) FREE(to, M_SONAME); return (error); } int kern_sendit(td, s, mp, flags, control, segflg) struct thread *td; int s; struct msghdr *mp; int flags; struct mbuf *control; enum uio_seg segflg; { struct file *fp; struct uio auio; struct iovec *iov; struct socket *so; int i; int len, error; #ifdef KTRACE struct uio *ktruio = NULL; #endif NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, s, &fp); if (error) goto bad2; so = (struct socket *)fp->f_data; #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_send(td->td_ucred, so); SOCK_UNLOCK(so); if (error) goto bad; #endif auio.uio_iov = mp->msg_iov; auio.uio_iovcnt = mp->msg_iovlen; auio.uio_segflg = segflg; auio.uio_rw = UIO_WRITE; auio.uio_td = td; auio.uio_offset = 0; /* XXX */ auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { if ((auio.uio_resid += iov->iov_len) < 0) { error = EINVAL; goto bad; } } #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(&auio); #endif len = auio.uio_resid; error = so->so_proto->pr_usrreqs->pru_sosend(so, mp->msg_name, &auio, 0, control, flags, td); if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; /* Generation of SIGPIPE can be controlled per socket */ if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && !(flags & MSG_NOSIGNAL)) { PROC_LOCK(td->td_proc); psignal(td->td_proc, SIGPIPE); PROC_UNLOCK(td->td_proc); } } if (error == 0) td->td_retval[0] = len - auio.uio_resid; #ifdef KTRACE if (ktruio != NULL) { ktruio->uio_resid = td->td_retval[0]; ktrgenio(s, UIO_WRITE, ktruio, error); } #endif bad: fdrop(fp, td); bad2: NET_UNLOCK_GIANT(); return (error); } /* * MPSAFE */ int sendto(td, uap) struct thread *td; register struct sendto_args /* { int s; caddr_t buf; size_t len; int flags; caddr_t to; int tolen; } */ *uap; { struct msghdr msg; struct iovec aiov; int error; msg.msg_name = uap->to; msg.msg_namelen = uap->tolen; msg.msg_iov = &aiov; msg.msg_iovlen = 1; msg.msg_control = 0; #ifdef COMPAT_OLDSOCK msg.msg_flags = 0; #endif aiov.iov_base = uap->buf; aiov.iov_len = uap->len; error = sendit(td, uap->s, &msg, uap->flags); return (error); } #ifdef COMPAT_OLDSOCK /* * MPSAFE */ int osend(td, uap) struct thread *td; register struct osend_args /* { int s; caddr_t buf; int len; int flags; } */ *uap; { struct msghdr msg; struct iovec aiov; int error; msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = &aiov; msg.msg_iovlen = 1; aiov.iov_base = uap->buf; aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = 0; error = sendit(td, uap->s, &msg, uap->flags); return (error); } /* * MPSAFE */ int osendmsg(td, uap) struct thread *td; struct osendmsg_args /* { int s; caddr_t msg; int flags; } */ *uap; { struct msghdr msg; struct iovec *iov; int error; error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); if (error) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error); msg.msg_iov = iov; msg.msg_flags = MSG_COMPAT; error = sendit(td, uap->s, &msg, uap->flags); free(iov, M_IOV); return (error); } #endif /* * MPSAFE */ int sendmsg(td, uap) struct thread *td; struct sendmsg_args /* { int s; caddr_t msg; int flags; } */ *uap; { struct msghdr msg; struct iovec *iov; int error; error = copyin(uap->msg, &msg, sizeof (msg)); if (error) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error); msg.msg_iov = iov; #ifdef COMPAT_OLDSOCK msg.msg_flags = 0; #endif error = sendit(td, uap->s, &msg, uap->flags); free(iov, M_IOV); return (error); } static int recvit(td, s, mp, namelenp) struct thread *td; int s; struct msghdr *mp; void *namelenp; { struct uio auio; struct iovec *iov; int i; socklen_t len; int error; struct mbuf *m, *control = 0; caddr_t ctlbuf; struct file *fp; struct socket *so; struct sockaddr *fromsa = 0; #ifdef KTRACE struct uio *ktruio = NULL; #endif NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, s, &fp); if (error) { NET_UNLOCK_GIANT(); return (error); } so = fp->f_data; #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_receive(td->td_ucred, so); SOCK_UNLOCK(so); if (error) { fdrop(fp, td); NET_UNLOCK_GIANT(); return (error); } #endif auio.uio_iov = mp->msg_iov; auio.uio_iovcnt = mp->msg_iovlen; auio.uio_segflg = UIO_USERSPACE; auio.uio_rw = UIO_READ; auio.uio_td = td; auio.uio_offset = 0; /* XXX */ auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { if ((auio.uio_resid += iov->iov_len) < 0) { fdrop(fp, td); NET_UNLOCK_GIANT(); return (EINVAL); } } #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(&auio); #endif len = auio.uio_resid; error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, &mp->msg_flags); if (error) { if (auio.uio_resid != (int)len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; } #ifdef KTRACE if (ktruio != NULL) { ktruio->uio_resid = (int)len - auio.uio_resid; ktrgenio(s, UIO_READ, ktruio, error); } #endif if (error) goto out; td->td_retval[0] = (int)len - auio.uio_resid; if (mp->msg_name) { len = mp->msg_namelen; if (len <= 0 || fromsa == 0) len = 0; else { /* save sa_len before it is destroyed by MSG_COMPAT */ len = MIN(len, fromsa->sa_len); #ifdef COMPAT_OLDSOCK if (mp->msg_flags & MSG_COMPAT) ((struct osockaddr *)fromsa)->sa_family = fromsa->sa_family; #endif error = copyout(fromsa, mp->msg_name, (unsigned)len); if (error) goto out; } mp->msg_namelen = len; if (namelenp && (error = copyout(&len, namelenp, sizeof (socklen_t)))) { #ifdef COMPAT_OLDSOCK if (mp->msg_flags & MSG_COMPAT) error = 0; /* old recvfrom didn't check */ else #endif goto out; } } if (mp->msg_control) { #ifdef COMPAT_OLDSOCK /* * We assume that old recvmsg calls won't receive access * rights and other control info, esp. as control info * is always optional and those options didn't exist in 4.3. * If we receive rights, trim the cmsghdr; anything else * is tossed. */ if (control && mp->msg_flags & MSG_COMPAT) { if (mtod(control, struct cmsghdr *)->cmsg_level != SOL_SOCKET || mtod(control, struct cmsghdr *)->cmsg_type != SCM_RIGHTS) { mp->msg_controllen = 0; goto out; } control->m_len -= sizeof (struct cmsghdr); control->m_data += sizeof (struct cmsghdr); } #endif len = mp->msg_controllen; m = control; mp->msg_controllen = 0; ctlbuf = mp->msg_control; while (m && len > 0) { unsigned int tocopy; if (len >= m->m_len) tocopy = m->m_len; else { mp->msg_flags |= MSG_CTRUNC; tocopy = len; } if ((error = copyout(mtod(m, caddr_t), ctlbuf, tocopy)) != 0) goto out; ctlbuf += tocopy; len -= tocopy; m = m->m_next; } mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control; } out: fdrop(fp, td); NET_UNLOCK_GIANT(); if (fromsa) FREE(fromsa, M_SONAME); if (control) m_freem(control); return (error); } /* * MPSAFE */ int recvfrom(td, uap) struct thread *td; register struct recvfrom_args /* { int s; caddr_t buf; size_t len; int flags; struct sockaddr * __restrict from; socklen_t * __restrict fromlenaddr; } */ *uap; { struct msghdr msg; struct iovec aiov; int error; if (uap->fromlenaddr) { error = copyin(uap->fromlenaddr, &msg.msg_namelen, sizeof (msg.msg_namelen)); if (error) goto done2; } else { msg.msg_namelen = 0; } msg.msg_name = uap->from; msg.msg_iov = &aiov; msg.msg_iovlen = 1; aiov.iov_base = uap->buf; aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = uap->flags; error = recvit(td, uap->s, &msg, uap->fromlenaddr); done2: return(error); } #ifdef COMPAT_OLDSOCK /* * MPSAFE */ int orecvfrom(td, uap) struct thread *td; struct recvfrom_args *uap; { uap->flags |= MSG_COMPAT; return (recvfrom(td, uap)); } #endif #ifdef COMPAT_OLDSOCK /* * MPSAFE */ int orecv(td, uap) struct thread *td; register struct orecv_args /* { int s; caddr_t buf; int len; int flags; } */ *uap; { struct msghdr msg; struct iovec aiov; int error; msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = &aiov; msg.msg_iovlen = 1; aiov.iov_base = uap->buf; aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = uap->flags; error = recvit(td, uap->s, &msg, NULL); return (error); } /* * Old recvmsg. This code takes advantage of the fact that the old msghdr * overlays the new one, missing only the flags, and with the (old) access * rights where the control fields are now. * * MPSAFE */ int orecvmsg(td, uap) struct thread *td; struct orecvmsg_args /* { int s; struct omsghdr *msg; int flags; } */ *uap; { struct msghdr msg; struct iovec *iov; int error; error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); if (error) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error); msg.msg_flags = uap->flags | MSG_COMPAT; msg.msg_iov = iov; error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen); if (msg.msg_controllen && error == 0) error = copyout(&msg.msg_controllen, &uap->msg->msg_accrightslen, sizeof (int)); free(iov, M_IOV); return (error); } #endif /* * MPSAFE */ int recvmsg(td, uap) struct thread *td; struct recvmsg_args /* { int s; struct msghdr *msg; int flags; } */ *uap; { struct msghdr msg; struct iovec *uiov, *iov; int error; error = copyin(uap->msg, &msg, sizeof (msg)); if (error) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error); msg.msg_flags = uap->flags; #ifdef COMPAT_OLDSOCK msg.msg_flags &= ~MSG_COMPAT; #endif uiov = msg.msg_iov; msg.msg_iov = iov; error = recvit(td, uap->s, &msg, NULL); if (error == 0) { msg.msg_iov = uiov; error = copyout(&msg, uap->msg, sizeof(msg)); } free(iov, M_IOV); return (error); } /* * MPSAFE */ /* ARGSUSED */ int shutdown(td, uap) struct thread *td; register struct shutdown_args /* { int s; int how; } */ *uap; { struct socket *so; struct file *fp; int error; NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, uap->s, &fp); if (error == 0) { so = fp->f_data; error = soshutdown(so, uap->how); fdrop(fp, td); } NET_UNLOCK_GIANT(); return (error); } /* * MPSAFE */ /* ARGSUSED */ int setsockopt(td, uap) struct thread *td; register struct setsockopt_args /* { int s; int level; int name; caddr_t val; int valsize; } */ *uap; { return (kern_setsockopt(td, uap->s, uap->level, uap->name, uap->val, UIO_USERSPACE, uap->valsize)); } int kern_setsockopt(td, s, level, name, val, valseg, valsize) struct thread *td; int s; int level; int name; void *val; enum uio_seg valseg; socklen_t valsize; { int error; struct socket *so; struct file *fp; struct sockopt sopt; if (val == NULL && valsize != 0) return (EFAULT); if (valsize < 0) return (EINVAL); sopt.sopt_dir = SOPT_SET; sopt.sopt_level = level; sopt.sopt_name = name; sopt.sopt_val = val; sopt.sopt_valsize = valsize; switch (valseg) { case UIO_USERSPACE: sopt.sopt_td = td; break; case UIO_SYSSPACE: sopt.sopt_td = NULL; break; default: panic("kern_setsockopt called with bad valseg"); } NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, s, &fp); if (error == 0) { so = fp->f_data; error = sosetopt(so, &sopt); fdrop(fp, td); } NET_UNLOCK_GIANT(); return(error); } /* * MPSAFE */ /* ARGSUSED */ int getsockopt(td, uap) struct thread *td; register struct getsockopt_args /* { int s; int level; int name; void * __restrict val; socklen_t * __restrict avalsize; } */ *uap; { socklen_t valsize; int error; if (uap->val) { error = copyin(uap->avalsize, &valsize, sizeof (valsize)); if (error) return (error); } error = kern_getsockopt(td, uap->s, uap->level, uap->name, uap->val, UIO_USERSPACE, &valsize); if (error == 0) error = copyout(&valsize, uap->avalsize, sizeof (valsize)); return (error); } /* * Kernel version of getsockopt. * optval can be a userland or userspace. optlen is always a kernel pointer. */ int kern_getsockopt(td, s, level, name, val, valseg, valsize) struct thread *td; int s; int level; int name; void *val; enum uio_seg valseg; socklen_t *valsize; { int error; struct socket *so; struct file *fp; struct sockopt sopt; if (val == NULL) *valsize = 0; if (*valsize < 0) return (EINVAL); sopt.sopt_dir = SOPT_GET; sopt.sopt_level = level; sopt.sopt_name = name; sopt.sopt_val = val; sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */ switch (valseg) { case UIO_USERSPACE: sopt.sopt_td = td; break; case UIO_SYSSPACE: sopt.sopt_td = NULL; break; default: panic("kern_getsockopt called with bad valseg"); } NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, s, &fp); if (error == 0) { so = fp->f_data; error = sogetopt(so, &sopt); *valsize = sopt.sopt_valsize; fdrop(fp, td); } NET_UNLOCK_GIANT(); return (error); } /* * getsockname1() - Get socket name. * * MPSAFE */ /* ARGSUSED */ static int getsockname1(td, uap, compat) struct thread *td; register struct getsockname_args /* { int fdes; struct sockaddr * __restrict asa; socklen_t * __restrict alen; } */ *uap; int compat; { struct socket *so; struct sockaddr *sa; struct file *fp; socklen_t len; int error; NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, uap->fdes, &fp); if (error) goto done2; so = fp->f_data; error = copyin(uap->alen, &len, sizeof (len)); if (error) goto done1; if (len < 0) { error = EINVAL; goto done1; } sa = 0; error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa); if (error) goto bad; if (sa == 0) { len = 0; goto gotnothing; } len = MIN(len, sa->sa_len); #ifdef COMPAT_OLDSOCK if (compat) ((struct osockaddr *)sa)->sa_family = sa->sa_family; #endif error = copyout(sa, uap->asa, (u_int)len); if (error == 0) gotnothing: error = copyout(&len, uap->alen, sizeof (len)); bad: if (sa) FREE(sa, M_SONAME); done1: fdrop(fp, td); done2: NET_UNLOCK_GIANT(); return (error); } /* * MPSAFE */ int getsockname(td, uap) struct thread *td; struct getsockname_args *uap; { return (getsockname1(td, uap, 0)); } #ifdef COMPAT_OLDSOCK /* * MPSAFE */ int ogetsockname(td, uap) struct thread *td; struct getsockname_args *uap; { return (getsockname1(td, uap, 1)); } #endif /* COMPAT_OLDSOCK */ /* * getpeername1() - Get name of peer for connected socket. * * MPSAFE */ /* ARGSUSED */ static int getpeername1(td, uap, compat) struct thread *td; register struct getpeername_args /* { int fdes; struct sockaddr * __restrict asa; socklen_t * __restrict alen; } */ *uap; int compat; { struct socket *so; struct sockaddr *sa; struct file *fp; socklen_t len; int error; NET_LOCK_GIANT(); error = getsock(td->td_proc->p_fd, uap->fdes, &fp); if (error) goto done2; so = fp->f_data; if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { error = ENOTCONN; goto done1; } error = copyin(uap->alen, &len, sizeof (len)); if (error) goto done1; if (len < 0) { error = EINVAL; goto done1; } sa = 0; error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa); if (error) goto bad; if (sa == 0) { len = 0; goto gotnothing; } len = MIN(len, sa->sa_len); #ifdef COMPAT_OLDSOCK if (compat) ((struct osockaddr *)sa)->sa_family = sa->sa_family; #endif error = copyout(sa, uap->asa, (u_int)len); if (error) goto bad; gotnothing: error = copyout(&len, uap->alen, sizeof (len)); bad: if (sa) FREE(sa, M_SONAME); done1: fdrop(fp, td); done2: NET_UNLOCK_GIANT(); return (error); } /* * MPSAFE */ int getpeername(td, uap) struct thread *td; struct getpeername_args *uap; { return (getpeername1(td, uap, 0)); } #ifdef COMPAT_OLDSOCK /* * MPSAFE */ int ogetpeername(td, uap) struct thread *td; struct ogetpeername_args *uap; { /* XXX uap should have type `getpeername_args *' to begin with. */ return (getpeername1(td, (struct getpeername_args *)uap, 1)); } #endif /* COMPAT_OLDSOCK */ int sockargs(mp, buf, buflen, type) struct mbuf **mp; caddr_t buf; int buflen, type; { register struct sockaddr *sa; register struct mbuf *m; int error; if ((u_int)buflen > MLEN) { #ifdef COMPAT_OLDSOCK if (type == MT_SONAME && (u_int)buflen <= 112) buflen = MLEN; /* unix domain compat. hack */ else #endif if ((u_int)buflen > MCLBYTES) return (EINVAL); } m = m_get(M_TRYWAIT, type); if (m == NULL) return (ENOBUFS); if ((u_int)buflen > MLEN) { MCLGET(m, M_TRYWAIT); if ((m->m_flags & M_EXT) == 0) { m_free(m); return (ENOBUFS); } } m->m_len = buflen; error = copyin(buf, mtod(m, caddr_t), (u_int)buflen); if (error) (void) m_free(m); else { *mp = m; if (type == MT_SONAME) { sa = mtod(m, struct sockaddr *); #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN if (sa->sa_family == 0 && sa->sa_len < AF_MAX) sa->sa_family = sa->sa_len; #endif sa->sa_len = buflen; } } return (error); } int getsockaddr(namp, uaddr, len) struct sockaddr **namp; caddr_t uaddr; size_t len; { struct sockaddr *sa; int error; if (len > SOCK_MAXADDRLEN) return (ENAMETOOLONG); if (len < offsetof(struct sockaddr, sa_data[0])) return (EINVAL); MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK); error = copyin(uaddr, sa, len); if (error) { FREE(sa, M_SONAME); } else { #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN if (sa->sa_family == 0 && sa->sa_len < AF_MAX) sa->sa_family = sa->sa_len; #endif sa->sa_len = len; *namp = sa; } return (error); } /* * Detach mapped page and release resources back to the system. */ void sf_buf_mext(void *addr, void *args) { vm_page_t m; m = sf_buf_page(args); sf_buf_free(args); vm_page_lock_queues(); vm_page_unwire(m, 0); /* * Check for the object going away on us. This can * happen since we don't hold a reference to it. * If so, we're responsible for freeing the page. */ if (m->wire_count == 0 && m->object == NULL) vm_page_free(m); vm_page_unlock_queues(); } /* * sendfile(2) * * MPSAFE * * int sendfile(int fd, int s, off_t offset, size_t nbytes, * struct sf_hdtr *hdtr, off_t *sbytes, int flags) * * Send a file specified by 'fd' and starting at 'offset' to a socket * specified by 's'. Send only 'nbytes' of the file or until EOF if * nbytes == 0. Optionally add a header and/or trailer to the socket * output. If specified, write the total number of bytes sent into *sbytes. * */ int sendfile(struct thread *td, struct sendfile_args *uap) { return (do_sendfile(td, uap, 0)); } #ifdef COMPAT_FREEBSD4 int freebsd4_sendfile(struct thread *td, struct freebsd4_sendfile_args *uap) { struct sendfile_args args; args.fd = uap->fd; args.s = uap->s; args.offset = uap->offset; args.nbytes = uap->nbytes; args.hdtr = uap->hdtr; args.sbytes = uap->sbytes; args.flags = uap->flags; return (do_sendfile(td, &args, 1)); } #endif /* COMPAT_FREEBSD4 */ static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) { struct vnode *vp; struct vm_object *obj; struct socket *so = NULL; struct mbuf *m, *m_header = NULL; struct sf_buf *sf; struct vm_page *pg; struct writev_args nuap; struct sf_hdtr hdtr; struct uio *hdr_uio = NULL; off_t off, xfsize, hdtr_size, sbytes = 0; int error, headersize = 0, headersent = 0; mtx_lock(&Giant); hdtr_size = 0; /* * The descriptor must be a regular file and have a backing VM object. */ if ((error = fgetvp_read(td, uap->fd, &vp)) != 0) goto done; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); obj = vp->v_object; VOP_UNLOCK(vp, 0, td); if (obj == NULL) { error = EINVAL; goto done; } if ((error = fgetsock(td, uap->s, &so, NULL)) != 0) goto done; if (so->so_type != SOCK_STREAM) { error = EINVAL; goto done; } if ((so->so_state & SS_ISCONNECTED) == 0) { error = ENOTCONN; goto done; } if (uap->offset < 0) { error = EINVAL; goto done; } #ifdef MAC SOCK_LOCK(so); error = mac_check_socket_send(td->td_ucred, so); SOCK_UNLOCK(so); if (error) goto done; #endif /* * If specified, get the pointer to the sf_hdtr struct for * any headers/trailers. */ if (uap->hdtr != NULL) { error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); if (error) goto done; /* * Send any headers. */ if (hdtr.headers != NULL) { error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); if (error) goto done; hdr_uio->uio_td = td; hdr_uio->uio_rw = UIO_WRITE; if (hdr_uio->uio_resid > 0) { m_header = m_uiotombuf(hdr_uio, M_DONTWAIT, 0); if (m_header == NULL) goto done; headersize = m_header->m_pkthdr.len; if (compat) sbytes += headersize; } } } /* * Protect against multiple writers to the socket. */ SOCKBUF_LOCK(&so->so_snd); (void) sblock(&so->so_snd, M_WAITOK); SOCKBUF_UNLOCK(&so->so_snd); /* * Loop through the pages in the file, starting with the requested * offset. Get a file page (do I/O if necessary), map the file page * into an sf_buf, attach an mbuf header to the sf_buf, and queue * it on the socket. */ for (off = uap->offset; ; off += xfsize, sbytes += xfsize) { vm_pindex_t pindex; vm_offset_t pgoff; pindex = OFF_TO_IDX(off); VM_OBJECT_LOCK(obj); retry_lookup: /* * Calculate the amount to transfer. Not to exceed a page, * the EOF, or the passed in nbytes. */ xfsize = obj->un_pager.vnp.vnp_size - off; VM_OBJECT_UNLOCK(obj); if (xfsize > PAGE_SIZE) xfsize = PAGE_SIZE; pgoff = (vm_offset_t)(off & PAGE_MASK); if (PAGE_SIZE - pgoff < xfsize) xfsize = PAGE_SIZE - pgoff; if (uap->nbytes && xfsize > (uap->nbytes - sbytes)) xfsize = uap->nbytes - sbytes; if (xfsize <= 0) { if (m_header != NULL) { m = m_header; m_header = NULL; SOCKBUF_LOCK(&so->so_snd); goto retry_space; } else break; } /* * Optimize the non-blocking case by looking at the socket space * before going to the extra work of constituting the sf_buf. */ SOCKBUF_LOCK(&so->so_snd); if ((so->so_state & SS_NBIO) && sbspace(&so->so_snd) <= 0) { if (so->so_snd.sb_state & SBS_CANTSENDMORE) error = EPIPE; else error = EAGAIN; sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); goto done; } SOCKBUF_UNLOCK(&so->so_snd); VM_OBJECT_LOCK(obj); /* * Attempt to look up the page. * * Allocate if not found * * Wait and loop if busy. */ pg = vm_page_lookup(obj, pindex); if (pg == NULL) { pg = vm_page_alloc(obj, pindex, VM_ALLOC_NOBUSY | VM_ALLOC_NORMAL | VM_ALLOC_WIRED); if (pg == NULL) { VM_OBJECT_UNLOCK(obj); VM_WAIT; VM_OBJECT_LOCK(obj); goto retry_lookup; } vm_page_lock_queues(); } else { vm_page_lock_queues(); if (vm_page_sleep_if_busy(pg, TRUE, "sfpbsy")) goto retry_lookup; /* * Wire the page so it does not get ripped out from * under us. */ vm_page_wire(pg); } /* * If page is not valid for what we need, initiate I/O */ if (pg->valid && vm_page_is_valid(pg, pgoff, xfsize)) { VM_OBJECT_UNLOCK(obj); } else if (uap->flags & SF_NODISKIO) { error = EBUSY; } else { int bsize, resid; /* * Ensure that our page is still around when the I/O * completes. */ vm_page_io_start(pg); vm_page_unlock_queues(); VM_OBJECT_UNLOCK(obj); /* * Get the page from backing store. */ bsize = vp->v_mount->mnt_stat.f_iosize; vn_lock(vp, LK_SHARED | LK_RETRY, td); /* * XXXMAC: Because we don't have fp->f_cred here, * we pass in NOCRED. This is probably wrong, but * is consistent with our original implementation. */ error = vn_rdwr(UIO_READ, vp, NULL, MAXBSIZE, trunc_page(off), UIO_NOCOPY, IO_NODELOCKED | IO_VMIO | ((MAXBSIZE / bsize) << IO_SEQSHIFT), td->td_ucred, NOCRED, &resid, td); VOP_UNLOCK(vp, 0, td); VM_OBJECT_LOCK(obj); vm_page_lock_queues(); vm_page_io_finish(pg); if (!error) VM_OBJECT_UNLOCK(obj); mbstat.sf_iocnt++; } if (error) { vm_page_unwire(pg, 0); /* * See if anyone else might know about this page. * If not and it is not valid, then free it. */ if (pg->wire_count == 0 && pg->valid == 0 && pg->busy == 0 && !(pg->flags & PG_BUSY) && pg->hold_count == 0) { vm_page_free(pg); } vm_page_unlock_queues(); VM_OBJECT_UNLOCK(obj); SOCKBUF_LOCK(&so->so_snd); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); goto done; } vm_page_unlock_queues(); /* * Get a sendfile buf. We usually wait as long as necessary, * but this wait can be interrupted. */ if ((sf = sf_buf_alloc(pg, SFB_CATCH)) == NULL) { mbstat.sf_allocfail++; vm_page_lock_queues(); vm_page_unwire(pg, 0); if (pg->wire_count == 0 && pg->object == NULL) vm_page_free(pg); vm_page_unlock_queues(); SOCKBUF_LOCK(&so->so_snd); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); error = EINTR; goto done; } /* * Get an mbuf header and set it up as having external storage. */ if (m_header) MGET(m, M_TRYWAIT, MT_DATA); else MGETHDR(m, M_TRYWAIT, MT_DATA); if (m == NULL) { error = ENOBUFS; sf_buf_mext((void *)sf_buf_kva(sf), sf); SOCKBUF_LOCK(&so->so_snd); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); goto done; } /* * Setup external storage for mbuf. */ MEXTADD(m, sf_buf_kva(sf), PAGE_SIZE, sf_buf_mext, sf, M_RDONLY, EXT_SFBUF); m->m_data = (char *)sf_buf_kva(sf) + pgoff; m->m_pkthdr.len = m->m_len = xfsize; if (m_header) { m_cat(m_header, m); m = m_header; m_header = NULL; m_fixhdr(m); } /* * Add the buffer to the socket buffer chain. */ SOCKBUF_LOCK(&so->so_snd); retry_space: /* * Make sure that the socket is still able to take more data. * CANTSENDMORE being true usually means that the connection * was closed. so_error is true when an error was sensed after * a previous send. * The state is checked after the page mapping and buffer * allocation above since those operations may block and make * any socket checks stale. From this point forward, nothing * blocks before the pru_send (or more accurately, any blocking * results in a loop back to here to re-check). */ SOCKBUF_LOCK_ASSERT(&so->so_snd); if ((so->so_snd.sb_state & SBS_CANTSENDMORE) || so->so_error) { if (so->so_snd.sb_state & SBS_CANTSENDMORE) { error = EPIPE; } else { error = so->so_error; so->so_error = 0; } m_freem(m); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); goto done; } /* * Wait for socket space to become available. We do this just * after checking the connection state above in order to avoid * a race condition with sbwait(). */ if (sbspace(&so->so_snd) < so->so_snd.sb_lowat) { if (so->so_state & SS_NBIO) { m_freem(m); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); error = EAGAIN; goto done; } error = sbwait(&so->so_snd); /* * An error from sbwait usually indicates that we've * been interrupted by a signal. If we've sent anything * then return bytes sent, otherwise return the error. */ if (error) { m_freem(m); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); goto done; } goto retry_space; } SOCKBUF_UNLOCK(&so->so_snd); error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, 0, 0, td); if (error) { SOCKBUF_LOCK(&so->so_snd); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); goto done; } headersent = 1; } SOCKBUF_LOCK(&so->so_snd); sbunlock(&so->so_snd); SOCKBUF_UNLOCK(&so->so_snd); /* * Send trailers. Wimp out and use writev(2). */ if (uap->hdtr != NULL && hdtr.trailers != NULL) { nuap.fd = uap->s; nuap.iovp = hdtr.trailers; nuap.iovcnt = hdtr.trl_cnt; error = writev(td, &nuap); if (error) goto done; if (compat) sbytes += td->td_retval[0]; else hdtr_size += td->td_retval[0]; } done: if (headersent) { if (!compat) hdtr_size += headersize; } else { if (compat) sbytes -= headersize; } /* * If there was no error we have to clear td->td_retval[0] * because it may have been set by writev. */ if (error == 0) { td->td_retval[0] = 0; } if (uap->sbytes != NULL) { if (!compat) sbytes += hdtr_size; copyout(&sbytes, uap->sbytes, sizeof(off_t)); } if (vp) vrele(vp); if (so) fputsock(so); if (hdr_uio != NULL) free(hdr_uio, M_IOV); if (m_header) m_freem(m_header); mtx_unlock(&Giant); if (error == ERESTART) error = EINTR; return (error); } Index: head/sys/security/mac/mac_framework.h =================================================================== --- head/sys/security/mac/mac_framework.h (revision 145166) +++ head/sys/security/mac/mac_framework.h (revision 145167) @@ -1,450 +1,454 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson - * Copyright (c) 2001-2003 Networks Associates Technology, Inc. + * Copyright (c) 2001-2005 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * This software was developed for the FreeBSD Project in part by Network * Associates Laboratories, the Security Research Division of Network * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), * as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Userland/kernel interface for Mandatory Access Control. * * The POSIX.1e implementation page may be reached at: * http://www.trustedbsd.org/ */ + #ifndef _SYS_MAC_H_ #define _SYS_MAC_H_ #include #ifndef _POSIX_MAC #define _POSIX_MAC #endif /* * MAC framework-related constants and limits. */ #define MAC_MAX_POLICY_NAME 32 #define MAC_MAX_LABEL_ELEMENT_NAME 32 #define MAC_MAX_LABEL_ELEMENT_DATA 4096 #define MAC_MAX_LABEL_BUF_LEN 8192 struct mac { size_t m_buflen; char *m_string; }; typedef struct mac *mac_t; #ifndef _KERNEL /* * Location of the userland MAC framework configuration file. mac.conf * binds policy names to shared libraries that understand those policies, * as well as setting defaults for MAC-aware applications. */ #define MAC_CONFFILE "/etc/mac.conf" /* * Extended non-POSIX.1e interfaces that offer additional services * available from the userland and kernel MAC frameworks. */ __BEGIN_DECLS int mac_execve(char *fname, char **argv, char **envv, mac_t _label); int mac_free(mac_t _label); int mac_from_text(mac_t *_label, const char *_text); int mac_get_fd(int _fd, mac_t _label); int mac_get_file(const char *_path, mac_t _label); int mac_get_link(const char *_path, mac_t _label); int mac_get_peer(int _fd, mac_t _label); int mac_get_pid(pid_t _pid, mac_t _label); int mac_get_proc(mac_t _label); int mac_is_present(const char *_policyname); int mac_prepare(mac_t *_label, const char *_elements); int mac_prepare_file_label(mac_t *_label); int mac_prepare_ifnet_label(mac_t *_label); int mac_prepare_process_label(mac_t *_label); int mac_prepare_type(mac_t *_label, const char *_type); int mac_set_fd(int _fildes, const mac_t _label); int mac_set_file(const char *_path, mac_t _label); int mac_set_link(const char *_path, mac_t _label); int mac_set_proc(const mac_t _label); int mac_syscall(const char *_policyname, int _call, void *_arg); int mac_to_text(mac_t mac, char **_text); __END_DECLS #else /* _KERNEL */ /* * Kernel functions to manage and evaluate labels. */ struct bpf_d; struct cdev; struct componentname; struct devfs_dirent; struct ifnet; struct ifreq; struct inpcb; struct image_params; struct inpcb; struct ipq; struct m_tag; struct mbuf; struct mount; struct msg; struct msqid_kernel; struct proc; struct semid_kernel; struct shmid_kernel; struct sockaddr; struct socket; struct sysctl_oid; struct sysctl_req; struct pipepair; struct thread; struct timespec; struct ucred; struct uio; struct vattr; struct vnode; #include /* XXX acl_type_t */ struct vop_setlabel_args; /* * Label operations. */ void mac_init_bpfdesc(struct bpf_d *); void mac_init_cred(struct ucred *); void mac_init_devfsdirent(struct devfs_dirent *); void mac_init_ifnet(struct ifnet *); int mac_init_inpcb(struct inpcb *, int flag); void mac_init_sysv_msgmsg(struct msg *); void mac_init_sysv_msgqueue(struct msqid_kernel*); void mac_init_sysv_sema(struct semid_kernel*); void mac_init_sysv_shm(struct shmid_kernel*); int mac_init_ipq(struct ipq *, int flag); int mac_init_socket(struct socket *, int flag); void mac_init_pipe(struct pipepair *); int mac_init_mbuf(struct mbuf *mbuf, int flag); int mac_init_mbuf_tag(struct m_tag *, int flag); void mac_init_mount(struct mount *); void mac_init_proc(struct proc *); void mac_init_vnode(struct vnode *); void mac_copy_mbuf_tag(struct m_tag *, struct m_tag *); void mac_copy_vnode_label(struct label *, struct label *label); void mac_destroy_bpfdesc(struct bpf_d *); void mac_destroy_cred(struct ucred *); void mac_destroy_devfsdirent(struct devfs_dirent *); void mac_destroy_ifnet(struct ifnet *); void mac_destroy_inpcb(struct inpcb *); void mac_destroy_sysv_msgmsg(struct msg *); void mac_destroy_sysv_msgqueue(struct msqid_kernel *); void mac_destroy_sysv_sema(struct semid_kernel *); void mac_destroy_sysv_shm(struct shmid_kernel *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); void mac_destroy_pipe(struct pipepair *); void mac_destroy_proc(struct proc *); void mac_destroy_mbuf_tag(struct m_tag *); void mac_destroy_mount(struct mount *); void mac_destroy_vnode(struct vnode *); struct label *mac_cred_label_alloc(void); void mac_cred_label_free(struct label *label); struct label *mac_vnode_label_alloc(void); void mac_vnode_label_free(struct label *label); /* * Labeling event operations: file system objects, and things that * look a lot like file system objects. */ void mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, struct vnode *vp); int mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp); void mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp); void mac_create_devfs_device(struct mount *mp, struct cdev *dev, struct devfs_dirent *de); void mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *de); void mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct devfs_dirent *de); int mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); void mac_create_mount(struct ucred *cred, struct mount *mp); void mac_create_root_mount(struct ucred *cred, struct mount *mp); void mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel); void mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, struct vnode *vp); /* * Labeling event operations: IPC objects. */ void mac_create_mbuf_from_socket(struct socket *so, struct mbuf *m); void mac_create_socket(struct ucred *cred, struct socket *socket); void mac_create_socket_from_socket(struct socket *oldsocket, struct socket *newsocket); void mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket); void mac_set_socket_peer_from_socket(struct socket *oldsocket, struct socket *newsocket); void mac_create_pipe(struct ucred *cred, struct pipepair *pp); /* * Labeling event operations: System V IPC primitives */ void mac_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, struct msg *msgptr); void mac_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr); void mac_create_sysv_sema(struct ucred *cred, struct semid_kernel *semakptr); void mac_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr); /* * Labeling event operations: network objects. */ void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); void mac_create_ifnet(struct ifnet *ifp); void mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp); void mac_create_ipq(struct mbuf *fragment, struct ipq *ipq); void mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram); void mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment); void mac_create_mbuf_from_inpcb(struct inpcb *inp, struct mbuf *m); void mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf); void mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *m); void mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *m); void mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *m); void mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, struct mbuf *newmbuf); void mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf); int mac_fragment_match(struct mbuf *fragment, struct ipq *ipq); void mac_reflect_mbuf_icmp(struct mbuf *m); void mac_reflect_mbuf_tcp(struct mbuf *m); void mac_update_ipq(struct mbuf *fragment, struct ipq *ipq); void mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp); /* * Labeling event operations: processes. */ void mac_copy_cred(struct ucred *cr1, struct ucred *cr2); int mac_execve_enter(struct image_params *imgp, struct mac *mac_p); void mac_execve_exit(struct image_params *imgp); void mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, struct label *interpvnodelabel, struct image_params *imgp); int mac_execve_will_transition(struct ucred *old, struct vnode *vp, struct label *interpvnodelabel, struct image_params *imgp); void mac_create_proc0(struct ucred *cred); void mac_create_proc1(struct ucred *cred); void mac_thread_userret(struct thread *td); /* * Label cleanup operation: This is the inverse complement for the * mac_create and associate type of hooks. This hook lets the policy * module(s) perform a cleanup/flushing operation on the label * associated with the objects, without freeing up the space allocated. * This hook is useful in cases where it is desirable to remove any * labeling reference when recycling any object to a pool. This hook * does not replace the mac_destroy hooks. */ void mac_cleanup_sysv_msgmsg(struct msg *msgptr); void mac_cleanup_sysv_msgqueue(struct msqid_kernel *msqkptr); void mac_cleanup_sysv_sema(struct semid_kernel *semakptr); void mac_cleanup_sysv_shm(struct shmid_kernel *shmsegptr); /* Access control checks. */ int mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet); int mac_check_cred_visible(struct ucred *u1, struct ucred *u2); int mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *m); int mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m); int mac_check_sysv_msgmsq(struct ucred *cred, struct msg *msgptr, struct msqid_kernel *msqkptr); int mac_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr); int mac_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr); int mac_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr); int mac_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr); int mac_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr); int mac_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, int cmd); int mac_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, int cmd); int mac_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr); int mac_check_sysv_semop(struct ucred *cred,struct semid_kernel *semakptr, size_t accesstype); int mac_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, int shmflg); int mac_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, int cmd); int mac_check_sysv_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr); int mac_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, int shmflg); int mac_check_kenv_dump(struct ucred *cred); int mac_check_kenv_get(struct ucred *cred, char *name); int mac_check_kenv_set(struct ucred *cred, char *name, char *value); int mac_check_kenv_unset(struct ucred *cred, char *name); int mac_check_kld_load(struct ucred *cred, struct vnode *vp); int mac_check_kld_stat(struct ucred *cred); int mac_check_kld_unload(struct ucred *cred); int mac_check_mount_stat(struct ucred *cred, struct mount *mp); int mac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, unsigned long cmd, void *data); int mac_check_pipe_poll(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_read(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_stat(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_write(struct ucred *cred, struct pipepair *pp); int mac_check_proc_debug(struct ucred *cred, struct proc *proc); int mac_check_proc_sched(struct ucred *cred, struct proc *proc); int mac_check_proc_setuid(struct proc *proc, struct ucred *cred, uid_t uid); int mac_check_proc_seteuid(struct proc *proc, struct ucred *cred, uid_t euid); int mac_check_proc_setgid(struct proc *proc, struct ucred *cred, gid_t gid); int mac_check_proc_setegid(struct proc *proc, struct ucred *cred, gid_t egid); int mac_check_proc_setgroups(struct proc *proc, struct ucred *cred, int ngroups, gid_t *gidset); int mac_check_proc_setreuid(struct proc *proc, struct ucred *cred, uid_t ruid, uid_t euid); int mac_check_proc_setregid(struct proc *proc, struct ucred *cred, gid_t rgid, gid_t egid); int mac_check_proc_setresuid(struct proc *proc, struct ucred *cred, uid_t ruid, uid_t euid, uid_t suid); int mac_check_proc_setresgid(struct proc *proc, struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid); int mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum); +int mac_check_socket_accept(struct ucred *cred, struct socket *so); int mac_check_socket_bind(struct ucred *cred, struct socket *so, struct sockaddr *sockaddr); int mac_check_socket_connect(struct ucred *cred, struct socket *so, struct sockaddr *sockaddr); int mac_check_socket_deliver(struct socket *so, struct mbuf *m); int mac_check_socket_listen(struct ucred *cred, struct socket *so); +int mac_check_socket_poll(struct ucred *cred, struct socket *so); int mac_check_socket_receive(struct ucred *cred, struct socket *so); int mac_check_socket_send(struct ucred *cred, struct socket *so); +int mac_check_socket_stat(struct ucred *cred, struct socket *so); int mac_check_socket_visible(struct ucred *cred, struct socket *so); int mac_check_sysarch_ioperm(struct ucred *cred); int mac_check_system_acct(struct ucred *cred, struct vnode *vp); int mac_check_system_nfsd(struct ucred *cred); int mac_check_system_reboot(struct ucred *cred, int howto); int mac_check_system_settime(struct ucred *cred); int mac_check_system_swapon(struct ucred *cred, struct vnode *vp); int mac_check_system_swapoff(struct ucred *cred, struct vnode *vp); int mac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); int mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode); int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp); int mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp); int mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, struct componentname *cnp, struct vattr *vap); int mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, acl_type_t type); int mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name); int mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, struct image_params *imgp); int mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type); int mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name, struct uio *uio); int mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, int attrnamespace); int mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct componentname *cnp); int mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot, int flags); int mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot); int mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode); int mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_check_vnode_readdir(struct ucred *cred, struct vnode *vp); int mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp); int mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, struct vnode *vp, int samedir, struct componentname *cnp); int mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp); int mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, struct acl *acl); int mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name, struct uio *uio); int mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags); int mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode); int mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, gid_t gid); int mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, struct timespec atime, struct timespec mtime); int mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_getsockopt_label(struct ucred *cred, struct socket *so, struct mac *extmac); int mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, struct mac *extmac); int mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifnet); int mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifnet); int mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *extmac); int mac_pipe_label_set(struct ucred *cred, struct pipepair *pp, struct label *label); void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred); /* * Calls to help various file systems implement labeling functionality * using their existing EA implementation. */ int vop_stdsetlabel_ea(struct vop_setlabel_args *ap); #endif /* !_KERNEL */ #endif /* !_SYS_MAC_H_ */ Index: head/sys/security/mac/mac_policy.h =================================================================== --- head/sys/security/mac/mac_policy.h (revision 145166) +++ head/sys/security/mac/mac_policy.h (revision 145167) @@ -1,596 +1,602 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson - * Copyright (c) 2001-2004 Networks Associates Technology, Inc. + * Copyright (c) 2001-2005 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * This software was developed for the FreeBSD Project in part by Network * Associates Laboratories, the Security Research Division of Network * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), * as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Kernel interface for MAC policy modules. */ #ifndef _SYS_MAC_POLICY_H_ #define _SYS_MAC_POLICY_H_ /*- * Pluggable access control policy definition structure. * * List of operations that are performed as part of the implementation * of a MAC policy. Policy implementors declare operations with a * mac_policy_ops structure, and using the MAC_POLICY_SET() macro. * If an entry point is not declared, then then the policy will be ignored * during evaluation of that event or check. * * Operations are sorted first by general class of operation, then * alphabetically. */ struct acl; struct bpf_d; struct componentname; struct devfs_dirent; struct ifnet; struct image_params; struct inpcb; struct ipq; struct label; struct mac_policy_conf; struct mbuf; struct mount; struct msqid_kernel; struct pipepair; struct proc; struct sbuf; struct semid_kernel; struct shmid_kernel; struct sockaddr; struct socket; struct sysctl_oid; struct sysctl_req; struct thread; struct ucred; struct uio; struct vattr; struct vnode; struct mac_policy_ops { /* * Policy module operations. */ void (*mpo_destroy)(struct mac_policy_conf *mpc); void (*mpo_init)(struct mac_policy_conf *mpc); /* * General policy-directed security system call so that policies may * implement new services without reserving explicit system call * numbers. */ int (*mpo_syscall)(struct thread *td, int call, void *arg); /* * Label operations. Initialize label storage, destroy label * storage, recycle for re-use without init/destroy, copy a label to * initialized storage, and externalize/internalize from/to * initialized storage. */ void (*mpo_init_bpfdesc_label)(struct label *label); void (*mpo_init_cred_label)(struct label *label); void (*mpo_init_devfsdirent_label)(struct label *label); void (*mpo_init_ifnet_label)(struct label *label); int (*mpo_init_inpcb_label)(struct label *label, int flag); void (*mpo_init_sysv_msgmsg_label)(struct label *label); void (*mpo_init_sysv_msgqueue_label)(struct label *label); void (*mpo_init_sysv_sema_label)(struct label *label); void (*mpo_init_sysv_shm_label)(struct label *label); int (*mpo_init_ipq_label)(struct label *label, int flag); int (*mpo_init_mbuf_label)(struct label *label, int flag); void (*mpo_init_mount_label)(struct label *label); void (*mpo_init_mount_fs_label)(struct label *label); int (*mpo_init_socket_label)(struct label *label, int flag); int (*mpo_init_socket_peer_label)(struct label *label, int flag); void (*mpo_init_pipe_label)(struct label *label); void (*mpo_init_proc_label)(struct label *label); void (*mpo_init_vnode_label)(struct label *label); void (*mpo_destroy_bpfdesc_label)(struct label *label); void (*mpo_destroy_cred_label)(struct label *label); void (*mpo_destroy_devfsdirent_label)(struct label *label); void (*mpo_destroy_ifnet_label)(struct label *label); void (*mpo_destroy_inpcb_label)(struct label *label); void (*mpo_destroy_sysv_msgmsg_label)(struct label *label); void (*mpo_destroy_sysv_msgqueue_label)(struct label *label); void (*mpo_destroy_sysv_sema_label)(struct label *label); void (*mpo_destroy_sysv_shm_label)(struct label *label); void (*mpo_destroy_ipq_label)(struct label *label); void (*mpo_destroy_mbuf_label)(struct label *label); void (*mpo_destroy_mount_label)(struct label *label); void (*mpo_destroy_mount_fs_label)(struct label *label); void (*mpo_destroy_socket_label)(struct label *label); void (*mpo_destroy_socket_peer_label)(struct label *label); void (*mpo_destroy_pipe_label)(struct label *label); void (*mpo_destroy_proc_label)(struct label *label); void (*mpo_destroy_vnode_label)(struct label *label); void (*mpo_cleanup_sysv_msgmsg)(struct label *msglabel); void (*mpo_cleanup_sysv_msgqueue)(struct label *msqlabel); void (*mpo_cleanup_sysv_sema)(struct label *semalabel); void (*mpo_cleanup_sysv_shm)(struct label *shmlabel); void (*mpo_copy_cred_label)(struct label *src, struct label *dest); void (*mpo_copy_ifnet_label)(struct label *src, struct label *dest); void (*mpo_copy_mbuf_label)(struct label *src, struct label *dest); void (*mpo_copy_pipe_label)(struct label *src, struct label *dest); void (*mpo_copy_socket_label)(struct label *src, struct label *dest); void (*mpo_copy_vnode_label)(struct label *src, struct label *dest); int (*mpo_externalize_cred_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_ifnet_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_pipe_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_socket_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_socket_peer_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_vnode_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_internalize_cred_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_ifnet_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_pipe_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_socket_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_vnode_label)(struct label *label, char *element_name, char *element_data, int *claimed); /* * Labeling event operations: file system objects, and things that * look a lot like file system objects. */ void (*mpo_associate_vnode_devfs)(struct mount *mp, struct label *fslabel, struct devfs_dirent *de, struct label *delabel, struct vnode *vp, struct label *vlabel); int (*mpo_associate_vnode_extattr)(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel); void (*mpo_associate_vnode_singlelabel)(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel); void (*mpo_create_devfs_device)(struct mount *mp, struct cdev *dev, struct devfs_dirent *de, struct label *label); void (*mpo_create_devfs_directory)(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *de, struct label *label); void (*mpo_create_devfs_symlink)(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, struct label *delabel); int (*mpo_create_vnode_extattr)(struct ucred *cred, struct mount *mp, struct label *fslabel, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *vlabel, struct componentname *cnp); void (*mpo_create_mount)(struct ucred *cred, struct mount *mp, struct label *mntlabel, struct label *fslabel); void (*mpo_create_root_mount)(struct ucred *cred, struct mount *mp, struct label *mountlabel, struct label *fslabel); void (*mpo_relabel_vnode)(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *label); int (*mpo_setlabel_vnode_extattr)(struct ucred *cred, struct vnode *vp, struct label *vlabel, struct label *intlabel); void (*mpo_update_devfsdirent)(struct mount *mp, struct devfs_dirent *devfs_dirent, struct label *direntlabel, struct vnode *vp, struct label *vnodelabel); /* * Labeling event operations: IPC objects. */ void (*mpo_create_mbuf_from_socket)(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel); void (*mpo_create_socket)(struct ucred *cred, struct socket *so, struct label *socketlabel); void (*mpo_create_socket_from_socket)(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel); void (*mpo_relabel_socket)(struct ucred *cred, struct socket *so, struct label *oldlabel, struct label *newlabel); void (*mpo_relabel_pipe)(struct ucred *cred, struct pipepair *pp, struct label *oldlabel, struct label *newlabel); void (*mpo_set_socket_peer_from_mbuf)(struct mbuf *mbuf, struct label *mbuflabel, struct socket *so, struct label *socketpeerlabel); void (*mpo_set_socket_peer_from_socket)(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketpeerlabel); void (*mpo_create_pipe)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); /* * Labeling event operations: System V IPC primitives. */ void (*mpo_create_sysv_msgmsg)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel, struct msg *msgptr, struct label *msglabel); void (*mpo_create_sysv_msgqueue)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel); void (*mpo_create_sysv_sema)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semalabel); void (*mpo_create_sysv_shm)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmlabel); /* * Labeling event operations: network objects. */ void (*mpo_create_bpfdesc)(struct ucred *cred, struct bpf_d *bpf_d, struct label *bpflabel); void (*mpo_create_ifnet)(struct ifnet *ifnet, struct label *ifnetlabel); void (*mpo_create_inpcb_from_socket)(struct socket *so, struct label *solabel, struct inpcb *inp, struct label *inplabel); void (*mpo_create_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); void (*mpo_create_datagram_from_ipq) (struct ipq *ipq, struct label *ipqlabel, struct mbuf *datagram, struct label *datagramlabel); void (*mpo_create_fragment)(struct mbuf *datagram, struct label *datagramlabel, struct mbuf *fragment, struct label *fragmentlabel); void (*mpo_create_mbuf_from_inpcb)(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel); void (*mpo_create_mbuf_from_mbuf)(struct mbuf *oldmbuf, struct label *oldlabel, struct mbuf *newmbuf, struct label *newlabel); void (*mpo_create_mbuf_linklayer)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel); void (*mpo_create_mbuf_from_bpfdesc)(struct bpf_d *bpf_d, struct label *bpflabel, struct mbuf *mbuf, struct label *mbuflabel); void (*mpo_create_mbuf_from_ifnet)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel); void (*mpo_create_mbuf_multicast_encap)(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *newmbuf, struct label *newmbuflabel); void (*mpo_create_mbuf_netlayer)(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel); int (*mpo_fragment_match)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); void (*mpo_reflect_mbuf_icmp)(struct mbuf *m, struct label *mlabel); void (*mpo_reflect_mbuf_tcp)(struct mbuf *m, struct label *mlabel); void (*mpo_relabel_ifnet)(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel); void (*mpo_update_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); void (*mpo_inpcb_sosetlabel)(struct socket *so, struct label *label, struct inpcb *inp, struct label *inplabel); /* * Labeling event operations: processes. */ void (*mpo_execve_transition)(struct ucred *old, struct ucred *new, struct vnode *vp, struct label *vnodelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel); int (*mpo_execve_will_transition)(struct ucred *old, struct vnode *vp, struct label *vnodelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel); void (*mpo_create_proc0)(struct ucred *cred); void (*mpo_create_proc1)(struct ucred *cred); void (*mpo_relabel_cred)(struct ucred *cred, struct label *newlabel); void (*mpo_thread_userret)(struct thread *thread); /* * Access control checks. */ int (*mpo_check_bpfdesc_receive)(struct bpf_d *bpf_d, struct label *bpflabel, struct ifnet *ifnet, struct label *ifnetlabel); int (*mpo_check_cred_relabel)(struct ucred *cred, struct label *newlabel); int (*mpo_check_cred_visible)(struct ucred *u1, struct ucred *u2); int (*mpo_check_ifnet_relabel)(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel); int (*mpo_check_ifnet_transmit)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel); int (*mpo_check_inpcb_deliver)(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel); int (*mpo_check_sysv_msgmsq)(struct ucred *cred, struct msg *msgptr, struct label *msglabel, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msgrcv)(struct ucred *cred, struct msg *msgptr, struct label *msglabel); int (*mpo_check_sysv_msgrmid)(struct ucred *cred, struct msg *msgptr, struct label *msglabel); int (*mpo_check_sysv_msqget)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msqsnd)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msqrcv)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msqctl)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel, int cmd); int (*mpo_check_sysv_semctl)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, int cmd); int (*mpo_check_sysv_semget)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel); int (*mpo_check_sysv_semop)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, size_t accesstype); int (*mpo_check_sysv_shmat)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg); int (*mpo_check_sysv_shmctl)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int cmd); int (*mpo_check_sysv_shmdt)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel); int (*mpo_check_sysv_shmget)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg); int (*mpo_check_kenv_dump)(struct ucred *cred); int (*mpo_check_kenv_get)(struct ucred *cred, char *name); int (*mpo_check_kenv_set)(struct ucred *cred, char *name, char *value); int (*mpo_check_kenv_unset)(struct ucred *cred, char *name); int (*mpo_check_kld_load)(struct ucred *cred, struct vnode *vp, struct label *vlabel); int (*mpo_check_kld_stat)(struct ucred *cred); int (*mpo_check_kld_unload)(struct ucred *cred); int (*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp, struct label *mntlabel); int (*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, unsigned long cmd, void *data); int (*mpo_check_pipe_poll)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_read)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_relabel)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, struct label *newlabel); int (*mpo_check_pipe_stat)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_write)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_proc_debug)(struct ucred *cred, struct proc *proc); int (*mpo_check_proc_sched)(struct ucred *cred, struct proc *proc); int (*mpo_check_proc_setuid)(struct ucred *cred, uid_t uid); int (*mpo_check_proc_seteuid)(struct ucred *cred, uid_t euid); int (*mpo_check_proc_setgid)(struct ucred *cred, gid_t gid); int (*mpo_check_proc_setegid)(struct ucred *cred, gid_t egid); int (*mpo_check_proc_setgroups)(struct ucred *cred, int ngroups, gid_t *gidset); int (*mpo_check_proc_setreuid)(struct ucred *cred, uid_t ruid, uid_t euid); int (*mpo_check_proc_setregid)(struct ucred *cred, gid_t rgid, gid_t egid); int (*mpo_check_proc_setresuid)(struct ucred *cred, uid_t ruid, uid_t euid, uid_t suid); int (*mpo_check_proc_setresgid)(struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid); int (*mpo_check_proc_signal)(struct ucred *cred, struct proc *proc, int signum); + int (*mpo_check_socket_accept)(struct ucred *cred, + struct socket *so, struct label *socketlabel); int (*mpo_check_socket_bind)(struct ucred *cred, struct socket *so, struct label *socketlabel, struct sockaddr *sockaddr); int (*mpo_check_socket_connect)(struct ucred *cred, struct socket *so, struct label *socketlabel, struct sockaddr *sockaddr); int (*mpo_check_socket_deliver)(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel); int (*mpo_check_socket_listen)(struct ucred *cred, struct socket *so, struct label *socketlabel); + int (*mpo_check_socket_poll)(struct ucred *cred, + struct socket *so, struct label *socketlabel); int (*mpo_check_socket_receive)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_socket_relabel)(struct ucred *cred, struct socket *so, struct label *socketlabel, struct label *newlabel); int (*mpo_check_socket_send)(struct ucred *cred, + struct socket *so, struct label *socketlabel); + int (*mpo_check_socket_stat)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_socket_visible)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_sysarch_ioperm)(struct ucred *cred); int (*mpo_check_system_acct)(struct ucred *cred, struct vnode *vp, struct label *vlabel); int (*mpo_check_system_nfsd)(struct ucred *cred); int (*mpo_check_system_reboot)(struct ucred *cred, int howto); int (*mpo_check_system_settime)(struct ucred *cred); int (*mpo_check_system_swapon)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_system_swapoff)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_system_sysctl)(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); int (*mpo_check_vnode_access)(struct ucred *cred, struct vnode *vp, struct label *label, int acc_mode); int (*mpo_check_vnode_chdir)(struct ucred *cred, struct vnode *dvp, struct label *dlabel); int (*mpo_check_vnode_chroot)(struct ucred *cred, struct vnode *dvp, struct label *dlabel); int (*mpo_check_vnode_create)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp, struct vattr *vap); int (*mpo_check_vnode_delete)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp); int (*mpo_check_vnode_deleteacl)(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type); int (*mpo_check_vnode_deleteextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name); int (*mpo_check_vnode_exec)(struct ucred *cred, struct vnode *vp, struct label *label, struct image_params *imgp, struct label *execlabel); int (*mpo_check_vnode_getacl)(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type); int (*mpo_check_vnode_getextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio); int (*mpo_check_vnode_link)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp); int (*mpo_check_vnode_listextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace); int (*mpo_check_vnode_lookup)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp); int (*mpo_check_vnode_mmap)(struct ucred *cred, struct vnode *vp, struct label *label, int prot, int flags); void (*mpo_check_vnode_mmap_downgrade)(struct ucred *cred, struct vnode *vp, struct label *label, int *prot); int (*mpo_check_vnode_mprotect)(struct ucred *cred, struct vnode *vp, struct label *label, int prot); int (*mpo_check_vnode_open)(struct ucred *cred, struct vnode *vp, struct label *label, int acc_mode); int (*mpo_check_vnode_poll)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_read)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_readdir)(struct ucred *cred, struct vnode *dvp, struct label *dlabel); int (*mpo_check_vnode_readlink)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_relabel)(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *newlabel); int (*mpo_check_vnode_rename_from)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp); int (*mpo_check_vnode_rename_to)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, int samedir, struct componentname *cnp); int (*mpo_check_vnode_revoke)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_setacl)(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type, struct acl *acl); int (*mpo_check_vnode_setextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio); int (*mpo_check_vnode_setflags)(struct ucred *cred, struct vnode *vp, struct label *label, u_long flags); int (*mpo_check_vnode_setmode)(struct ucred *cred, struct vnode *vp, struct label *label, mode_t mode); int (*mpo_check_vnode_setowner)(struct ucred *cred, struct vnode *vp, struct label *label, uid_t uid, gid_t gid); int (*mpo_check_vnode_setutimes)(struct ucred *cred, struct vnode *vp, struct label *label, struct timespec atime, struct timespec mtime); int (*mpo_check_vnode_stat)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_write)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); }; /* * struct mac_policy_conf is the registration structure for policies, and is * provided to the MAC Framework using MAC_POLICY_SET() to invoke a SYSINIT * to register the policy. In general, the fields are immutable, with the * exception of the "security field", run-time flags, and policy list entry, * which are managed by the MAC Framework. Be careful when modifying this * structure, as its layout is statically compiled into all policies. */ struct mac_policy_conf { char *mpc_name; /* policy name */ char *mpc_fullname; /* policy full name */ struct mac_policy_ops *mpc_ops; /* policy operations */ int mpc_loadtime_flags; /* flags */ int *mpc_field_off; /* security field */ int mpc_runtime_flags; /* flags */ LIST_ENTRY(mac_policy_conf) mpc_list; /* global list */ }; /* Flags for the mpc_loadtime_flags field. */ #define MPC_LOADTIME_FLAG_NOTLATE 0x00000001 #define MPC_LOADTIME_FLAG_UNLOADOK 0x00000002 #define MPC_LOADTIME_FLAG_LABELMBUFS 0x00000004 /* Flags for the mpc_runtime_flags field. */ #define MPC_RUNTIME_FLAG_REGISTERED 0x00000001 #define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted) \ static struct mac_policy_conf mpname##_mac_policy_conf = { \ #mpname, \ mpfullname, \ mpops, \ mpflags, \ privdata_wanted, \ 0, \ }; \ static moduledata_t mpname##_mod = { \ #mpname, \ mac_policy_modevent, \ &mpname##_mac_policy_conf \ }; \ MODULE_DEPEND(mpname, kernel_mac_support, 2, 2, 2); \ DECLARE_MODULE(mpname, mpname##_mod, SI_SUB_MAC_POLICY, \ SI_ORDER_MIDDLE) int mac_policy_modevent(module_t mod, int type, void *data); #define LABEL_TO_SLOT(l, s) (l)->l_perpolicy[s] #endif /* !_SYS_MAC_POLICY_H_ */ Index: head/sys/security/mac/mac_socket.c =================================================================== --- head/sys/security/mac/mac_socket.c (revision 145166) +++ head/sys/security/mac/mac_socket.c (revision 145167) @@ -1,536 +1,580 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson * Copyright (c) 2001 Ilmar S. Habibulin - * Copyright (c) 2001-2004 Networks Associates Technology, Inc. + * Copyright (c) 2001-2005 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed by Robert Watson and Ilmar Habibulin for the * TrustedBSD Project. * - * This software was developed for the FreeBSD Project in part by Network - * Associates Laboratories, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), - * as part of the DARPA CHATS research program. + * This software was developed for the FreeBSD Project in part by McAfee + * Research, the Technology Research Division of Network Associates, Inc. + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the + * DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_mac.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * mac_enforce_socket is used by the inet code when delivering to an inpcb * without hitting the socket layer, and has to be non-static for now. */ int mac_enforce_socket = 1; SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); #ifdef MAC_DEBUG static unsigned int nmacsockets; SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, &nmacsockets, 0, "number of sockets in use"); #endif struct label * mac_socket_label_alloc(int flag) { struct label *label; int error; label = mac_labelzone_alloc(flag); if (label == NULL) return (NULL); MAC_CHECK(init_socket_label, label, flag); if (error) { MAC_PERFORM(destroy_socket_label, label); mac_labelzone_free(label); return (NULL); } MAC_DEBUG_COUNTER_INC(&nmacsockets); return (label); } static struct label * mac_socket_peer_label_alloc(int flag) { struct label *label; int error; label = mac_labelzone_alloc(flag); if (label == NULL) return (NULL); MAC_CHECK(init_socket_peer_label, label, flag); if (error) { MAC_PERFORM(destroy_socket_peer_label, label); mac_labelzone_free(label); return (NULL); } MAC_DEBUG_COUNTER_INC(&nmacsockets); return (label); } int mac_init_socket(struct socket *so, int flag) { so->so_label = mac_socket_label_alloc(flag); if (so->so_label == NULL) return (ENOMEM); so->so_peerlabel = mac_socket_peer_label_alloc(flag); if (so->so_peerlabel == NULL) { mac_socket_label_free(so->so_label); so->so_label = NULL; return (ENOMEM); } return (0); } void mac_socket_label_free(struct label *label) { MAC_PERFORM(destroy_socket_label, label); mac_labelzone_free(label); MAC_DEBUG_COUNTER_DEC(&nmacsockets); } static void mac_socket_peer_label_free(struct label *label) { MAC_PERFORM(destroy_socket_peer_label, label); mac_labelzone_free(label); MAC_DEBUG_COUNTER_DEC(&nmacsockets); } void mac_destroy_socket(struct socket *socket) { mac_socket_label_free(socket->so_label); socket->so_label = NULL; mac_socket_peer_label_free(socket->so_peerlabel); socket->so_peerlabel = NULL; } void mac_copy_socket_label(struct label *src, struct label *dest) { MAC_PERFORM(copy_socket_label, src, dest); } int mac_externalize_socket_label(struct label *label, char *elements, char *outbuf, size_t outbuflen) { int error; MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen); return (error); } static int mac_externalize_socket_peer_label(struct label *label, char *elements, char *outbuf, size_t outbuflen) { int error; MAC_EXTERNALIZE(socket_peer, label, elements, outbuf, outbuflen); return (error); } int mac_internalize_socket_label(struct label *label, char *string) { int error; MAC_INTERNALIZE(socket, label, string); return (error); } void mac_create_socket(struct ucred *cred, struct socket *socket) { MAC_PERFORM(create_socket, cred, socket, socket->so_label); } void mac_create_socket_from_socket(struct socket *oldsocket, struct socket *newsocket) { SOCK_LOCK_ASSERT(oldsocket); MAC_PERFORM(create_socket_from_socket, oldsocket, oldsocket->so_label, newsocket, newsocket->so_label); } static void mac_relabel_socket(struct ucred *cred, struct socket *socket, struct label *newlabel) { SOCK_LOCK_ASSERT(socket); MAC_PERFORM(relabel_socket, cred, socket, socket->so_label, newlabel); } void mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) { struct label *label; SOCK_LOCK_ASSERT(socket); label = mac_mbuf_to_label(mbuf); MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, socket->so_peerlabel); } void mac_set_socket_peer_from_socket(struct socket *oldsocket, struct socket *newsocket) { /* * XXXRW: only hold the socket lock on one at a time, as one * socket is the original, and one is the new. However, it's * called in both directions, so we can't assert the lock * here currently. */ MAC_PERFORM(set_socket_peer_from_socket, oldsocket, oldsocket->so_label, newsocket, newsocket->so_peerlabel); } void mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) { struct label *label; label = mac_mbuf_to_label(mbuf); SOCK_LOCK_ASSERT(socket); MAC_PERFORM(create_mbuf_from_socket, socket, socket->so_label, mbuf, label); } int +mac_check_socket_accept(struct ucred *cred, struct socket *socket) +{ + int error; + + SOCK_LOCK_ASSERT(socket); + + if (!mac_enforce_socket) + return (0); + + MAC_CHECK(check_socket_accept, cred, socket, socket->so_label); + + return (error); +} + +int mac_check_socket_bind(struct ucred *ucred, struct socket *socket, struct sockaddr *sockaddr) { int error; SOCK_LOCK_ASSERT(socket); if (!mac_enforce_socket) return (0); MAC_CHECK(check_socket_bind, ucred, socket, socket->so_label, sockaddr); return (error); } int mac_check_socket_connect(struct ucred *cred, struct socket *socket, struct sockaddr *sockaddr) { int error; SOCK_LOCK_ASSERT(socket); if (!mac_enforce_socket) return (0); MAC_CHECK(check_socket_connect, cred, socket, socket->so_label, sockaddr); return (error); } int mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) { struct label *label; int error; SOCK_LOCK_ASSERT(socket); if (!mac_enforce_socket) return (0); label = mac_mbuf_to_label(mbuf); MAC_CHECK(check_socket_deliver, socket, socket->so_label, mbuf, label); return (error); } int mac_check_socket_listen(struct ucred *cred, struct socket *socket) { int error; SOCK_LOCK_ASSERT(socket); if (!mac_enforce_socket) return (0); MAC_CHECK(check_socket_listen, cred, socket, socket->so_label); return (error); } int +mac_check_socket_poll(struct ucred *cred, struct socket *so) +{ + int error; + + SOCK_LOCK_ASSERT(so); + + if (!mac_enforce_socket) + return (0); + + MAC_CHECK(check_socket_poll, cred, so, so->so_label); + return (error); +} + +int mac_check_socket_receive(struct ucred *cred, struct socket *so) { int error; SOCK_LOCK_ASSERT(so); if (!mac_enforce_socket) return (0); MAC_CHECK(check_socket_receive, cred, so, so->so_label); return (error); } static int mac_check_socket_relabel(struct ucred *cred, struct socket *socket, struct label *newlabel) { int error; SOCK_LOCK_ASSERT(socket); MAC_CHECK(check_socket_relabel, cred, socket, socket->so_label, newlabel); return (error); } int mac_check_socket_send(struct ucred *cred, struct socket *so) { int error; SOCK_LOCK_ASSERT(so); if (!mac_enforce_socket) return (0); MAC_CHECK(check_socket_send, cred, so, so->so_label); + + return (error); +} + +int +mac_check_socket_stat(struct ucred *cred, struct socket *so) +{ + int error; + + SOCK_LOCK_ASSERT(so); + + if (!mac_enforce_socket) + return (0); + + MAC_CHECK(check_socket_stat, cred, so, so->so_label); return (error); } int mac_check_socket_visible(struct ucred *cred, struct socket *socket) { int error; SOCK_LOCK_ASSERT(socket); if (!mac_enforce_socket) return (0); MAC_CHECK(check_socket_visible, cred, socket, socket->so_label); return (error); } int mac_socket_label_set(struct ucred *cred, struct socket *so, struct label *label) { int error; /* * We acquire the socket lock when we perform the test and set, * but have to release it as the pcb code needs to acquire the * pcb lock, which will precede the socket lock in the lock * order. However, this is fine, as any race will simply * result in the inpcb being refreshed twice, but still * consistently, as the inpcb code will acquire the socket lock * before refreshing, holding both locks. */ SOCK_LOCK(so); error = mac_check_socket_relabel(cred, so, label); if (error) { SOCK_UNLOCK(so); return (error); } mac_relabel_socket(cred, so, label); SOCK_UNLOCK(so); /* * If the protocol has expressed interest in socket layer changes, * such as if it needs to propagate changes to a cached pcb * label from the socket, notify it of the label change while * holding the socket lock. */ if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL) (so->so_proto->pr_usrreqs->pru_sosetlabel)(so); return (0); } int mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac) { struct label *intlabel; char *buffer; int error; error = mac_check_structmac_consistent(mac); if (error) return (error); buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); if (error) { free(buffer, M_MACTEMP); return (error); } intlabel = mac_socket_label_alloc(M_WAITOK); error = mac_internalize_socket_label(intlabel, buffer); free(buffer, M_MACTEMP); if (error) goto out; error = mac_socket_label_set(cred, so, intlabel); out: mac_socket_label_free(intlabel); return (error); } int mac_getsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac) { char *buffer, *elements; struct label *intlabel; int error; error = mac_check_structmac_consistent(mac); if (error) return (error); elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); if (error) { free(elements, M_MACTEMP); return (error); } buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); intlabel = mac_socket_label_alloc(M_WAITOK); SOCK_LOCK(so); mac_copy_socket_label(so->so_label, intlabel); SOCK_UNLOCK(so); error = mac_externalize_socket_label(intlabel, elements, buffer, mac->m_buflen); mac_socket_label_free(intlabel); if (error == 0) error = copyout(buffer, mac->m_string, strlen(buffer)+1); free(buffer, M_MACTEMP); free(elements, M_MACTEMP); return (error); } int mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, struct mac *mac) { char *elements, *buffer; struct label *intlabel; int error; error = mac_check_structmac_consistent(mac); if (error) return (error); elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); if (error) { free(elements, M_MACTEMP); return (error); } buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); intlabel = mac_socket_label_alloc(M_WAITOK); SOCK_LOCK(so); mac_copy_socket_label(so->so_peerlabel, intlabel); SOCK_UNLOCK(so); error = mac_externalize_socket_peer_label(intlabel, elements, buffer, mac->m_buflen); mac_socket_label_free(intlabel); if (error == 0) error = copyout(buffer, mac->m_string, strlen(buffer)+1); free(buffer, M_MACTEMP); free(elements, M_MACTEMP); return (error); } Index: head/sys/security/mac_stub/mac_stub.c =================================================================== --- head/sys/security/mac_stub/mac_stub.c (revision 145166) +++ head/sys/security/mac_stub/mac_stub.c (revision 145167) @@ -1,1467 +1,1511 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson * Copyright (c) 2001-2005 McAfee, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * This software was developed for the FreeBSD Project in part by McAfee * Research, the Security Research Division of McAfee, Inc. under * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA * CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Developed by the TrustedBSD Project. * * Stub module that implements a NOOP for most (if not all) MAC Framework * policy entry points. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include SYSCTL_DECL(_security_mac); SYSCTL_NODE(_security_mac, OID_AUTO, stub, CTLFLAG_RW, 0, "TrustedBSD mac_stub policy controls"); static int stub_enabled = 1; SYSCTL_INT(_security_mac_stub, OID_AUTO, enabled, CTLFLAG_RW, &stub_enabled, 0, "Enforce mac_stub policy"); /* * Policy module operations. */ static void stub_destroy(struct mac_policy_conf *conf) { } static void stub_init(struct mac_policy_conf *conf) { } static int stub_syscall(struct thread *td, int call, void *arg) { return (0); } /* * Label operations. */ static void stub_init_label(struct label *label) { } static int stub_init_label_waitcheck(struct label *label, int flag) { return (0); } static void stub_destroy_label(struct label *label) { } static void stub_copy_label(struct label *src, struct label *dest) { } static int stub_externalize_label(struct label *label, char *element_name, struct sbuf *sb, int *claimed) { return (0); } static int stub_internalize_label(struct label *label, char *element_name, char *element_data, int *claimed) { return (0); } /* * Labeling event operations: file system objects, and things that look * a lot like file system objects. */ static void stub_associate_vnode_devfs(struct mount *mp, struct label *fslabel, struct devfs_dirent *de, struct label *delabel, struct vnode *vp, struct label *vlabel) { } static int stub_associate_vnode_extattr(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel) { return (0); } static void stub_associate_vnode_singlelabel(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel) { } static void stub_create_devfs_device(struct mount *mp, struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) { } static void stub_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) { } static void stub_create_devfs_symlink(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) { } static int stub_create_vnode_extattr(struct ucred *cred, struct mount *mp, struct label *fslabel, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *vlabel, struct componentname *cnp) { return (0); } static void stub_create_mount(struct ucred *cred, struct mount *mp, struct label *mntlabel, struct label *fslabel) { } static void stub_create_root_mount(struct ucred *cred, struct mount *mp, struct label *mntlabel, struct label *fslabel) { } static void stub_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *label) { } static int stub_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, struct label *vlabel, struct label *intlabel) { return (0); } static void stub_update_devfsdirent(struct mount *mp, struct devfs_dirent *devfs_dirent, struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) { } /* * Labeling event operations: IPC object. */ static void stub_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { } static void stub_create_socket(struct ucred *cred, struct socket *socket, struct label *socketlabel) { } static void stub_create_pipe(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { } static void stub_create_socket_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel) { } static void stub_relabel_socket(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct label *newlabel) { } static void stub_relabel_pipe(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, struct label *newlabel) { } static void stub_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, struct socket *socket, struct label *socketpeerlabel) { } static void stub_set_socket_peer_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketpeerlabel) { } /* * Labeling event operations: network objects. */ static void stub_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, struct label *bpflabel) { } static void stub_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, struct mbuf *datagram, struct label *datagramlabel) { } static void stub_create_fragment(struct mbuf *datagram, struct label *datagramlabel, struct mbuf *fragment, struct label *fragmentlabel) { } static void stub_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) { } static void stub_create_inpcb_from_socket(struct socket *so, struct label *solabel, struct inpcb *inp, struct label *inplabel) { } static void stub_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel, struct msg *msgptr, struct label *msglabel) { } static void stub_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel) { } static void stub_create_sysv_sema(struct ucred *cred, struct semid_kernel *semakptr, struct label *semalabel) { } static void stub_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmalabel) { } static void stub_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { } static void stub_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel) { } static void stub_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel) { } static void stub_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel) { } static void stub_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, struct mbuf *mbuf, struct label *mbuflabel) { } static void stub_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel) { } static void stub_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *newmbuf, struct label *newmbuflabel) { } static void stub_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel) { } static int stub_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { return (1); } static void stub_reflect_mbuf_icmp(struct mbuf *m, struct label *mlabel) { } static void stub_reflect_mbuf_tcp(struct mbuf *m, struct label *mlabel) { } static void stub_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel) { } static void stub_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { } static void stub_inpcb_sosetlabel(struct socket *so, struct label *solabel, struct inpcb *inp, struct label *inplabel) { } /* * Labeling event operations: processes. */ static void stub_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, struct label *vnodelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel) { } static int stub_execve_will_transition(struct ucred *old, struct vnode *vp, struct label *vnodelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel) { return (0); } static void stub_create_proc0(struct ucred *cred) { } static void stub_create_proc1(struct ucred *cred) { } static void stub_relabel_cred(struct ucred *cred, struct label *newlabel) { } static void stub_thread_userret(struct thread *td) { } /* * Label cleanup/flush operations */ static void stub_cleanup_sysv_msgmsg(struct label *msglabel) { } static void stub_cleanup_sysv_msgqueue(struct label *msqlabel) { } static void stub_cleanup_sysv_sema(struct label *semalabel) { } static void stub_cleanup_sysv_shm(struct label *shmlabel) { } /* * Access control checks. */ static int stub_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, struct ifnet *ifnet, struct label *ifnet_label) { return (0); } static int stub_check_cred_relabel(struct ucred *cred, struct label *newlabel) { return (0); } static int stub_check_cred_visible(struct ucred *u1, struct ucred *u2) { return (0); } static int stub_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel) { return (0); } static int stub_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel) { return (0); } static int stub_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel) { return (0); } static int stub_check_sysv_msgmsq(struct ucred *cred, struct msg *msgptr, struct label *msglabel, struct msqid_kernel *msqkptr, struct label *msqklabel) { return (0); } static int stub_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, struct label *msglabel) { return (0); } static int stub_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, struct label *msglabel) { return (0); } static int stub_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel) { return (0); } static int stub_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel) { return (0); } static int stub_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel) { return (0); } static int stub_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel, int cmd) { return (0); } static int stub_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, int cmd) { return (0); } static int stub_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel) { return (0); } static int stub_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, size_t accesstype) { return (0); } static int stub_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg) { return (0); } static int stub_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int cmd) { return (0); } static int stub_check_sysv_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel) { return (0); } static int stub_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg) { return (0); } static int stub_check_kenv_dump(struct ucred *cred) { return (0); } static int stub_check_kenv_get(struct ucred *cred, char *name) { return (0); } static int stub_check_kenv_set(struct ucred *cred, char *name, char *value) { return (0); } static int stub_check_kenv_unset(struct ucred *cred, char *name) { return (0); } static int stub_check_kld_load(struct ucred *cred, struct vnode *vp, struct label *vlabel) { return (0); } static int stub_check_kld_stat(struct ucred *cred) { return (0); } static int stub_check_kld_unload(struct ucred *cred) { return (0); } static int stub_check_mount_stat(struct ucred *cred, struct mount *mp, struct label *mntlabel) { return (0); } static int stub_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) { return (0); } static int stub_check_pipe_poll(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { return (0); } static int stub_check_pipe_read(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { return (0); } static int stub_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, struct label *newlabel) { return (0); } static int stub_check_pipe_stat(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { return (0); } static int stub_check_pipe_write(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { return (0); } static int stub_check_proc_debug(struct ucred *cred, struct proc *proc) { return (0); } static int stub_check_proc_sched(struct ucred *cred, struct proc *proc) { return (0); } static int stub_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) { return (0); } static int stub_check_proc_setuid(struct ucred *cred, uid_t uid) { return (0); } static int stub_check_proc_seteuid(struct ucred *cred, uid_t euid) { return (0); } static int stub_check_proc_setgid(struct ucred *cred, gid_t gid) { return (0); } static int stub_check_proc_setegid(struct ucred *cred, gid_t egid) { return (0); } static int stub_check_proc_setgroups(struct ucred *cred, int ngroups, gid_t *gidset) { return (0); } static int stub_check_proc_setreuid(struct ucred *cred, uid_t ruid, uid_t euid) { return (0); } static int stub_check_proc_setregid(struct ucred *cred, gid_t rgid, gid_t egid) { return (0); } static int stub_check_proc_setresuid(struct ucred *cred, uid_t ruid, uid_t euid, uid_t suid) { return (0); } static int stub_check_proc_setresgid(struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid) { return (0); } static int +stub_check_socket_accept(struct ucred *cred, struct socket *socket, + struct label *socketlabel) +{ + + return (0); +} + +static int stub_check_socket_bind(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct sockaddr *sockaddr) { return (0); } static int stub_check_socket_connect(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct sockaddr *sockaddr) { return (0); } static int stub_check_socket_deliver(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { return (0); } static int stub_check_socket_listen(struct ucred *cred, struct socket *so, struct label *socketlabel) { return (0); } static int +stub_check_socket_poll(struct ucred *cred, struct socket *so, + struct label *socketlabel) +{ + + return (0); +} + +static int +stub_check_socket_receive(struct ucred *cred, struct socket *so, + struct label *socketlabel) +{ + + return (0); +} + +static int stub_check_socket_relabel(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct label *newlabel) { return (0); } +static int +stub_check_socket_send(struct ucred *cred, struct socket *so, + struct label *socketlabel) +{ + return (0); +} + static int +stub_check_socket_stat(struct ucred *cred, struct socket *so, + struct label *socketlabel) +{ + + return (0); +} + +static int stub_check_socket_visible(struct ucred *cred, struct socket *socket, struct label *socketlabel) { return (0); } static int stub_check_sysarch_ioperm(struct ucred *cred) { return (0); } static int stub_check_system_acct(struct ucred *cred, struct vnode *vp, struct label *vlabel) { return (0); } static int stub_check_system_reboot(struct ucred *cred, int how) { return (0); } static int stub_check_system_settime(struct ucred *cred) { return (0); } static int stub_check_system_swapon(struct ucred *cred, struct vnode *vp, struct label *label) { return (0); } static int stub_check_system_swapoff(struct ucred *cred, struct vnode *vp, struct label *label) { return (0); } static int stub_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req) { return (0); } static int stub_check_vnode_access(struct ucred *cred, struct vnode *vp, struct label *label, int acc_mode) { return (0); } static int stub_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, struct label *dlabel) { return (0); } static int stub_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, struct label *dlabel) { return (0); } static int stub_check_vnode_create(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp, struct vattr *vap) { return (0); } static int stub_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp) { return (0); } static int stub_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type) { return (0); } static int stub_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name) { return (0); } static int stub_check_vnode_exec(struct ucred *cred, struct vnode *vp, struct label *label, struct image_params *imgp, struct label *execlabel) { return (0); } static int stub_check_vnode_getacl(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type) { return (0); } static int stub_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio) { return (0); } static int stub_check_vnode_link(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp) { return (0); } static int stub_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace) { return (0); } static int stub_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp) { return (0); } static int stub_check_vnode_mmap(struct ucred *cred, struct vnode *vp, struct label *label, int prot, int flags) { return (0); } static int stub_check_vnode_open(struct ucred *cred, struct vnode *vp, struct label *filelabel, int acc_mode) { return (0); } static int stub_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { return (0); } static int stub_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { return (0); } static int stub_check_vnode_readdir(struct ucred *cred, struct vnode *vp, struct label *dlabel) { return (0); } static int stub_check_vnode_readlink(struct ucred *cred, struct vnode *vp, struct label *vnodelabel) { return (0); } static int stub_check_vnode_relabel(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *newlabel) { return (0); } static int stub_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp) { return (0); } static int stub_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, int samedir, struct componentname *cnp) { return (0); } static int stub_check_vnode_revoke(struct ucred *cred, struct vnode *vp, struct label *label) { return (0); } static int stub_check_vnode_setacl(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type, struct acl *acl) { return (0); } static int stub_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio) { return (0); } static int stub_check_vnode_setflags(struct ucred *cred, struct vnode *vp, struct label *label, u_long flags) { return (0); } static int stub_check_vnode_setmode(struct ucred *cred, struct vnode *vp, struct label *label, mode_t mode) { return (0); } static int stub_check_vnode_setowner(struct ucred *cred, struct vnode *vp, struct label *label, uid_t uid, gid_t gid) { return (0); } static int stub_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, struct label *label, struct timespec atime, struct timespec mtime) { return (0); } static int stub_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { return (0); } static int stub_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { return (0); } static struct mac_policy_ops mac_stub_ops = { .mpo_destroy = stub_destroy, .mpo_init = stub_init, .mpo_syscall = stub_syscall, .mpo_init_bpfdesc_label = stub_init_label, .mpo_init_cred_label = stub_init_label, .mpo_init_devfsdirent_label = stub_init_label, .mpo_init_ifnet_label = stub_init_label, .mpo_init_inpcb_label = stub_init_label_waitcheck, .mpo_init_sysv_msgmsg_label = stub_init_label, .mpo_init_sysv_msgqueue_label = stub_init_label, .mpo_init_sysv_sema_label = stub_init_label, .mpo_init_sysv_shm_label = stub_init_label, .mpo_init_ipq_label = stub_init_label_waitcheck, .mpo_init_mbuf_label = stub_init_label_waitcheck, .mpo_init_mount_label = stub_init_label, .mpo_init_mount_fs_label = stub_init_label, .mpo_init_pipe_label = stub_init_label, .mpo_init_socket_label = stub_init_label_waitcheck, .mpo_init_socket_peer_label = stub_init_label_waitcheck, .mpo_init_vnode_label = stub_init_label, .mpo_destroy_bpfdesc_label = stub_destroy_label, .mpo_destroy_cred_label = stub_destroy_label, .mpo_destroy_devfsdirent_label = stub_destroy_label, .mpo_destroy_ifnet_label = stub_destroy_label, .mpo_destroy_inpcb_label = stub_destroy_label, .mpo_destroy_sysv_msgmsg_label = stub_destroy_label, .mpo_destroy_sysv_msgqueue_label = stub_destroy_label, .mpo_destroy_sysv_sema_label = stub_destroy_label, .mpo_destroy_sysv_shm_label = stub_destroy_label, .mpo_destroy_ipq_label = stub_destroy_label, .mpo_destroy_mbuf_label = stub_destroy_label, .mpo_destroy_mount_label = stub_destroy_label, .mpo_destroy_mount_fs_label = stub_destroy_label, .mpo_destroy_pipe_label = stub_destroy_label, .mpo_destroy_socket_label = stub_destroy_label, .mpo_destroy_socket_peer_label = stub_destroy_label, .mpo_destroy_vnode_label = stub_destroy_label, .mpo_copy_cred_label = stub_copy_label, .mpo_copy_ifnet_label = stub_copy_label, .mpo_copy_mbuf_label = stub_copy_label, .mpo_copy_pipe_label = stub_copy_label, .mpo_copy_socket_label = stub_copy_label, .mpo_copy_vnode_label = stub_copy_label, .mpo_externalize_cred_label = stub_externalize_label, .mpo_externalize_ifnet_label = stub_externalize_label, .mpo_externalize_pipe_label = stub_externalize_label, .mpo_externalize_socket_label = stub_externalize_label, .mpo_externalize_socket_peer_label = stub_externalize_label, .mpo_externalize_vnode_label = stub_externalize_label, .mpo_internalize_cred_label = stub_internalize_label, .mpo_internalize_ifnet_label = stub_internalize_label, .mpo_internalize_pipe_label = stub_internalize_label, .mpo_internalize_socket_label = stub_internalize_label, .mpo_internalize_vnode_label = stub_internalize_label, .mpo_associate_vnode_devfs = stub_associate_vnode_devfs, .mpo_associate_vnode_extattr = stub_associate_vnode_extattr, .mpo_associate_vnode_singlelabel = stub_associate_vnode_singlelabel, .mpo_create_devfs_device = stub_create_devfs_device, .mpo_create_devfs_directory = stub_create_devfs_directory, .mpo_create_devfs_symlink = stub_create_devfs_symlink, .mpo_create_sysv_msgmsg = stub_create_sysv_msgmsg, .mpo_create_sysv_msgqueue = stub_create_sysv_msgqueue, .mpo_create_sysv_sema = stub_create_sysv_sema, .mpo_create_sysv_shm = stub_create_sysv_shm, .mpo_create_vnode_extattr = stub_create_vnode_extattr, .mpo_create_mount = stub_create_mount, .mpo_create_root_mount = stub_create_root_mount, .mpo_relabel_vnode = stub_relabel_vnode, .mpo_setlabel_vnode_extattr = stub_setlabel_vnode_extattr, .mpo_update_devfsdirent = stub_update_devfsdirent, .mpo_create_mbuf_from_socket = stub_create_mbuf_from_socket, .mpo_create_pipe = stub_create_pipe, .mpo_create_socket = stub_create_socket, .mpo_create_socket_from_socket = stub_create_socket_from_socket, .mpo_relabel_pipe = stub_relabel_pipe, .mpo_relabel_socket = stub_relabel_socket, .mpo_set_socket_peer_from_mbuf = stub_set_socket_peer_from_mbuf, .mpo_set_socket_peer_from_socket = stub_set_socket_peer_from_socket, .mpo_create_bpfdesc = stub_create_bpfdesc, .mpo_create_ifnet = stub_create_ifnet, .mpo_create_inpcb_from_socket = stub_create_inpcb_from_socket, .mpo_create_ipq = stub_create_ipq, .mpo_create_datagram_from_ipq = stub_create_datagram_from_ipq, .mpo_create_fragment = stub_create_fragment, .mpo_create_ipq = stub_create_ipq, .mpo_create_mbuf_from_inpcb = stub_create_mbuf_from_inpcb, .mpo_create_mbuf_from_mbuf = stub_create_mbuf_from_mbuf, .mpo_create_mbuf_linklayer = stub_create_mbuf_linklayer, .mpo_create_mbuf_from_bpfdesc = stub_create_mbuf_from_bpfdesc, .mpo_create_mbuf_from_ifnet = stub_create_mbuf_from_ifnet, .mpo_create_mbuf_multicast_encap = stub_create_mbuf_multicast_encap, .mpo_create_mbuf_netlayer = stub_create_mbuf_netlayer, .mpo_fragment_match = stub_fragment_match, .mpo_reflect_mbuf_icmp = stub_reflect_mbuf_icmp, .mpo_reflect_mbuf_tcp = stub_reflect_mbuf_tcp, .mpo_relabel_ifnet = stub_relabel_ifnet, .mpo_update_ipq = stub_update_ipq, .mpo_inpcb_sosetlabel = stub_inpcb_sosetlabel, .mpo_execve_transition = stub_execve_transition, .mpo_execve_will_transition = stub_execve_will_transition, .mpo_create_proc0 = stub_create_proc0, .mpo_create_proc1 = stub_create_proc1, .mpo_relabel_cred = stub_relabel_cred, .mpo_thread_userret = stub_thread_userret, .mpo_cleanup_sysv_msgmsg = stub_cleanup_sysv_msgmsg, .mpo_cleanup_sysv_msgqueue = stub_cleanup_sysv_msgqueue, .mpo_cleanup_sysv_sema = stub_cleanup_sysv_sema, .mpo_cleanup_sysv_shm = stub_cleanup_sysv_shm, .mpo_check_bpfdesc_receive = stub_check_bpfdesc_receive, .mpo_check_cred_relabel = stub_check_cred_relabel, .mpo_check_cred_visible = stub_check_cred_visible, .mpo_check_ifnet_relabel = stub_check_ifnet_relabel, .mpo_check_ifnet_transmit = stub_check_ifnet_transmit, .mpo_check_inpcb_deliver = stub_check_inpcb_deliver, .mpo_check_sysv_msgmsq = stub_check_sysv_msgmsq, .mpo_check_sysv_msgrcv = stub_check_sysv_msgrcv, .mpo_check_sysv_msgrmid = stub_check_sysv_msgrmid, .mpo_check_sysv_msqget = stub_check_sysv_msqget, .mpo_check_sysv_msqsnd = stub_check_sysv_msqsnd, .mpo_check_sysv_msqrcv = stub_check_sysv_msqrcv, .mpo_check_sysv_msqctl = stub_check_sysv_msqctl, .mpo_check_sysv_semctl = stub_check_sysv_semctl, .mpo_check_sysv_semget = stub_check_sysv_semget, .mpo_check_sysv_semop = stub_check_sysv_semop, .mpo_check_sysv_shmat = stub_check_sysv_shmat, .mpo_check_sysv_shmctl = stub_check_sysv_shmctl, .mpo_check_sysv_shmdt = stub_check_sysv_shmdt, .mpo_check_sysv_shmget = stub_check_sysv_shmget, .mpo_check_kenv_dump = stub_check_kenv_dump, .mpo_check_kenv_get = stub_check_kenv_get, .mpo_check_kenv_set = stub_check_kenv_set, .mpo_check_kenv_unset = stub_check_kenv_unset, .mpo_check_kld_load = stub_check_kld_load, .mpo_check_kld_stat = stub_check_kld_stat, .mpo_check_kld_unload = stub_check_kld_unload, .mpo_check_mount_stat = stub_check_mount_stat, .mpo_check_pipe_ioctl = stub_check_pipe_ioctl, .mpo_check_pipe_poll = stub_check_pipe_poll, .mpo_check_pipe_read = stub_check_pipe_read, .mpo_check_pipe_relabel = stub_check_pipe_relabel, .mpo_check_pipe_stat = stub_check_pipe_stat, .mpo_check_pipe_write = stub_check_pipe_write, .mpo_check_proc_debug = stub_check_proc_debug, .mpo_check_proc_sched = stub_check_proc_sched, .mpo_check_proc_setuid = stub_check_proc_setuid, .mpo_check_proc_seteuid = stub_check_proc_seteuid, .mpo_check_proc_setgid = stub_check_proc_setgid, .mpo_check_proc_setegid = stub_check_proc_setegid, .mpo_check_proc_setgroups = stub_check_proc_setgroups, .mpo_check_proc_setreuid = stub_check_proc_setreuid, .mpo_check_proc_setregid = stub_check_proc_setregid, .mpo_check_proc_setresuid = stub_check_proc_setresuid, .mpo_check_proc_setresgid = stub_check_proc_setresgid, .mpo_check_proc_signal = stub_check_proc_signal, + .mpo_check_socket_accept = stub_check_socket_accept, .mpo_check_socket_bind = stub_check_socket_bind, .mpo_check_socket_connect = stub_check_socket_connect, .mpo_check_socket_deliver = stub_check_socket_deliver, .mpo_check_socket_listen = stub_check_socket_listen, + .mpo_check_socket_poll = stub_check_socket_poll, + .mpo_check_socket_receive = stub_check_socket_receive, .mpo_check_socket_relabel = stub_check_socket_relabel, + .mpo_check_socket_send = stub_check_socket_send, + .mpo_check_socket_stat = stub_check_socket_stat, .mpo_check_socket_visible = stub_check_socket_visible, .mpo_check_sysarch_ioperm = stub_check_sysarch_ioperm, .mpo_check_system_acct = stub_check_system_acct, .mpo_check_system_reboot = stub_check_system_reboot, .mpo_check_system_settime = stub_check_system_settime, .mpo_check_system_swapon = stub_check_system_swapon, .mpo_check_system_swapoff = stub_check_system_swapoff, .mpo_check_system_sysctl = stub_check_system_sysctl, .mpo_check_vnode_access = stub_check_vnode_access, .mpo_check_vnode_chdir = stub_check_vnode_chdir, .mpo_check_vnode_chroot = stub_check_vnode_chroot, .mpo_check_vnode_create = stub_check_vnode_create, .mpo_check_vnode_delete = stub_check_vnode_delete, .mpo_check_vnode_deleteacl = stub_check_vnode_deleteacl, .mpo_check_vnode_deleteextattr = stub_check_vnode_deleteextattr, .mpo_check_vnode_exec = stub_check_vnode_exec, .mpo_check_vnode_getacl = stub_check_vnode_getacl, .mpo_check_vnode_getextattr = stub_check_vnode_getextattr, .mpo_check_vnode_link = stub_check_vnode_link, .mpo_check_vnode_listextattr = stub_check_vnode_listextattr, .mpo_check_vnode_lookup = stub_check_vnode_lookup, .mpo_check_vnode_mmap = stub_check_vnode_mmap, .mpo_check_vnode_open = stub_check_vnode_open, .mpo_check_vnode_poll = stub_check_vnode_poll, .mpo_check_vnode_read = stub_check_vnode_read, .mpo_check_vnode_readdir = stub_check_vnode_readdir, .mpo_check_vnode_readlink = stub_check_vnode_readlink, .mpo_check_vnode_relabel = stub_check_vnode_relabel, .mpo_check_vnode_rename_from = stub_check_vnode_rename_from, .mpo_check_vnode_rename_to = stub_check_vnode_rename_to, .mpo_check_vnode_revoke = stub_check_vnode_revoke, .mpo_check_vnode_setacl = stub_check_vnode_setacl, .mpo_check_vnode_setextattr = stub_check_vnode_setextattr, .mpo_check_vnode_setflags = stub_check_vnode_setflags, .mpo_check_vnode_setmode = stub_check_vnode_setmode, .mpo_check_vnode_setowner = stub_check_vnode_setowner, .mpo_check_vnode_setutimes = stub_check_vnode_setutimes, .mpo_check_vnode_stat = stub_check_vnode_stat, .mpo_check_vnode_write = stub_check_vnode_write, }; MAC_POLICY_SET(&mac_stub_ops, mac_stub, "TrustedBSD MAC/Stub", MPC_LOADTIME_FLAG_UNLOADOK, NULL); Index: head/sys/security/mac_test/mac_test.c =================================================================== --- head/sys/security/mac_test/mac_test.c (revision 145166) +++ head/sys/security/mac_test/mac_test.c (revision 145167) @@ -1,2501 +1,2561 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson * Copyright (c) 2001-2005 McAfee, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * This software was developed for the FreeBSD Project in part by McAfee * Research, the Security Research Division of McAfee, Inc. under * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA * CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Developed by the TrustedBSD Project. * Generic mandatory access module that does nothing. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include SYSCTL_DECL(_security_mac); SYSCTL_NODE(_security_mac, OID_AUTO, test, CTLFLAG_RW, 0, "TrustedBSD mac_test policy controls"); static int mac_test_enabled = 1; SYSCTL_INT(_security_mac_test, OID_AUTO, enabled, CTLFLAG_RW, &mac_test_enabled, 0, "Enforce test policy"); #define BPFMAGIC 0xfe1ad1b6 #define DEVFSMAGIC 0x9ee79c32 #define IFNETMAGIC 0xc218b120 #define INPCBMAGIC 0x4440f7bb #define IPQMAGIC 0x206188ef #define MBUFMAGIC 0xbbefa5bb #define MOUNTMAGIC 0xc7c46e47 #define SOCKETMAGIC 0x9199c6cd #define SYSVIPCMSQMAGIC 0xea672391 #define SYSVIPCMSGMAGIC 0x8bbba61e #define SYSVIPCSEMMAGIC 0x896e8a0b #define SYSVIPCSHMMAGIC 0x76119ab0 #define PIPEMAGIC 0xdc6c9919 #define POSIXSEMMAGIC 0x78ae980c #define PROCMAGIC 0x3b4be98f #define CREDMAGIC 0x9a5a4987 #define VNODEMAGIC 0x1a67a45c #define EXMAGIC 0x849ba1fd #define SLOT(x) LABEL_TO_SLOT((x), test_slot).l_long #define ASSERT_BPF_LABEL(x) KASSERT(SLOT(x) == BPFMAGIC || \ SLOT(x) == 0, ("%s: Bad BPF label", __func__ )) #define ASSERT_DEVFS_LABEL(x) KASSERT(SLOT(x) == DEVFSMAGIC || \ SLOT(x) == 0, ("%s: Bad DEVFS label", __func__ )) #define ASSERT_IFNET_LABEL(x) KASSERT(SLOT(x) == IFNETMAGIC || \ SLOT(x) == 0, ("%s: Bad IFNET label", __func__ )) #define ASSERT_INPCB_LABEL(x) KASSERT(SLOT(x) == INPCBMAGIC || \ SLOT(x) == 0, ("%s: Bad INPCB label", __func__ )) #define ASSERT_IPQ_LABEL(x) KASSERT(SLOT(x) == IPQMAGIC || \ SLOT(x) == 0, ("%s: Bad IPQ label", __func__ )) #define ASSERT_MBUF_LABEL(x) KASSERT(x == NULL || \ SLOT(x) == MBUFMAGIC || SLOT(x) == 0, \ ("%s: Bad MBUF label", __func__ )) #define ASSERT_MOUNT_LABEL(x) KASSERT(SLOT(x) == MOUNTMAGIC || \ SLOT(x) == 0, ("%s: Bad MOUNT label", __func__ )) #define ASSERT_SOCKET_LABEL(x) KASSERT(SLOT(x) == SOCKETMAGIC || \ SLOT(x) == 0, ("%s: Bad SOCKET label", __func__ )) #define ASSERT_SYSVIPCMSQ_LABEL(x) KASSERT(SLOT(x) == SYSVIPCMSQMAGIC || \ SLOT(x) == 0, ("%s: Bad SYSVIPCMSQ label", __func__ )) #define ASSERT_SYSVIPCMSG_LABEL(x) KASSERT(SLOT(x) == SYSVIPCMSGMAGIC || \ SLOT(x) == 0, ("%s: Bad SYSVIPCMSG label", __func__ )) #define ASSERT_SYSVIPCSEM_LABEL(x) KASSERT(SLOT(x) == SYSVIPCSEMMAGIC || \ SLOT(x) == 0, ("%s: Bad SYSVIPCSEM label", __func__ )) #define ASSERT_SYSVIPCSHM_LABEL(x) KASSERT(SLOT(x) == SYSVIPCSHMMAGIC || \ SLOT(x) == 0, ("%s: Bad SYSVIPCSHM label", __func__ )) #define ASSERT_PIPE_LABEL(x) KASSERT(SLOT(x) == PIPEMAGIC || \ SLOT(x) == 0, ("%s: Bad PIPE label", __func__ )) #define ASSERT_PROC_LABEL(x) KASSERT(SLOT(x) == PROCMAGIC || \ SLOT(x) == 0, ("%s: Bad PROC label", __func__ )) #define ASSERT_CRED_LABEL(x) KASSERT(SLOT(x) == CREDMAGIC || \ SLOT(x) == 0, ("%s: Bad CRED label", __func__ )) #define ASSERT_VNODE_LABEL(x) KASSERT(SLOT(x) == VNODEMAGIC || \ SLOT(x) == 0, ("%s: Bad VNODE label", __func__ )) static int test_slot; SYSCTL_INT(_security_mac_test, OID_AUTO, slot, CTLFLAG_RD, &test_slot, 0, "Slot allocated by framework"); static int init_count_bpfdesc; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_bpfdesc, CTLFLAG_RD, &init_count_bpfdesc, 0, "bpfdesc init calls"); static int init_count_cred; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_cred, CTLFLAG_RD, &init_count_cred, 0, "cred init calls"); static int init_count_devfsdirent; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_devfsdirent, CTLFLAG_RD, &init_count_devfsdirent, 0, "devfsdirent init calls"); static int init_count_ifnet; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ifnet, CTLFLAG_RD, &init_count_ifnet, 0, "ifnet init calls"); static int init_count_inpcb; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_inpcb, CTLFLAG_RD, &init_count_inpcb, 0, "inpcb init calls"); static int init_count_sysv_msg; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_sysv_msg, CTLFLAG_RD, &init_count_sysv_msg, 0, "ipc_msg init calls"); static int init_count_sysv_msq; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_sysv_msq, CTLFLAG_RD, &init_count_sysv_msq, 0, "ipc_msq init calls"); static int init_count_sysv_sema; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_sysv_sema, CTLFLAG_RD, &init_count_sysv_sema, 0, "ipc_sema init calls"); static int init_count_sysv_shm; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_sysv_shm, CTLFLAG_RD, &init_count_sysv_shm, 0, "ipc_shm init calls"); static int init_count_ipq; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipq, CTLFLAG_RD, &init_count_ipq, 0, "ipq init calls"); static int init_count_mbuf; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_mbuf, CTLFLAG_RD, &init_count_mbuf, 0, "mbuf init calls"); static int init_count_mount; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_mount, CTLFLAG_RD, &init_count_mount, 0, "mount init calls"); static int init_count_mount_fslabel; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_mount_fslabel, CTLFLAG_RD, &init_count_mount_fslabel, 0, "mount_fslabel init calls"); static int init_count_socket; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_socket, CTLFLAG_RD, &init_count_socket, 0, "socket init calls"); static int init_count_socket_peerlabel; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_socket_peerlabel, CTLFLAG_RD, &init_count_socket_peerlabel, 0, "socket_peerlabel init calls"); static int init_count_pipe; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_pipe, CTLFLAG_RD, &init_count_pipe, 0, "pipe init calls"); static int init_count_proc; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_proc, CTLFLAG_RD, &init_count_proc, 0, "proc init calls"); static int init_count_vnode; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_vnode, CTLFLAG_RD, &init_count_vnode, 0, "vnode init calls"); static int destroy_count_bpfdesc; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_bpfdesc, CTLFLAG_RD, &destroy_count_bpfdesc, 0, "bpfdesc destroy calls"); static int destroy_count_cred; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_cred, CTLFLAG_RD, &destroy_count_cred, 0, "cred destroy calls"); static int destroy_count_devfsdirent; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_devfsdirent, CTLFLAG_RD, &destroy_count_devfsdirent, 0, "devfsdirent destroy calls"); static int destroy_count_ifnet; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ifnet, CTLFLAG_RD, &destroy_count_ifnet, 0, "ifnet destroy calls"); static int destroy_count_inpcb; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_inpcb, CTLFLAG_RD, &destroy_count_inpcb, 0, "inpcb destroy calls"); static int destroy_count_sysv_msg; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_sysv_msg, CTLFLAG_RD, &destroy_count_sysv_msg, 0, "ipc_msg destroy calls"); static int destroy_count_sysv_msq; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_sysv_msq, CTLFLAG_RD, &destroy_count_sysv_msq, 0, "ipc_msq destroy calls"); static int destroy_count_sysv_sema; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_sysv_sema, CTLFLAG_RD, &destroy_count_sysv_sema, 0, "ipc_sema destroy calls"); static int destroy_count_sysv_shm; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_sysv_shm, CTLFLAG_RD, &destroy_count_sysv_shm, 0, "ipc_shm destroy calls"); static int destroy_count_ipq; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipq, CTLFLAG_RD, &destroy_count_ipq, 0, "ipq destroy calls"); static int destroy_count_mbuf; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_mbuf, CTLFLAG_RD, &destroy_count_mbuf, 0, "mbuf destroy calls"); static int destroy_count_mount; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_mount, CTLFLAG_RD, &destroy_count_mount, 0, "mount destroy calls"); static int destroy_count_mount_fslabel; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_mount_fslabel, CTLFLAG_RD, &destroy_count_mount_fslabel, 0, "mount_fslabel destroy calls"); static int destroy_count_socket; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_socket, CTLFLAG_RD, &destroy_count_socket, 0, "socket destroy calls"); static int destroy_count_socket_peerlabel; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_socket_peerlabel, CTLFLAG_RD, &destroy_count_socket_peerlabel, 0, "socket_peerlabel destroy calls"); static int destroy_count_pipe; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_pipe, CTLFLAG_RD, &destroy_count_pipe, 0, "pipe destroy calls"); static int destroy_count_proc; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_proc, CTLFLAG_RD, &destroy_count_proc, 0, "proc destroy calls"); static int destroy_count_vnode; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_vnode, CTLFLAG_RD, &destroy_count_vnode, 0, "vnode destroy calls"); static int externalize_count; SYSCTL_INT(_security_mac_test, OID_AUTO, externalize_count, CTLFLAG_RD, &externalize_count, 0, "Subject/object externalize calls"); static int internalize_count; SYSCTL_INT(_security_mac_test, OID_AUTO, internalize_count, CTLFLAG_RD, &internalize_count, 0, "Subject/object internalize calls"); #ifdef KDB #define DEBUGGER(x) kdb_enter(x) #else #define DEBUGGER(x) printf("mac_test: %s\n", (x)) #endif /* * Policy module operations. */ static void mac_test_destroy(struct mac_policy_conf *conf) { } static void mac_test_init(struct mac_policy_conf *conf) { } static int mac_test_syscall(struct thread *td, int call, void *arg) { return (0); } /* * Label operations. */ static void mac_test_init_bpfdesc_label(struct label *label) { SLOT(label) = BPFMAGIC; atomic_add_int(&init_count_bpfdesc, 1); } static void mac_test_init_cred_label(struct label *label) { SLOT(label) = CREDMAGIC; atomic_add_int(&init_count_cred, 1); } static void mac_test_init_devfsdirent_label(struct label *label) { SLOT(label) = DEVFSMAGIC; atomic_add_int(&init_count_devfsdirent, 1); } static void mac_test_init_ifnet_label(struct label *label) { SLOT(label) = IFNETMAGIC; atomic_add_int(&init_count_ifnet, 1); } static int mac_test_init_inpcb_label(struct label *label, int flag) { if (flag & M_WAITOK) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "mac_test_init_inpcb_label() at %s:%d", __FILE__, __LINE__); SLOT(label) = INPCBMAGIC; atomic_add_int(&init_count_inpcb, 1); return (0); } static void mac_test_init_sysv_msgmsg_label(struct label *label) { SLOT(label) = SYSVIPCMSGMAGIC; atomic_add_int(&init_count_sysv_msg, 1); } static void mac_test_init_sysv_msgqueue_label(struct label *label) { SLOT(label) = SYSVIPCMSQMAGIC; atomic_add_int(&init_count_sysv_msq, 1); } static void mac_test_init_sysv_sema_label(struct label *label) { SLOT(label) = SYSVIPCSEMMAGIC; atomic_add_int(&init_count_sysv_sema, 1); } static void mac_test_init_sysv_shm_label(struct label *label) { SLOT(label) = SYSVIPCSHMMAGIC; atomic_add_int(&init_count_sysv_shm, 1); } static int mac_test_init_ipq_label(struct label *label, int flag) { if (flag & M_WAITOK) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "mac_test_init_ipq_label() at %s:%d", __FILE__, __LINE__); SLOT(label) = IPQMAGIC; atomic_add_int(&init_count_ipq, 1); return (0); } static int mac_test_init_mbuf_label(struct label *label, int flag) { if (flag & M_WAITOK) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "mac_test_init_mbuf_label() at %s:%d", __FILE__, __LINE__); SLOT(label) = MBUFMAGIC; atomic_add_int(&init_count_mbuf, 1); return (0); } static void mac_test_init_mount_label(struct label *label) { SLOT(label) = MOUNTMAGIC; atomic_add_int(&init_count_mount, 1); } static void mac_test_init_mount_fs_label(struct label *label) { SLOT(label) = MOUNTMAGIC; atomic_add_int(&init_count_mount_fslabel, 1); } static int mac_test_init_socket_label(struct label *label, int flag) { if (flag & M_WAITOK) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "mac_test_init_socket_label() at %s:%d", __FILE__, __LINE__); SLOT(label) = SOCKETMAGIC; atomic_add_int(&init_count_socket, 1); return (0); } static int mac_test_init_socket_peer_label(struct label *label, int flag) { if (flag & M_WAITOK) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "mac_test_init_socket_peer_label() at %s:%d", __FILE__, __LINE__); SLOT(label) = SOCKETMAGIC; atomic_add_int(&init_count_socket_peerlabel, 1); return (0); } static void mac_test_init_pipe_label(struct label *label) { SLOT(label) = PIPEMAGIC; atomic_add_int(&init_count_pipe, 1); } static void mac_test_init_proc_label(struct label *label) { SLOT(label) = PROCMAGIC; atomic_add_int(&init_count_proc, 1); } static void mac_test_init_vnode_label(struct label *label) { SLOT(label) = VNODEMAGIC; atomic_add_int(&init_count_vnode, 1); } static void mac_test_destroy_bpfdesc_label(struct label *label) { if (SLOT(label) == BPFMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_bpfdesc, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_bpfdesc: dup destroy"); } else { DEBUGGER("mac_test_destroy_bpfdesc: corrupted label"); } } static void mac_test_destroy_cred_label(struct label *label) { if (SLOT(label) == CREDMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_cred, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_cred: dup destroy"); } else { DEBUGGER("mac_test_destroy_cred: corrupted label"); } } static void mac_test_destroy_devfsdirent_label(struct label *label) { if (SLOT(label) == DEVFSMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_devfsdirent, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_devfsdirent: dup destroy"); } else { DEBUGGER("mac_test_destroy_devfsdirent: corrupted label"); } } static void mac_test_destroy_ifnet_label(struct label *label) { if (SLOT(label) == IFNETMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_ifnet, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_ifnet: dup destroy"); } else { DEBUGGER("mac_test_destroy_ifnet: corrupted label"); } } static void mac_test_destroy_inpcb_label(struct label *label) { if (SLOT(label) == INPCBMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_inpcb, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_inpcb: dup destroy"); } else { DEBUGGER("mac_test_destroy_inpcb: corrupted label"); } } static void mac_test_destroy_sysv_msgmsg_label(struct label *label) { if (SLOT(label) == SYSVIPCMSGMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_sysv_msg, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_sysv_msgmsg_label: dup destroy"); } else { DEBUGGER( "mac_test_destroy_sysv_msgmsg_label: corrupted label"); } } static void mac_test_destroy_sysv_msgqueue_label(struct label *label) { if (SLOT(label) == SYSVIPCMSQMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_sysv_msq, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_sysv_msgqueue_label: dup destroy"); } else { DEBUGGER( "mac_test_destroy_sysv_msgqueue_label: corrupted label"); } } static void mac_test_destroy_sysv_sema_label(struct label *label) { if (SLOT(label) == SYSVIPCSEMMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_sysv_sema, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_sysv_sema_label: dup destroy"); } else { DEBUGGER("mac_test_destroy_sysv_sema_label: corrupted label"); } } static void mac_test_destroy_sysv_shm_label(struct label *label) { if (SLOT(label) == SYSVIPCSHMMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_sysv_shm, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_sysv_shm_label: dup destroy"); } else { DEBUGGER("mac_test_destroy_sysv_shm_label: corrupted label"); } } static void mac_test_destroy_ipq_label(struct label *label) { if (SLOT(label) == IPQMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_ipq, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_ipq: dup destroy"); } else { DEBUGGER("mac_test_destroy_ipq: corrupted label"); } } static void mac_test_destroy_mbuf_label(struct label *label) { /* * If we're loaded dynamically, there may be mbufs in flight that * didn't have label storage allocated for them. Handle this * gracefully. */ if (label == NULL) return; if (SLOT(label) == MBUFMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_mbuf, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_mbuf: dup destroy"); } else { DEBUGGER("mac_test_destroy_mbuf: corrupted label"); } } static void mac_test_destroy_mount_label(struct label *label) { if ((SLOT(label) == MOUNTMAGIC || SLOT(label) == 0)) { atomic_add_int(&destroy_count_mount, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_mount: dup destroy"); } else { DEBUGGER("mac_test_destroy_mount: corrupted label"); } } static void mac_test_destroy_mount_fs_label(struct label *label) { if ((SLOT(label) == MOUNTMAGIC || SLOT(label) == 0)) { atomic_add_int(&destroy_count_mount_fslabel, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_mount_fslabel: dup destroy"); } else { DEBUGGER("mac_test_destroy_mount_fslabel: corrupted label"); } } static void mac_test_destroy_socket_label(struct label *label) { if ((SLOT(label) == SOCKETMAGIC || SLOT(label) == 0)) { atomic_add_int(&destroy_count_socket, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_socket: dup destroy"); } else { DEBUGGER("mac_test_destroy_socket: corrupted label"); } } static void mac_test_destroy_socket_peer_label(struct label *label) { if ((SLOT(label) == SOCKETMAGIC || SLOT(label) == 0)) { atomic_add_int(&destroy_count_socket_peerlabel, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_socket_peerlabel: dup destroy"); } else { DEBUGGER("mac_test_destroy_socket_peerlabel: corrupted label"); } } static void mac_test_destroy_pipe_label(struct label *label) { if ((SLOT(label) == PIPEMAGIC || SLOT(label) == 0)) { atomic_add_int(&destroy_count_pipe, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_pipe: dup destroy"); } else { DEBUGGER("mac_test_destroy_pipe: corrupted label"); } } static void mac_test_destroy_proc_label(struct label *label) { if ((SLOT(label) == PROCMAGIC || SLOT(label) == 0)) { atomic_add_int(&destroy_count_proc, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_proc: dup destroy"); } else { DEBUGGER("mac_test_destroy_proc: corrupted label"); } } static void mac_test_destroy_vnode_label(struct label *label) { if (SLOT(label) == VNODEMAGIC || SLOT(label) == 0) { atomic_add_int(&destroy_count_vnode, 1); SLOT(label) = EXMAGIC; } else if (SLOT(label) == EXMAGIC) { DEBUGGER("mac_test_destroy_vnode: dup destroy"); } else { DEBUGGER("mac_test_destroy_vnode: corrupted label"); } } static void mac_test_copy_cred_label(struct label *src, struct label *dest) { ASSERT_CRED_LABEL(src); ASSERT_CRED_LABEL(dest); } static void mac_test_copy_ifnet_label(struct label *src, struct label *dest) { ASSERT_IFNET_LABEL(src); ASSERT_IFNET_LABEL(dest); } static void mac_test_copy_mbuf_label(struct label *src, struct label *dest) { ASSERT_MBUF_LABEL(src); ASSERT_MBUF_LABEL(dest); } static void mac_test_copy_pipe_label(struct label *src, struct label *dest) { ASSERT_PIPE_LABEL(src); ASSERT_PIPE_LABEL(dest); } static void mac_test_copy_socket_label(struct label *src, struct label *dest) { ASSERT_SOCKET_LABEL(src); ASSERT_SOCKET_LABEL(dest); } static void mac_test_copy_vnode_label(struct label *src, struct label *dest) { ASSERT_VNODE_LABEL(src); ASSERT_VNODE_LABEL(dest); } static int mac_test_externalize_label(struct label *label, char *element_name, struct sbuf *sb, int *claimed) { atomic_add_int(&externalize_count, 1); KASSERT(SLOT(label) != EXMAGIC, ("mac_test_externalize_label: destroyed label")); return (0); } static int mac_test_internalize_label(struct label *label, char *element_name, char *element_data, int *claimed) { atomic_add_int(&internalize_count, 1); KASSERT(SLOT(label) != EXMAGIC, ("mac_test_internalize_label: destroyed label")); return (0); } /* * Labeling event operations: file system objects, and things that look * a lot like file system objects. */ static void mac_test_associate_vnode_devfs(struct mount *mp, struct label *fslabel, struct devfs_dirent *de, struct label *delabel, struct vnode *vp, struct label *vlabel) { ASSERT_MOUNT_LABEL(fslabel); ASSERT_DEVFS_LABEL(delabel); ASSERT_VNODE_LABEL(vlabel); } static int mac_test_associate_vnode_extattr(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel) { ASSERT_MOUNT_LABEL(fslabel); ASSERT_VNODE_LABEL(vlabel); return (0); } static void mac_test_associate_vnode_singlelabel(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel) { ASSERT_MOUNT_LABEL(fslabel); ASSERT_VNODE_LABEL(vlabel); } static void mac_test_create_devfs_device(struct mount *mp, struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) { ASSERT_DEVFS_LABEL(label); } static void mac_test_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) { ASSERT_DEVFS_LABEL(label); } static void mac_test_create_devfs_symlink(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_DEVFS_LABEL(ddlabel); ASSERT_DEVFS_LABEL(delabel); } static int mac_test_create_vnode_extattr(struct ucred *cred, struct mount *mp, struct label *fslabel, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *vlabel, struct componentname *cnp) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_MOUNT_LABEL(fslabel); ASSERT_VNODE_LABEL(dlabel); return (0); } static void mac_test_create_mount(struct ucred *cred, struct mount *mp, struct label *mntlabel, struct label *fslabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_MOUNT_LABEL(mntlabel); ASSERT_MOUNT_LABEL(fslabel); } static void mac_test_create_root_mount(struct ucred *cred, struct mount *mp, struct label *mntlabel, struct label *fslabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_MOUNT_LABEL(mntlabel); ASSERT_MOUNT_LABEL(fslabel); } static void mac_test_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *label) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(vnodelabel); ASSERT_VNODE_LABEL(label); } static int mac_test_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, struct label *vlabel, struct label *intlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(vlabel); ASSERT_VNODE_LABEL(intlabel); return (0); } static void mac_test_update_devfsdirent(struct mount *mp, struct devfs_dirent *devfs_dirent, struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) { ASSERT_DEVFS_LABEL(direntlabel); ASSERT_VNODE_LABEL(vnodelabel); } /* * Labeling event operations: IPC object. */ static void mac_test_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { ASSERT_SOCKET_LABEL(socketlabel); ASSERT_MBUF_LABEL(mbuflabel); } static void mac_test_create_socket(struct ucred *cred, struct socket *socket, struct label *socketlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(socketlabel); } static void mac_test_create_pipe(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); } static void mac_test_create_socket_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel) { ASSERT_SOCKET_LABEL(oldsocketlabel); ASSERT_SOCKET_LABEL(newsocketlabel); } static void mac_test_relabel_socket(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(newlabel); } static void mac_test_relabel_pipe(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); ASSERT_PIPE_LABEL(newlabel); } static void mac_test_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, struct socket *socket, struct label *socketpeerlabel) { ASSERT_MBUF_LABEL(mbuflabel); ASSERT_SOCKET_LABEL(socketpeerlabel); } /* * Labeling event operations: network objects. */ static void mac_test_set_socket_peer_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketpeerlabel) { ASSERT_SOCKET_LABEL(oldsocketlabel); ASSERT_SOCKET_LABEL(newsocketpeerlabel); } static void mac_test_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, struct label *bpflabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_BPF_LABEL(bpflabel); } static void mac_test_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, struct mbuf *datagram, struct label *datagramlabel) { ASSERT_IPQ_LABEL(ipqlabel); ASSERT_MBUF_LABEL(datagramlabel); } static void mac_test_create_fragment(struct mbuf *datagram, struct label *datagramlabel, struct mbuf *fragment, struct label *fragmentlabel) { ASSERT_MBUF_LABEL(datagramlabel); ASSERT_MBUF_LABEL(fragmentlabel); } static void mac_test_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) { ASSERT_IFNET_LABEL(ifnetlabel); } static void mac_test_create_inpcb_from_socket(struct socket *so, struct label *solabel, struct inpcb *inp, struct label *inplabel) { ASSERT_SOCKET_LABEL(solabel); ASSERT_INPCB_LABEL(inplabel); } static void mac_test_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel, struct msg *msgptr, struct label *msglabel) { ASSERT_SYSVIPCMSG_LABEL(msglabel); ASSERT_SYSVIPCMSQ_LABEL(msqlabel); } static void mac_test_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel) { ASSERT_SYSVIPCMSQ_LABEL(msqlabel); } static void mac_test_create_sysv_sema(struct ucred *cred, struct semid_kernel *semakptr, struct label *semalabel) { ASSERT_SYSVIPCSEM_LABEL(semalabel); } static void mac_test_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmlabel) { ASSERT_SYSVIPCSHM_LABEL(shmlabel); } static void mac_test_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { ASSERT_MBUF_LABEL(fragmentlabel); ASSERT_IPQ_LABEL(ipqlabel); } static void mac_test_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel) { ASSERT_INPCB_LABEL(inplabel); ASSERT_MBUF_LABEL(mlabel); } static void mac_test_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel) { ASSERT_MBUF_LABEL(oldmbuflabel); ASSERT_MBUF_LABEL(newmbuflabel); } static void mac_test_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel) { ASSERT_IFNET_LABEL(ifnetlabel); ASSERT_MBUF_LABEL(mbuflabel); } static void mac_test_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, struct mbuf *mbuf, struct label *mbuflabel) { ASSERT_BPF_LABEL(bpflabel); ASSERT_MBUF_LABEL(mbuflabel); } static void mac_test_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel) { ASSERT_IFNET_LABEL(ifnetlabel); ASSERT_MBUF_LABEL(mbuflabel); } static void mac_test_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *newmbuf, struct label *newmbuflabel) { ASSERT_MBUF_LABEL(oldmbuflabel); ASSERT_IFNET_LABEL(ifnetlabel); ASSERT_MBUF_LABEL(newmbuflabel); } static void mac_test_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel) { ASSERT_MBUF_LABEL(oldmbuflabel); ASSERT_MBUF_LABEL(newmbuflabel); } static int mac_test_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { ASSERT_MBUF_LABEL(fragmentlabel); ASSERT_IPQ_LABEL(ipqlabel); return (1); } static void mac_test_reflect_mbuf_icmp(struct mbuf *m, struct label *mlabel) { ASSERT_MBUF_LABEL(mlabel); } static void mac_test_reflect_mbuf_tcp(struct mbuf *m, struct label *mlabel) { ASSERT_MBUF_LABEL(mlabel); } static void mac_test_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_IFNET_LABEL(ifnetlabel); ASSERT_IFNET_LABEL(newlabel); } static void mac_test_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { ASSERT_MBUF_LABEL(fragmentlabel); ASSERT_IPQ_LABEL(ipqlabel); } static void mac_test_inpcb_sosetlabel(struct socket *so, struct label *solabel, struct inpcb *inp, struct label *inplabel) { ASSERT_SOCKET_LABEL(solabel); ASSERT_INPCB_LABEL(inplabel); } /* * Labeling event operations: processes. */ static void mac_test_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, struct label *filelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel) { ASSERT_CRED_LABEL(old->cr_label); ASSERT_CRED_LABEL(new->cr_label); ASSERT_VNODE_LABEL(filelabel); if (interpvnodelabel != NULL) { ASSERT_VNODE_LABEL(interpvnodelabel); } if (execlabel != NULL) { ASSERT_CRED_LABEL(execlabel); } } static int mac_test_execve_will_transition(struct ucred *old, struct vnode *vp, struct label *filelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel) { ASSERT_CRED_LABEL(old->cr_label); ASSERT_VNODE_LABEL(filelabel); if (interpvnodelabel != NULL) { ASSERT_VNODE_LABEL(interpvnodelabel); } if (execlabel != NULL) { ASSERT_CRED_LABEL(execlabel); } return (0); } static void mac_test_create_proc0(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); } static void mac_test_create_proc1(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); } static void mac_test_relabel_cred(struct ucred *cred, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_CRED_LABEL(newlabel); } static void mac_test_thread_userret(struct thread *td) { printf("mac_test_thread_userret(process = %d)\n", curthread->td_proc->p_pid); } /* * Label cleanup/flush operations */ static void mac_test_cleanup_sysv_msgmsg(struct label *msglabel) { ASSERT_SYSVIPCMSG_LABEL(msglabel); } static void mac_test_cleanup_sysv_msgqueue(struct label *msqlabel) { ASSERT_SYSVIPCMSQ_LABEL(msqlabel); } static void mac_test_cleanup_sysv_sema(struct label *semalabel) { ASSERT_SYSVIPCSEM_LABEL(semalabel); } static void mac_test_cleanup_sysv_shm(struct label *shmlabel) { ASSERT_SYSVIPCSHM_LABEL(shmlabel); } /* * Access control checks. */ static int mac_test_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, struct ifnet *ifnet, struct label *ifnetlabel) { ASSERT_BPF_LABEL(bpflabel); ASSERT_IFNET_LABEL(ifnetlabel); return (0); } static int mac_test_check_cred_relabel(struct ucred *cred, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_CRED_LABEL(newlabel); return (0); } static int mac_test_check_cred_visible(struct ucred *u1, struct ucred *u2) { ASSERT_CRED_LABEL(u1->cr_label); ASSERT_CRED_LABEL(u2->cr_label); return (0); } static int mac_test_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_IFNET_LABEL(ifnetlabel); ASSERT_IFNET_LABEL(newlabel); return (0); } static int mac_test_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel) { ASSERT_IFNET_LABEL(ifnetlabel); ASSERT_MBUF_LABEL(mbuflabel); return (0); } static int mac_test_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel) { ASSERT_INPCB_LABEL(inplabel); ASSERT_MBUF_LABEL(mlabel); return (0); } static int mac_test_check_sysv_msgmsq(struct ucred *cred, struct msg *msgptr, struct label *msglabel, struct msqid_kernel *msqkptr, struct label *msqklabel) { ASSERT_SYSVIPCMSQ_LABEL(msqklabel); ASSERT_SYSVIPCMSG_LABEL(msglabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, struct label *msglabel) { ASSERT_SYSVIPCMSG_LABEL(msglabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, struct label *msglabel) { ASSERT_SYSVIPCMSG_LABEL(msglabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel) { ASSERT_SYSVIPCMSQ_LABEL(msqklabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel) { ASSERT_SYSVIPCMSQ_LABEL(msqklabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel) { ASSERT_SYSVIPCMSQ_LABEL(msqklabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel, int cmd) { ASSERT_SYSVIPCMSQ_LABEL(msqklabel); ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, int cmd) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSEM_LABEL(semaklabel); return (0); } static int mac_test_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSEM_LABEL(semaklabel); return (0); } static int mac_test_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, size_t accesstype) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSEM_LABEL(semaklabel); return (0); } static int mac_test_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSHM_LABEL(shmseglabel); return (0); } static int mac_test_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int cmd) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSHM_LABEL(shmseglabel); return (0); } static int mac_test_check_sysv_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSHM_LABEL(shmseglabel); return (0); } static int mac_test_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SYSVIPCSHM_LABEL(shmseglabel); return (0); } static int mac_test_check_kenv_dump(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_kenv_get(struct ucred *cred, char *name) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_kenv_set(struct ucred *cred, char *name, char *value) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_kenv_unset(struct ucred *cred, char *name) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_kld_load(struct ucred *cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_kld_stat(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_kld_unload(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_mount_stat(struct ucred *cred, struct mount *mp, struct label *mntlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_MOUNT_LABEL(mntlabel); return (0); } static int mac_test_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); return (0); } static int mac_test_check_pipe_poll(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); return (0); } static int mac_test_check_pipe_read(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); return (0); } static int mac_test_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); ASSERT_PIPE_LABEL(newlabel); return (0); } static int mac_test_check_pipe_stat(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); return (0); } static int mac_test_check_pipe_write(struct ucred *cred, struct pipepair *pp, struct label *pipelabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_PIPE_LABEL(pipelabel); return (0); } static int mac_test_check_proc_debug(struct ucred *cred, struct proc *proc) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_CRED_LABEL(proc->p_ucred->cr_label); return (0); } static int mac_test_check_proc_sched(struct ucred *cred, struct proc *proc) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_CRED_LABEL(proc->p_ucred->cr_label); return (0); } static int mac_test_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_CRED_LABEL(proc->p_ucred->cr_label); return (0); } static int mac_test_check_proc_setuid(struct ucred *cred, uid_t uid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_seteuid(struct ucred *cred, uid_t euid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setgid(struct ucred *cred, gid_t gid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setegid(struct ucred *cred, gid_t egid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setgroups(struct ucred *cred, int ngroups, gid_t *gidset) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setreuid(struct ucred *cred, uid_t ruid, uid_t euid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setregid(struct ucred *cred, gid_t rgid, gid_t egid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setresuid(struct ucred *cred, uid_t ruid, uid_t euid, uid_t suid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_proc_setresgid(struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int +mac_test_check_socket_accept(struct ucred *cred, struct socket *socket, + struct label *socketlabel) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_SOCKET_LABEL(socketlabel); + + return (0); +} + +static int mac_test_check_socket_bind(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct sockaddr *sockaddr) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(socketlabel); return (0); } static int mac_test_check_socket_connect(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct sockaddr *sockaddr) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(socketlabel); return (0); } static int mac_test_check_socket_deliver(struct socket *socket, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { ASSERT_SOCKET_LABEL(socketlabel); ASSERT_MBUF_LABEL(mbuflabel); return (0); } static int mac_test_check_socket_listen(struct ucred *cred, struct socket *socket, struct label *socketlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(socketlabel); return (0); } static int -mac_test_check_socket_visible(struct ucred *cred, struct socket *socket, +mac_test_check_socket_poll(struct ucred *cred, struct socket *socket, struct label *socketlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(socketlabel); return (0); } static int +mac_test_check_socket_receive(struct ucred *cred, struct socket *socket, + struct label *socketlabel) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_SOCKET_LABEL(socketlabel); + + return (0); +} + +static int mac_test_check_socket_relabel(struct ucred *cred, struct socket *socket, struct label *socketlabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_SOCKET_LABEL(socketlabel); ASSERT_SOCKET_LABEL(newlabel); return (0); } static int +mac_test_check_socket_send(struct ucred *cred, struct socket *socket, + struct label *socketlabel) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_SOCKET_LABEL(socketlabel); + + return (0); +} + +static int +mac_test_check_socket_stat(struct ucred *cred, struct socket *socket, + struct label *socketlabel) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_SOCKET_LABEL(socketlabel); + + return (0); +} + +static int +mac_test_check_socket_visible(struct ucred *cred, struct socket *socket, + struct label *socketlabel) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_SOCKET_LABEL(socketlabel); + + return (0); +} + +static int mac_test_check_sysarch_ioperm(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_system_acct(struct ucred *cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_system_reboot(struct ucred *cred, int how) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_system_settime(struct ucred *cred) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_system_swapon(struct ucred *cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_system_swapoff(struct ucred *cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req) { ASSERT_CRED_LABEL(cred->cr_label); return (0); } static int mac_test_check_vnode_access(struct ucred *cred, struct vnode *vp, struct label *label, int acc_mode) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, struct label *dlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); return (0); } static int mac_test_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, struct label *dlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); return (0); } static int mac_test_check_vnode_create(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp, struct vattr *vap) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); return (0); } static int mac_test_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_exec(struct ucred *cred, struct vnode *vp, struct label *label, struct image_params *imgp, struct label *execlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); if (execlabel != NULL) { ASSERT_CRED_LABEL(execlabel); } return (0); } static int mac_test_check_vnode_getacl(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_link(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); return (0); } static int mac_test_check_vnode_mmap(struct ucred *cred, struct vnode *vp, struct label *label, int prot, int flags) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_open(struct ucred *cred, struct vnode *vp, struct label *filelabel, int acc_mode) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(filelabel); return (0); } static int mac_test_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(active_cred->cr_label); ASSERT_CRED_LABEL(file_cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(active_cred->cr_label); if (file_cred != NULL) { ASSERT_CRED_LABEL(file_cred->cr_label); } ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, struct label *dlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); return (0); } static int mac_test_check_vnode_readlink(struct ucred *cred, struct vnode *vp, struct label *vnodelabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(vnodelabel); return (0); } static int mac_test_check_vnode_relabel(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *newlabel) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(vnodelabel); ASSERT_VNODE_LABEL(newlabel); return (0); } static int mac_test_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, int samedir, struct componentname *cnp) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(dlabel); if (vp != NULL) { ASSERT_VNODE_LABEL(label); } return (0); } static int mac_test_check_vnode_revoke(struct ucred *cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_setacl(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type, struct acl *acl) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_setflags(struct ucred *cred, struct vnode *vp, struct label *label, u_long flags) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_setmode(struct ucred *cred, struct vnode *vp, struct label *label, mode_t mode) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_setowner(struct ucred *cred, struct vnode *vp, struct label *label, uid_t uid, gid_t gid) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, struct label *label, struct timespec atime, struct timespec mtime) { ASSERT_CRED_LABEL(cred->cr_label); ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(active_cred->cr_label); if (file_cred != NULL) { ASSERT_CRED_LABEL(file_cred->cr_label); } ASSERT_VNODE_LABEL(label); return (0); } static int mac_test_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label) { ASSERT_CRED_LABEL(active_cred->cr_label); if (file_cred != NULL) { ASSERT_CRED_LABEL(file_cred->cr_label); } ASSERT_VNODE_LABEL(label); return (0); } static struct mac_policy_ops mac_test_ops = { .mpo_destroy = mac_test_destroy, .mpo_init = mac_test_init, .mpo_syscall = mac_test_syscall, .mpo_init_bpfdesc_label = mac_test_init_bpfdesc_label, .mpo_init_cred_label = mac_test_init_cred_label, .mpo_init_devfsdirent_label = mac_test_init_devfsdirent_label, .mpo_init_ifnet_label = mac_test_init_ifnet_label, .mpo_init_sysv_msgmsg_label = mac_test_init_sysv_msgmsg_label, .mpo_init_sysv_msgqueue_label = mac_test_init_sysv_msgqueue_label, .mpo_init_sysv_sema_label = mac_test_init_sysv_sema_label, .mpo_init_sysv_shm_label = mac_test_init_sysv_shm_label, .mpo_init_inpcb_label = mac_test_init_inpcb_label, .mpo_init_ipq_label = mac_test_init_ipq_label, .mpo_init_mbuf_label = mac_test_init_mbuf_label, .mpo_init_mount_label = mac_test_init_mount_label, .mpo_init_mount_fs_label = mac_test_init_mount_fs_label, .mpo_init_pipe_label = mac_test_init_pipe_label, .mpo_init_proc_label = mac_test_init_proc_label, .mpo_init_socket_label = mac_test_init_socket_label, .mpo_init_socket_peer_label = mac_test_init_socket_peer_label, .mpo_init_vnode_label = mac_test_init_vnode_label, .mpo_destroy_bpfdesc_label = mac_test_destroy_bpfdesc_label, .mpo_destroy_cred_label = mac_test_destroy_cred_label, .mpo_destroy_devfsdirent_label = mac_test_destroy_devfsdirent_label, .mpo_destroy_ifnet_label = mac_test_destroy_ifnet_label, .mpo_destroy_sysv_msgmsg_label = mac_test_destroy_sysv_msgmsg_label, .mpo_destroy_sysv_msgqueue_label = mac_test_destroy_sysv_msgqueue_label, .mpo_destroy_sysv_sema_label = mac_test_destroy_sysv_sema_label, .mpo_destroy_sysv_shm_label = mac_test_destroy_sysv_shm_label, .mpo_destroy_inpcb_label = mac_test_destroy_inpcb_label, .mpo_destroy_ipq_label = mac_test_destroy_ipq_label, .mpo_destroy_mbuf_label = mac_test_destroy_mbuf_label, .mpo_destroy_mount_label = mac_test_destroy_mount_label, .mpo_destroy_mount_fs_label = mac_test_destroy_mount_fs_label, .mpo_destroy_pipe_label = mac_test_destroy_pipe_label, .mpo_destroy_proc_label = mac_test_destroy_proc_label, .mpo_destroy_socket_label = mac_test_destroy_socket_label, .mpo_destroy_socket_peer_label = mac_test_destroy_socket_peer_label, .mpo_destroy_vnode_label = mac_test_destroy_vnode_label, .mpo_copy_cred_label = mac_test_copy_cred_label, .mpo_copy_ifnet_label = mac_test_copy_ifnet_label, .mpo_copy_mbuf_label = mac_test_copy_mbuf_label, .mpo_copy_pipe_label = mac_test_copy_pipe_label, .mpo_copy_socket_label = mac_test_copy_socket_label, .mpo_copy_vnode_label = mac_test_copy_vnode_label, .mpo_externalize_cred_label = mac_test_externalize_label, .mpo_externalize_ifnet_label = mac_test_externalize_label, .mpo_externalize_pipe_label = mac_test_externalize_label, .mpo_externalize_socket_label = mac_test_externalize_label, .mpo_externalize_socket_peer_label = mac_test_externalize_label, .mpo_externalize_vnode_label = mac_test_externalize_label, .mpo_internalize_cred_label = mac_test_internalize_label, .mpo_internalize_ifnet_label = mac_test_internalize_label, .mpo_internalize_pipe_label = mac_test_internalize_label, .mpo_internalize_socket_label = mac_test_internalize_label, .mpo_internalize_vnode_label = mac_test_internalize_label, .mpo_associate_vnode_devfs = mac_test_associate_vnode_devfs, .mpo_associate_vnode_extattr = mac_test_associate_vnode_extattr, .mpo_associate_vnode_singlelabel = mac_test_associate_vnode_singlelabel, .mpo_create_devfs_device = mac_test_create_devfs_device, .mpo_create_devfs_directory = mac_test_create_devfs_directory, .mpo_create_devfs_symlink = mac_test_create_devfs_symlink, .mpo_create_vnode_extattr = mac_test_create_vnode_extattr, .mpo_create_mount = mac_test_create_mount, .mpo_create_root_mount = mac_test_create_root_mount, .mpo_relabel_vnode = mac_test_relabel_vnode, .mpo_setlabel_vnode_extattr = mac_test_setlabel_vnode_extattr, .mpo_update_devfsdirent = mac_test_update_devfsdirent, .mpo_create_mbuf_from_socket = mac_test_create_mbuf_from_socket, .mpo_create_pipe = mac_test_create_pipe, .mpo_create_socket = mac_test_create_socket, .mpo_create_socket_from_socket = mac_test_create_socket_from_socket, .mpo_relabel_pipe = mac_test_relabel_pipe, .mpo_relabel_socket = mac_test_relabel_socket, .mpo_set_socket_peer_from_mbuf = mac_test_set_socket_peer_from_mbuf, .mpo_set_socket_peer_from_socket = mac_test_set_socket_peer_from_socket, .mpo_create_bpfdesc = mac_test_create_bpfdesc, .mpo_create_ifnet = mac_test_create_ifnet, .mpo_create_inpcb_from_socket = mac_test_create_inpcb_from_socket, .mpo_create_sysv_msgmsg = mac_test_create_sysv_msgmsg, .mpo_create_sysv_msgqueue = mac_test_create_sysv_msgqueue, .mpo_create_sysv_sema = mac_test_create_sysv_sema, .mpo_create_sysv_shm = mac_test_create_sysv_shm, .mpo_create_datagram_from_ipq = mac_test_create_datagram_from_ipq, .mpo_create_fragment = mac_test_create_fragment, .mpo_create_ipq = mac_test_create_ipq, .mpo_create_mbuf_from_inpcb = mac_test_create_mbuf_from_inpcb, .mpo_create_mbuf_from_mbuf = mac_test_create_mbuf_from_mbuf, .mpo_create_mbuf_linklayer = mac_test_create_mbuf_linklayer, .mpo_create_mbuf_from_bpfdesc = mac_test_create_mbuf_from_bpfdesc, .mpo_create_mbuf_from_ifnet = mac_test_create_mbuf_from_ifnet, .mpo_create_mbuf_multicast_encap = mac_test_create_mbuf_multicast_encap, .mpo_create_mbuf_netlayer = mac_test_create_mbuf_netlayer, .mpo_fragment_match = mac_test_fragment_match, .mpo_reflect_mbuf_icmp = mac_test_reflect_mbuf_icmp, .mpo_reflect_mbuf_tcp = mac_test_reflect_mbuf_tcp, .mpo_relabel_ifnet = mac_test_relabel_ifnet, .mpo_update_ipq = mac_test_update_ipq, .mpo_inpcb_sosetlabel = mac_test_inpcb_sosetlabel, .mpo_execve_transition = mac_test_execve_transition, .mpo_execve_will_transition = mac_test_execve_will_transition, .mpo_create_proc0 = mac_test_create_proc0, .mpo_create_proc1 = mac_test_create_proc1, .mpo_relabel_cred = mac_test_relabel_cred, .mpo_thread_userret = mac_test_thread_userret, .mpo_cleanup_sysv_msgmsg = mac_test_cleanup_sysv_msgmsg, .mpo_cleanup_sysv_msgqueue = mac_test_cleanup_sysv_msgqueue, .mpo_cleanup_sysv_sema = mac_test_cleanup_sysv_sema, .mpo_cleanup_sysv_shm = mac_test_cleanup_sysv_shm, .mpo_check_bpfdesc_receive = mac_test_check_bpfdesc_receive, .mpo_check_cred_relabel = mac_test_check_cred_relabel, .mpo_check_cred_visible = mac_test_check_cred_visible, .mpo_check_ifnet_relabel = mac_test_check_ifnet_relabel, .mpo_check_ifnet_transmit = mac_test_check_ifnet_transmit, .mpo_check_inpcb_deliver = mac_test_check_inpcb_deliver, .mpo_check_sysv_msgmsq = mac_test_check_sysv_msgmsq, .mpo_check_sysv_msgrcv = mac_test_check_sysv_msgrcv, .mpo_check_sysv_msgrmid = mac_test_check_sysv_msgrmid, .mpo_check_sysv_msqget = mac_test_check_sysv_msqget, .mpo_check_sysv_msqsnd = mac_test_check_sysv_msqsnd, .mpo_check_sysv_msqrcv = mac_test_check_sysv_msqrcv, .mpo_check_sysv_msqctl = mac_test_check_sysv_msqctl, .mpo_check_sysv_semctl = mac_test_check_sysv_semctl, .mpo_check_sysv_semget = mac_test_check_sysv_semget, .mpo_check_sysv_semop = mac_test_check_sysv_semop, .mpo_check_sysv_shmat = mac_test_check_sysv_shmat, .mpo_check_sysv_shmctl = mac_test_check_sysv_shmctl, .mpo_check_sysv_shmdt = mac_test_check_sysv_shmdt, .mpo_check_sysv_shmget = mac_test_check_sysv_shmget, .mpo_check_kenv_dump = mac_test_check_kenv_dump, .mpo_check_kenv_get = mac_test_check_kenv_get, .mpo_check_kenv_set = mac_test_check_kenv_set, .mpo_check_kenv_unset = mac_test_check_kenv_unset, .mpo_check_kld_load = mac_test_check_kld_load, .mpo_check_kld_stat = mac_test_check_kld_stat, .mpo_check_kld_unload = mac_test_check_kld_unload, .mpo_check_mount_stat = mac_test_check_mount_stat, .mpo_check_pipe_ioctl = mac_test_check_pipe_ioctl, .mpo_check_pipe_poll = mac_test_check_pipe_poll, .mpo_check_pipe_read = mac_test_check_pipe_read, .mpo_check_pipe_relabel = mac_test_check_pipe_relabel, .mpo_check_pipe_stat = mac_test_check_pipe_stat, .mpo_check_pipe_write = mac_test_check_pipe_write, .mpo_check_proc_debug = mac_test_check_proc_debug, .mpo_check_proc_sched = mac_test_check_proc_sched, .mpo_check_proc_setuid = mac_test_check_proc_setuid, .mpo_check_proc_seteuid = mac_test_check_proc_seteuid, .mpo_check_proc_setgid = mac_test_check_proc_setgid, .mpo_check_proc_setegid = mac_test_check_proc_setegid, .mpo_check_proc_setgroups = mac_test_check_proc_setgroups, .mpo_check_proc_setreuid = mac_test_check_proc_setreuid, .mpo_check_proc_setregid = mac_test_check_proc_setregid, .mpo_check_proc_setresuid = mac_test_check_proc_setresuid, .mpo_check_proc_setresgid = mac_test_check_proc_setresgid, .mpo_check_proc_signal = mac_test_check_proc_signal, + .mpo_check_socket_accept = mac_test_check_socket_accept, .mpo_check_socket_bind = mac_test_check_socket_bind, .mpo_check_socket_connect = mac_test_check_socket_connect, .mpo_check_socket_deliver = mac_test_check_socket_deliver, .mpo_check_socket_listen = mac_test_check_socket_listen, + .mpo_check_socket_poll = mac_test_check_socket_poll, + .mpo_check_socket_receive = mac_test_check_socket_receive, .mpo_check_socket_relabel = mac_test_check_socket_relabel, + .mpo_check_socket_send = mac_test_check_socket_send, + .mpo_check_socket_stat = mac_test_check_socket_stat, .mpo_check_socket_visible = mac_test_check_socket_visible, .mpo_check_sysarch_ioperm = mac_test_check_sysarch_ioperm, .mpo_check_system_acct = mac_test_check_system_acct, .mpo_check_system_reboot = mac_test_check_system_reboot, .mpo_check_system_settime = mac_test_check_system_settime, .mpo_check_system_swapon = mac_test_check_system_swapon, .mpo_check_system_swapoff = mac_test_check_system_swapoff, .mpo_check_system_sysctl = mac_test_check_system_sysctl, .mpo_check_vnode_access = mac_test_check_vnode_access, .mpo_check_vnode_chdir = mac_test_check_vnode_chdir, .mpo_check_vnode_chroot = mac_test_check_vnode_chroot, .mpo_check_vnode_create = mac_test_check_vnode_create, .mpo_check_vnode_delete = mac_test_check_vnode_delete, .mpo_check_vnode_deleteacl = mac_test_check_vnode_deleteacl, .mpo_check_vnode_deleteextattr = mac_test_check_vnode_deleteextattr, .mpo_check_vnode_exec = mac_test_check_vnode_exec, .mpo_check_vnode_getacl = mac_test_check_vnode_getacl, .mpo_check_vnode_getextattr = mac_test_check_vnode_getextattr, .mpo_check_vnode_link = mac_test_check_vnode_link, .mpo_check_vnode_listextattr = mac_test_check_vnode_listextattr, .mpo_check_vnode_lookup = mac_test_check_vnode_lookup, .mpo_check_vnode_mmap = mac_test_check_vnode_mmap, .mpo_check_vnode_open = mac_test_check_vnode_open, .mpo_check_vnode_poll = mac_test_check_vnode_poll, .mpo_check_vnode_read = mac_test_check_vnode_read, .mpo_check_vnode_readdir = mac_test_check_vnode_readdir, .mpo_check_vnode_readlink = mac_test_check_vnode_readlink, .mpo_check_vnode_relabel = mac_test_check_vnode_relabel, .mpo_check_vnode_rename_from = mac_test_check_vnode_rename_from, .mpo_check_vnode_rename_to = mac_test_check_vnode_rename_to, .mpo_check_vnode_revoke = mac_test_check_vnode_revoke, .mpo_check_vnode_setacl = mac_test_check_vnode_setacl, .mpo_check_vnode_setextattr = mac_test_check_vnode_setextattr, .mpo_check_vnode_setflags = mac_test_check_vnode_setflags, .mpo_check_vnode_setmode = mac_test_check_vnode_setmode, .mpo_check_vnode_setowner = mac_test_check_vnode_setowner, .mpo_check_vnode_setutimes = mac_test_check_vnode_setutimes, .mpo_check_vnode_stat = mac_test_check_vnode_stat, .mpo_check_vnode_write = mac_test_check_vnode_write, }; MAC_POLICY_SET(&mac_test_ops, mac_test, "TrustedBSD MAC/Test", MPC_LOADTIME_FLAG_UNLOADOK | MPC_LOADTIME_FLAG_LABELMBUFS, &test_slot); Index: head/sys/sys/mac.h =================================================================== --- head/sys/sys/mac.h (revision 145166) +++ head/sys/sys/mac.h (revision 145167) @@ -1,450 +1,454 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson - * Copyright (c) 2001-2003 Networks Associates Technology, Inc. + * Copyright (c) 2001-2005 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * This software was developed for the FreeBSD Project in part by Network * Associates Laboratories, the Security Research Division of Network * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), * as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Userland/kernel interface for Mandatory Access Control. * * The POSIX.1e implementation page may be reached at: * http://www.trustedbsd.org/ */ + #ifndef _SYS_MAC_H_ #define _SYS_MAC_H_ #include #ifndef _POSIX_MAC #define _POSIX_MAC #endif /* * MAC framework-related constants and limits. */ #define MAC_MAX_POLICY_NAME 32 #define MAC_MAX_LABEL_ELEMENT_NAME 32 #define MAC_MAX_LABEL_ELEMENT_DATA 4096 #define MAC_MAX_LABEL_BUF_LEN 8192 struct mac { size_t m_buflen; char *m_string; }; typedef struct mac *mac_t; #ifndef _KERNEL /* * Location of the userland MAC framework configuration file. mac.conf * binds policy names to shared libraries that understand those policies, * as well as setting defaults for MAC-aware applications. */ #define MAC_CONFFILE "/etc/mac.conf" /* * Extended non-POSIX.1e interfaces that offer additional services * available from the userland and kernel MAC frameworks. */ __BEGIN_DECLS int mac_execve(char *fname, char **argv, char **envv, mac_t _label); int mac_free(mac_t _label); int mac_from_text(mac_t *_label, const char *_text); int mac_get_fd(int _fd, mac_t _label); int mac_get_file(const char *_path, mac_t _label); int mac_get_link(const char *_path, mac_t _label); int mac_get_peer(int _fd, mac_t _label); int mac_get_pid(pid_t _pid, mac_t _label); int mac_get_proc(mac_t _label); int mac_is_present(const char *_policyname); int mac_prepare(mac_t *_label, const char *_elements); int mac_prepare_file_label(mac_t *_label); int mac_prepare_ifnet_label(mac_t *_label); int mac_prepare_process_label(mac_t *_label); int mac_prepare_type(mac_t *_label, const char *_type); int mac_set_fd(int _fildes, const mac_t _label); int mac_set_file(const char *_path, mac_t _label); int mac_set_link(const char *_path, mac_t _label); int mac_set_proc(const mac_t _label); int mac_syscall(const char *_policyname, int _call, void *_arg); int mac_to_text(mac_t mac, char **_text); __END_DECLS #else /* _KERNEL */ /* * Kernel functions to manage and evaluate labels. */ struct bpf_d; struct cdev; struct componentname; struct devfs_dirent; struct ifnet; struct ifreq; struct inpcb; struct image_params; struct inpcb; struct ipq; struct m_tag; struct mbuf; struct mount; struct msg; struct msqid_kernel; struct proc; struct semid_kernel; struct shmid_kernel; struct sockaddr; struct socket; struct sysctl_oid; struct sysctl_req; struct pipepair; struct thread; struct timespec; struct ucred; struct uio; struct vattr; struct vnode; #include /* XXX acl_type_t */ struct vop_setlabel_args; /* * Label operations. */ void mac_init_bpfdesc(struct bpf_d *); void mac_init_cred(struct ucred *); void mac_init_devfsdirent(struct devfs_dirent *); void mac_init_ifnet(struct ifnet *); int mac_init_inpcb(struct inpcb *, int flag); void mac_init_sysv_msgmsg(struct msg *); void mac_init_sysv_msgqueue(struct msqid_kernel*); void mac_init_sysv_sema(struct semid_kernel*); void mac_init_sysv_shm(struct shmid_kernel*); int mac_init_ipq(struct ipq *, int flag); int mac_init_socket(struct socket *, int flag); void mac_init_pipe(struct pipepair *); int mac_init_mbuf(struct mbuf *mbuf, int flag); int mac_init_mbuf_tag(struct m_tag *, int flag); void mac_init_mount(struct mount *); void mac_init_proc(struct proc *); void mac_init_vnode(struct vnode *); void mac_copy_mbuf_tag(struct m_tag *, struct m_tag *); void mac_copy_vnode_label(struct label *, struct label *label); void mac_destroy_bpfdesc(struct bpf_d *); void mac_destroy_cred(struct ucred *); void mac_destroy_devfsdirent(struct devfs_dirent *); void mac_destroy_ifnet(struct ifnet *); void mac_destroy_inpcb(struct inpcb *); void mac_destroy_sysv_msgmsg(struct msg *); void mac_destroy_sysv_msgqueue(struct msqid_kernel *); void mac_destroy_sysv_sema(struct semid_kernel *); void mac_destroy_sysv_shm(struct shmid_kernel *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); void mac_destroy_pipe(struct pipepair *); void mac_destroy_proc(struct proc *); void mac_destroy_mbuf_tag(struct m_tag *); void mac_destroy_mount(struct mount *); void mac_destroy_vnode(struct vnode *); struct label *mac_cred_label_alloc(void); void mac_cred_label_free(struct label *label); struct label *mac_vnode_label_alloc(void); void mac_vnode_label_free(struct label *label); /* * Labeling event operations: file system objects, and things that * look a lot like file system objects. */ void mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, struct vnode *vp); int mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp); void mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp); void mac_create_devfs_device(struct mount *mp, struct cdev *dev, struct devfs_dirent *de); void mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *de); void mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct devfs_dirent *de); int mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); void mac_create_mount(struct ucred *cred, struct mount *mp); void mac_create_root_mount(struct ucred *cred, struct mount *mp); void mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel); void mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, struct vnode *vp); /* * Labeling event operations: IPC objects. */ void mac_create_mbuf_from_socket(struct socket *so, struct mbuf *m); void mac_create_socket(struct ucred *cred, struct socket *socket); void mac_create_socket_from_socket(struct socket *oldsocket, struct socket *newsocket); void mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket); void mac_set_socket_peer_from_socket(struct socket *oldsocket, struct socket *newsocket); void mac_create_pipe(struct ucred *cred, struct pipepair *pp); /* * Labeling event operations: System V IPC primitives */ void mac_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, struct msg *msgptr); void mac_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr); void mac_create_sysv_sema(struct ucred *cred, struct semid_kernel *semakptr); void mac_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr); /* * Labeling event operations: network objects. */ void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); void mac_create_ifnet(struct ifnet *ifp); void mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp); void mac_create_ipq(struct mbuf *fragment, struct ipq *ipq); void mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram); void mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment); void mac_create_mbuf_from_inpcb(struct inpcb *inp, struct mbuf *m); void mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf); void mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *m); void mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *m); void mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *m); void mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, struct mbuf *newmbuf); void mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf); int mac_fragment_match(struct mbuf *fragment, struct ipq *ipq); void mac_reflect_mbuf_icmp(struct mbuf *m); void mac_reflect_mbuf_tcp(struct mbuf *m); void mac_update_ipq(struct mbuf *fragment, struct ipq *ipq); void mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp); /* * Labeling event operations: processes. */ void mac_copy_cred(struct ucred *cr1, struct ucred *cr2); int mac_execve_enter(struct image_params *imgp, struct mac *mac_p); void mac_execve_exit(struct image_params *imgp); void mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, struct label *interpvnodelabel, struct image_params *imgp); int mac_execve_will_transition(struct ucred *old, struct vnode *vp, struct label *interpvnodelabel, struct image_params *imgp); void mac_create_proc0(struct ucred *cred); void mac_create_proc1(struct ucred *cred); void mac_thread_userret(struct thread *td); /* * Label cleanup operation: This is the inverse complement for the * mac_create and associate type of hooks. This hook lets the policy * module(s) perform a cleanup/flushing operation on the label * associated with the objects, without freeing up the space allocated. * This hook is useful in cases where it is desirable to remove any * labeling reference when recycling any object to a pool. This hook * does not replace the mac_destroy hooks. */ void mac_cleanup_sysv_msgmsg(struct msg *msgptr); void mac_cleanup_sysv_msgqueue(struct msqid_kernel *msqkptr); void mac_cleanup_sysv_sema(struct semid_kernel *semakptr); void mac_cleanup_sysv_shm(struct shmid_kernel *shmsegptr); /* Access control checks. */ int mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet); int mac_check_cred_visible(struct ucred *u1, struct ucred *u2); int mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *m); int mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m); int mac_check_sysv_msgmsq(struct ucred *cred, struct msg *msgptr, struct msqid_kernel *msqkptr); int mac_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr); int mac_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr); int mac_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr); int mac_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr); int mac_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr); int mac_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, int cmd); int mac_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, int cmd); int mac_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr); int mac_check_sysv_semop(struct ucred *cred,struct semid_kernel *semakptr, size_t accesstype); int mac_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, int shmflg); int mac_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, int cmd); int mac_check_sysv_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr); int mac_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, int shmflg); int mac_check_kenv_dump(struct ucred *cred); int mac_check_kenv_get(struct ucred *cred, char *name); int mac_check_kenv_set(struct ucred *cred, char *name, char *value); int mac_check_kenv_unset(struct ucred *cred, char *name); int mac_check_kld_load(struct ucred *cred, struct vnode *vp); int mac_check_kld_stat(struct ucred *cred); int mac_check_kld_unload(struct ucred *cred); int mac_check_mount_stat(struct ucred *cred, struct mount *mp); int mac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, unsigned long cmd, void *data); int mac_check_pipe_poll(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_read(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_stat(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_write(struct ucred *cred, struct pipepair *pp); int mac_check_proc_debug(struct ucred *cred, struct proc *proc); int mac_check_proc_sched(struct ucred *cred, struct proc *proc); int mac_check_proc_setuid(struct proc *proc, struct ucred *cred, uid_t uid); int mac_check_proc_seteuid(struct proc *proc, struct ucred *cred, uid_t euid); int mac_check_proc_setgid(struct proc *proc, struct ucred *cred, gid_t gid); int mac_check_proc_setegid(struct proc *proc, struct ucred *cred, gid_t egid); int mac_check_proc_setgroups(struct proc *proc, struct ucred *cred, int ngroups, gid_t *gidset); int mac_check_proc_setreuid(struct proc *proc, struct ucred *cred, uid_t ruid, uid_t euid); int mac_check_proc_setregid(struct proc *proc, struct ucred *cred, gid_t rgid, gid_t egid); int mac_check_proc_setresuid(struct proc *proc, struct ucred *cred, uid_t ruid, uid_t euid, uid_t suid); int mac_check_proc_setresgid(struct proc *proc, struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid); int mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum); +int mac_check_socket_accept(struct ucred *cred, struct socket *so); int mac_check_socket_bind(struct ucred *cred, struct socket *so, struct sockaddr *sockaddr); int mac_check_socket_connect(struct ucred *cred, struct socket *so, struct sockaddr *sockaddr); int mac_check_socket_deliver(struct socket *so, struct mbuf *m); int mac_check_socket_listen(struct ucred *cred, struct socket *so); +int mac_check_socket_poll(struct ucred *cred, struct socket *so); int mac_check_socket_receive(struct ucred *cred, struct socket *so); int mac_check_socket_send(struct ucred *cred, struct socket *so); +int mac_check_socket_stat(struct ucred *cred, struct socket *so); int mac_check_socket_visible(struct ucred *cred, struct socket *so); int mac_check_sysarch_ioperm(struct ucred *cred); int mac_check_system_acct(struct ucred *cred, struct vnode *vp); int mac_check_system_nfsd(struct ucred *cred); int mac_check_system_reboot(struct ucred *cred, int howto); int mac_check_system_settime(struct ucred *cred); int mac_check_system_swapon(struct ucred *cred, struct vnode *vp); int mac_check_system_swapoff(struct ucred *cred, struct vnode *vp); int mac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); int mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode); int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp); int mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp); int mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, struct componentname *cnp, struct vattr *vap); int mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, acl_type_t type); int mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name); int mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, struct image_params *imgp); int mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type); int mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name, struct uio *uio); int mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, int attrnamespace); int mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct componentname *cnp); int mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot, int flags); int mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot); int mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode); int mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_check_vnode_readdir(struct ucred *cred, struct vnode *vp); int mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp); int mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, struct vnode *vp, int samedir, struct componentname *cnp); int mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp); int mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, struct acl *acl); int mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name, struct uio *uio); int mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags); int mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode); int mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, gid_t gid); int mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, struct timespec atime, struct timespec mtime); int mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp); int mac_getsockopt_label(struct ucred *cred, struct socket *so, struct mac *extmac); int mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, struct mac *extmac); int mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifnet); int mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifnet); int mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *extmac); int mac_pipe_label_set(struct ucred *cred, struct pipepair *pp, struct label *label); void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred); /* * Calls to help various file systems implement labeling functionality * using their existing EA implementation. */ int vop_stdsetlabel_ea(struct vop_setlabel_args *ap); #endif /* !_KERNEL */ #endif /* !_SYS_MAC_H_ */ Index: head/sys/sys/mac_policy.h =================================================================== --- head/sys/sys/mac_policy.h (revision 145166) +++ head/sys/sys/mac_policy.h (revision 145167) @@ -1,596 +1,602 @@ /*- * Copyright (c) 1999-2002 Robert N. M. Watson - * Copyright (c) 2001-2004 Networks Associates Technology, Inc. + * Copyright (c) 2001-2005 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * This software was developed for the FreeBSD Project in part by Network * Associates Laboratories, the Security Research Division of Network * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), * as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Kernel interface for MAC policy modules. */ #ifndef _SYS_MAC_POLICY_H_ #define _SYS_MAC_POLICY_H_ /*- * Pluggable access control policy definition structure. * * List of operations that are performed as part of the implementation * of a MAC policy. Policy implementors declare operations with a * mac_policy_ops structure, and using the MAC_POLICY_SET() macro. * If an entry point is not declared, then then the policy will be ignored * during evaluation of that event or check. * * Operations are sorted first by general class of operation, then * alphabetically. */ struct acl; struct bpf_d; struct componentname; struct devfs_dirent; struct ifnet; struct image_params; struct inpcb; struct ipq; struct label; struct mac_policy_conf; struct mbuf; struct mount; struct msqid_kernel; struct pipepair; struct proc; struct sbuf; struct semid_kernel; struct shmid_kernel; struct sockaddr; struct socket; struct sysctl_oid; struct sysctl_req; struct thread; struct ucred; struct uio; struct vattr; struct vnode; struct mac_policy_ops { /* * Policy module operations. */ void (*mpo_destroy)(struct mac_policy_conf *mpc); void (*mpo_init)(struct mac_policy_conf *mpc); /* * General policy-directed security system call so that policies may * implement new services without reserving explicit system call * numbers. */ int (*mpo_syscall)(struct thread *td, int call, void *arg); /* * Label operations. Initialize label storage, destroy label * storage, recycle for re-use without init/destroy, copy a label to * initialized storage, and externalize/internalize from/to * initialized storage. */ void (*mpo_init_bpfdesc_label)(struct label *label); void (*mpo_init_cred_label)(struct label *label); void (*mpo_init_devfsdirent_label)(struct label *label); void (*mpo_init_ifnet_label)(struct label *label); int (*mpo_init_inpcb_label)(struct label *label, int flag); void (*mpo_init_sysv_msgmsg_label)(struct label *label); void (*mpo_init_sysv_msgqueue_label)(struct label *label); void (*mpo_init_sysv_sema_label)(struct label *label); void (*mpo_init_sysv_shm_label)(struct label *label); int (*mpo_init_ipq_label)(struct label *label, int flag); int (*mpo_init_mbuf_label)(struct label *label, int flag); void (*mpo_init_mount_label)(struct label *label); void (*mpo_init_mount_fs_label)(struct label *label); int (*mpo_init_socket_label)(struct label *label, int flag); int (*mpo_init_socket_peer_label)(struct label *label, int flag); void (*mpo_init_pipe_label)(struct label *label); void (*mpo_init_proc_label)(struct label *label); void (*mpo_init_vnode_label)(struct label *label); void (*mpo_destroy_bpfdesc_label)(struct label *label); void (*mpo_destroy_cred_label)(struct label *label); void (*mpo_destroy_devfsdirent_label)(struct label *label); void (*mpo_destroy_ifnet_label)(struct label *label); void (*mpo_destroy_inpcb_label)(struct label *label); void (*mpo_destroy_sysv_msgmsg_label)(struct label *label); void (*mpo_destroy_sysv_msgqueue_label)(struct label *label); void (*mpo_destroy_sysv_sema_label)(struct label *label); void (*mpo_destroy_sysv_shm_label)(struct label *label); void (*mpo_destroy_ipq_label)(struct label *label); void (*mpo_destroy_mbuf_label)(struct label *label); void (*mpo_destroy_mount_label)(struct label *label); void (*mpo_destroy_mount_fs_label)(struct label *label); void (*mpo_destroy_socket_label)(struct label *label); void (*mpo_destroy_socket_peer_label)(struct label *label); void (*mpo_destroy_pipe_label)(struct label *label); void (*mpo_destroy_proc_label)(struct label *label); void (*mpo_destroy_vnode_label)(struct label *label); void (*mpo_cleanup_sysv_msgmsg)(struct label *msglabel); void (*mpo_cleanup_sysv_msgqueue)(struct label *msqlabel); void (*mpo_cleanup_sysv_sema)(struct label *semalabel); void (*mpo_cleanup_sysv_shm)(struct label *shmlabel); void (*mpo_copy_cred_label)(struct label *src, struct label *dest); void (*mpo_copy_ifnet_label)(struct label *src, struct label *dest); void (*mpo_copy_mbuf_label)(struct label *src, struct label *dest); void (*mpo_copy_pipe_label)(struct label *src, struct label *dest); void (*mpo_copy_socket_label)(struct label *src, struct label *dest); void (*mpo_copy_vnode_label)(struct label *src, struct label *dest); int (*mpo_externalize_cred_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_ifnet_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_pipe_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_socket_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_socket_peer_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_externalize_vnode_label)(struct label *label, char *element_name, struct sbuf *sb, int *claimed); int (*mpo_internalize_cred_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_ifnet_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_pipe_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_socket_label)(struct label *label, char *element_name, char *element_data, int *claimed); int (*mpo_internalize_vnode_label)(struct label *label, char *element_name, char *element_data, int *claimed); /* * Labeling event operations: file system objects, and things that * look a lot like file system objects. */ void (*mpo_associate_vnode_devfs)(struct mount *mp, struct label *fslabel, struct devfs_dirent *de, struct label *delabel, struct vnode *vp, struct label *vlabel); int (*mpo_associate_vnode_extattr)(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel); void (*mpo_associate_vnode_singlelabel)(struct mount *mp, struct label *fslabel, struct vnode *vp, struct label *vlabel); void (*mpo_create_devfs_device)(struct mount *mp, struct cdev *dev, struct devfs_dirent *de, struct label *label); void (*mpo_create_devfs_directory)(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *de, struct label *label); void (*mpo_create_devfs_symlink)(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, struct label *delabel); int (*mpo_create_vnode_extattr)(struct ucred *cred, struct mount *mp, struct label *fslabel, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *vlabel, struct componentname *cnp); void (*mpo_create_mount)(struct ucred *cred, struct mount *mp, struct label *mntlabel, struct label *fslabel); void (*mpo_create_root_mount)(struct ucred *cred, struct mount *mp, struct label *mountlabel, struct label *fslabel); void (*mpo_relabel_vnode)(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *label); int (*mpo_setlabel_vnode_extattr)(struct ucred *cred, struct vnode *vp, struct label *vlabel, struct label *intlabel); void (*mpo_update_devfsdirent)(struct mount *mp, struct devfs_dirent *devfs_dirent, struct label *direntlabel, struct vnode *vp, struct label *vnodelabel); /* * Labeling event operations: IPC objects. */ void (*mpo_create_mbuf_from_socket)(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel); void (*mpo_create_socket)(struct ucred *cred, struct socket *so, struct label *socketlabel); void (*mpo_create_socket_from_socket)(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel); void (*mpo_relabel_socket)(struct ucred *cred, struct socket *so, struct label *oldlabel, struct label *newlabel); void (*mpo_relabel_pipe)(struct ucred *cred, struct pipepair *pp, struct label *oldlabel, struct label *newlabel); void (*mpo_set_socket_peer_from_mbuf)(struct mbuf *mbuf, struct label *mbuflabel, struct socket *so, struct label *socketpeerlabel); void (*mpo_set_socket_peer_from_socket)(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketpeerlabel); void (*mpo_create_pipe)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); /* * Labeling event operations: System V IPC primitives. */ void (*mpo_create_sysv_msgmsg)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel, struct msg *msgptr, struct label *msglabel); void (*mpo_create_sysv_msgqueue)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqlabel); void (*mpo_create_sysv_sema)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semalabel); void (*mpo_create_sysv_shm)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmlabel); /* * Labeling event operations: network objects. */ void (*mpo_create_bpfdesc)(struct ucred *cred, struct bpf_d *bpf_d, struct label *bpflabel); void (*mpo_create_ifnet)(struct ifnet *ifnet, struct label *ifnetlabel); void (*mpo_create_inpcb_from_socket)(struct socket *so, struct label *solabel, struct inpcb *inp, struct label *inplabel); void (*mpo_create_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); void (*mpo_create_datagram_from_ipq) (struct ipq *ipq, struct label *ipqlabel, struct mbuf *datagram, struct label *datagramlabel); void (*mpo_create_fragment)(struct mbuf *datagram, struct label *datagramlabel, struct mbuf *fragment, struct label *fragmentlabel); void (*mpo_create_mbuf_from_inpcb)(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel); void (*mpo_create_mbuf_from_mbuf)(struct mbuf *oldmbuf, struct label *oldlabel, struct mbuf *newmbuf, struct label *newlabel); void (*mpo_create_mbuf_linklayer)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel); void (*mpo_create_mbuf_from_bpfdesc)(struct bpf_d *bpf_d, struct label *bpflabel, struct mbuf *mbuf, struct label *mbuflabel); void (*mpo_create_mbuf_from_ifnet)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel); void (*mpo_create_mbuf_multicast_encap)(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *newmbuf, struct label *newmbuflabel); void (*mpo_create_mbuf_netlayer)(struct mbuf *oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel); int (*mpo_fragment_match)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); void (*mpo_reflect_mbuf_icmp)(struct mbuf *m, struct label *mlabel); void (*mpo_reflect_mbuf_tcp)(struct mbuf *m, struct label *mlabel); void (*mpo_relabel_ifnet)(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel); void (*mpo_update_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); void (*mpo_inpcb_sosetlabel)(struct socket *so, struct label *label, struct inpcb *inp, struct label *inplabel); /* * Labeling event operations: processes. */ void (*mpo_execve_transition)(struct ucred *old, struct ucred *new, struct vnode *vp, struct label *vnodelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel); int (*mpo_execve_will_transition)(struct ucred *old, struct vnode *vp, struct label *vnodelabel, struct label *interpvnodelabel, struct image_params *imgp, struct label *execlabel); void (*mpo_create_proc0)(struct ucred *cred); void (*mpo_create_proc1)(struct ucred *cred); void (*mpo_relabel_cred)(struct ucred *cred, struct label *newlabel); void (*mpo_thread_userret)(struct thread *thread); /* * Access control checks. */ int (*mpo_check_bpfdesc_receive)(struct bpf_d *bpf_d, struct label *bpflabel, struct ifnet *ifnet, struct label *ifnetlabel); int (*mpo_check_cred_relabel)(struct ucred *cred, struct label *newlabel); int (*mpo_check_cred_visible)(struct ucred *u1, struct ucred *u2); int (*mpo_check_ifnet_relabel)(struct ucred *cred, struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel); int (*mpo_check_ifnet_transmit)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel); int (*mpo_check_inpcb_deliver)(struct inpcb *inp, struct label *inplabel, struct mbuf *m, struct label *mlabel); int (*mpo_check_sysv_msgmsq)(struct ucred *cred, struct msg *msgptr, struct label *msglabel, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msgrcv)(struct ucred *cred, struct msg *msgptr, struct label *msglabel); int (*mpo_check_sysv_msgrmid)(struct ucred *cred, struct msg *msgptr, struct label *msglabel); int (*mpo_check_sysv_msqget)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msqsnd)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msqrcv)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel); int (*mpo_check_sysv_msqctl)(struct ucred *cred, struct msqid_kernel *msqkptr, struct label *msqklabel, int cmd); int (*mpo_check_sysv_semctl)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, int cmd); int (*mpo_check_sysv_semget)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel); int (*mpo_check_sysv_semop)(struct ucred *cred, struct semid_kernel *semakptr, struct label *semaklabel, size_t accesstype); int (*mpo_check_sysv_shmat)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg); int (*mpo_check_sysv_shmctl)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int cmd); int (*mpo_check_sysv_shmdt)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel); int (*mpo_check_sysv_shmget)(struct ucred *cred, struct shmid_kernel *shmsegptr, struct label *shmseglabel, int shmflg); int (*mpo_check_kenv_dump)(struct ucred *cred); int (*mpo_check_kenv_get)(struct ucred *cred, char *name); int (*mpo_check_kenv_set)(struct ucred *cred, char *name, char *value); int (*mpo_check_kenv_unset)(struct ucred *cred, char *name); int (*mpo_check_kld_load)(struct ucred *cred, struct vnode *vp, struct label *vlabel); int (*mpo_check_kld_stat)(struct ucred *cred); int (*mpo_check_kld_unload)(struct ucred *cred); int (*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp, struct label *mntlabel); int (*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, unsigned long cmd, void *data); int (*mpo_check_pipe_poll)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_read)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_relabel)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel, struct label *newlabel); int (*mpo_check_pipe_stat)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_write)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); int (*mpo_check_proc_debug)(struct ucred *cred, struct proc *proc); int (*mpo_check_proc_sched)(struct ucred *cred, struct proc *proc); int (*mpo_check_proc_setuid)(struct ucred *cred, uid_t uid); int (*mpo_check_proc_seteuid)(struct ucred *cred, uid_t euid); int (*mpo_check_proc_setgid)(struct ucred *cred, gid_t gid); int (*mpo_check_proc_setegid)(struct ucred *cred, gid_t egid); int (*mpo_check_proc_setgroups)(struct ucred *cred, int ngroups, gid_t *gidset); int (*mpo_check_proc_setreuid)(struct ucred *cred, uid_t ruid, uid_t euid); int (*mpo_check_proc_setregid)(struct ucred *cred, gid_t rgid, gid_t egid); int (*mpo_check_proc_setresuid)(struct ucred *cred, uid_t ruid, uid_t euid, uid_t suid); int (*mpo_check_proc_setresgid)(struct ucred *cred, gid_t rgid, gid_t egid, gid_t sgid); int (*mpo_check_proc_signal)(struct ucred *cred, struct proc *proc, int signum); + int (*mpo_check_socket_accept)(struct ucred *cred, + struct socket *so, struct label *socketlabel); int (*mpo_check_socket_bind)(struct ucred *cred, struct socket *so, struct label *socketlabel, struct sockaddr *sockaddr); int (*mpo_check_socket_connect)(struct ucred *cred, struct socket *so, struct label *socketlabel, struct sockaddr *sockaddr); int (*mpo_check_socket_deliver)(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel); int (*mpo_check_socket_listen)(struct ucred *cred, struct socket *so, struct label *socketlabel); + int (*mpo_check_socket_poll)(struct ucred *cred, + struct socket *so, struct label *socketlabel); int (*mpo_check_socket_receive)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_socket_relabel)(struct ucred *cred, struct socket *so, struct label *socketlabel, struct label *newlabel); int (*mpo_check_socket_send)(struct ucred *cred, + struct socket *so, struct label *socketlabel); + int (*mpo_check_socket_stat)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_socket_visible)(struct ucred *cred, struct socket *so, struct label *socketlabel); int (*mpo_check_sysarch_ioperm)(struct ucred *cred); int (*mpo_check_system_acct)(struct ucred *cred, struct vnode *vp, struct label *vlabel); int (*mpo_check_system_nfsd)(struct ucred *cred); int (*mpo_check_system_reboot)(struct ucred *cred, int howto); int (*mpo_check_system_settime)(struct ucred *cred); int (*mpo_check_system_swapon)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_system_swapoff)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_system_sysctl)(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); int (*mpo_check_vnode_access)(struct ucred *cred, struct vnode *vp, struct label *label, int acc_mode); int (*mpo_check_vnode_chdir)(struct ucred *cred, struct vnode *dvp, struct label *dlabel); int (*mpo_check_vnode_chroot)(struct ucred *cred, struct vnode *dvp, struct label *dlabel); int (*mpo_check_vnode_create)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp, struct vattr *vap); int (*mpo_check_vnode_delete)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp); int (*mpo_check_vnode_deleteacl)(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type); int (*mpo_check_vnode_deleteextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name); int (*mpo_check_vnode_exec)(struct ucred *cred, struct vnode *vp, struct label *label, struct image_params *imgp, struct label *execlabel); int (*mpo_check_vnode_getacl)(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type); int (*mpo_check_vnode_getextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio); int (*mpo_check_vnode_link)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp); int (*mpo_check_vnode_listextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace); int (*mpo_check_vnode_lookup)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp); int (*mpo_check_vnode_mmap)(struct ucred *cred, struct vnode *vp, struct label *label, int prot, int flags); void (*mpo_check_vnode_mmap_downgrade)(struct ucred *cred, struct vnode *vp, struct label *label, int *prot); int (*mpo_check_vnode_mprotect)(struct ucred *cred, struct vnode *vp, struct label *label, int prot); int (*mpo_check_vnode_open)(struct ucred *cred, struct vnode *vp, struct label *label, int acc_mode); int (*mpo_check_vnode_poll)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_read)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_readdir)(struct ucred *cred, struct vnode *dvp, struct label *dlabel); int (*mpo_check_vnode_readlink)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_relabel)(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, struct label *newlabel); int (*mpo_check_vnode_rename_from)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct componentname *cnp); int (*mpo_check_vnode_rename_to)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, int samedir, struct componentname *cnp); int (*mpo_check_vnode_revoke)(struct ucred *cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_setacl)(struct ucred *cred, struct vnode *vp, struct label *label, acl_type_t type, struct acl *acl); int (*mpo_check_vnode_setextattr)(struct ucred *cred, struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio *uio); int (*mpo_check_vnode_setflags)(struct ucred *cred, struct vnode *vp, struct label *label, u_long flags); int (*mpo_check_vnode_setmode)(struct ucred *cred, struct vnode *vp, struct label *label, mode_t mode); int (*mpo_check_vnode_setowner)(struct ucred *cred, struct vnode *vp, struct label *label, uid_t uid, gid_t gid); int (*mpo_check_vnode_setutimes)(struct ucred *cred, struct vnode *vp, struct label *label, struct timespec atime, struct timespec mtime); int (*mpo_check_vnode_stat)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); int (*mpo_check_vnode_write)(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp, struct label *label); }; /* * struct mac_policy_conf is the registration structure for policies, and is * provided to the MAC Framework using MAC_POLICY_SET() to invoke a SYSINIT * to register the policy. In general, the fields are immutable, with the * exception of the "security field", run-time flags, and policy list entry, * which are managed by the MAC Framework. Be careful when modifying this * structure, as its layout is statically compiled into all policies. */ struct mac_policy_conf { char *mpc_name; /* policy name */ char *mpc_fullname; /* policy full name */ struct mac_policy_ops *mpc_ops; /* policy operations */ int mpc_loadtime_flags; /* flags */ int *mpc_field_off; /* security field */ int mpc_runtime_flags; /* flags */ LIST_ENTRY(mac_policy_conf) mpc_list; /* global list */ }; /* Flags for the mpc_loadtime_flags field. */ #define MPC_LOADTIME_FLAG_NOTLATE 0x00000001 #define MPC_LOADTIME_FLAG_UNLOADOK 0x00000002 #define MPC_LOADTIME_FLAG_LABELMBUFS 0x00000004 /* Flags for the mpc_runtime_flags field. */ #define MPC_RUNTIME_FLAG_REGISTERED 0x00000001 #define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted) \ static struct mac_policy_conf mpname##_mac_policy_conf = { \ #mpname, \ mpfullname, \ mpops, \ mpflags, \ privdata_wanted, \ 0, \ }; \ static moduledata_t mpname##_mod = { \ #mpname, \ mac_policy_modevent, \ &mpname##_mac_policy_conf \ }; \ MODULE_DEPEND(mpname, kernel_mac_support, 2, 2, 2); \ DECLARE_MODULE(mpname, mpname##_mod, SI_SUB_MAC_POLICY, \ SI_ORDER_MIDDLE) int mac_policy_modevent(module_t mod, int type, void *data); #define LABEL_TO_SLOT(l, s) (l)->l_perpolicy[s] #endif /* !_SYS_MAC_POLICY_H_ */