17bc82500SRobert Watson /*- 2471e5756SRobert Watson * Copyright (c) 1999-2002, 2006 Robert N. M. Watson 37bc82500SRobert Watson * Copyright (c) 2001 Ilmar S. Habibulin 4f0c2044bSRobert Watson * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 5aed55708SRobert Watson * Copyright (c) 2005-2006 SPARTA, Inc. 67bc82500SRobert Watson * All rights reserved. 77bc82500SRobert Watson * 87bc82500SRobert Watson * This software was developed by Robert Watson and Ilmar Habibulin for the 97bc82500SRobert Watson * TrustedBSD Project. 107bc82500SRobert Watson * 116201265bSRobert Watson * This software was developed for the FreeBSD Project in part by Network 126201265bSRobert Watson * Associates Laboratories, the Security Research Division of Network 136201265bSRobert Watson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 146201265bSRobert Watson * as part of the DARPA CHATS research program. 157bc82500SRobert Watson * 1649bb6870SRobert Watson * This software was enhanced by SPARTA ISSO under SPAWAR contract 1749bb6870SRobert Watson * N66001-04-C-6019 ("SEFOS"). 1849bb6870SRobert Watson * 197bc82500SRobert Watson * Redistribution and use in source and binary forms, with or without 207bc82500SRobert Watson * modification, are permitted provided that the following conditions 217bc82500SRobert Watson * are met: 227bc82500SRobert Watson * 1. Redistributions of source code must retain the above copyright 237bc82500SRobert Watson * notice, this list of conditions and the following disclaimer. 247bc82500SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 257bc82500SRobert Watson * notice, this list of conditions and the following disclaimer in the 267bc82500SRobert Watson * documentation and/or other materials provided with the distribution. 277bc82500SRobert Watson * 287bc82500SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 297bc82500SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 307bc82500SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 317bc82500SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 327bc82500SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 337bc82500SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 347bc82500SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 357bc82500SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 367bc82500SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 377bc82500SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 387bc82500SRobert Watson * SUCH DAMAGE. 397bc82500SRobert Watson */ 40677b542eSDavid E. O'Brien 41677b542eSDavid E. O'Brien #include <sys/cdefs.h> 42677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 43677b542eSDavid E. O'Brien 447bc82500SRobert Watson #include "opt_mac.h" 45f9d0d524SRobert Watson 467bc82500SRobert Watson #include <sys/param.h> 4795fab37eSRobert Watson #include <sys/kernel.h> 4895fab37eSRobert Watson #include <sys/lock.h> 49b656366bSBruce Evans #include <sys/malloc.h> 5095fab37eSRobert Watson #include <sys/mutex.h> 5195fab37eSRobert Watson #include <sys/mac.h> 5295fab37eSRobert Watson #include <sys/proc.h> 5395fab37eSRobert Watson #include <sys/systm.h> 547bc82500SRobert Watson #include <sys/sysproto.h> 557bc82500SRobert Watson #include <sys/sysent.h> 5695fab37eSRobert Watson #include <sys/vnode.h> 5795fab37eSRobert Watson #include <sys/mount.h> 5895fab37eSRobert Watson #include <sys/file.h> 5995fab37eSRobert Watson #include <sys/namei.h> 6095fab37eSRobert Watson #include <sys/socket.h> 6195fab37eSRobert Watson #include <sys/pipe.h> 6295fab37eSRobert Watson #include <sys/socketvar.h> 6395fab37eSRobert Watson 64aed55708SRobert Watson #include <security/mac/mac_framework.h> 656fa0475dSRobert Watson #include <security/mac/mac_internal.h> 660efd6615SRobert Watson #include <security/mac/mac_policy.h> 676fa0475dSRobert Watson 6895fab37eSRobert Watson #ifdef MAC 6995fab37eSRobert Watson 70f7b951a8SRobert Watson int 71f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 72f7b951a8SRobert Watson { 73f7b951a8SRobert Watson char *elements, *buffer; 74f7b951a8SRobert Watson struct mac mac; 75f7b951a8SRobert Watson struct proc *tproc; 76f7b951a8SRobert Watson struct ucred *tcred; 77f7b951a8SRobert Watson int error; 78f7b951a8SRobert Watson 79d1e405c5SAlfred Perlstein error = copyin(uap->mac_p, &mac, sizeof(mac)); 80f7b951a8SRobert Watson if (error) 81f7b951a8SRobert Watson return (error); 82f7b951a8SRobert Watson 83f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 84f7b951a8SRobert Watson if (error) 85f7b951a8SRobert Watson return (error); 86f7b951a8SRobert Watson 87f7b951a8SRobert Watson tproc = pfind(uap->pid); 88f7b951a8SRobert Watson if (tproc == NULL) 89f7b951a8SRobert Watson return (ESRCH); 90f7b951a8SRobert Watson 91f7b951a8SRobert Watson tcred = NULL; /* Satisfy gcc. */ 92f7b951a8SRobert Watson error = p_cansee(td, tproc); 93f7b951a8SRobert Watson if (error == 0) 94f7b951a8SRobert Watson tcred = crhold(tproc->p_ucred); 95f7b951a8SRobert Watson PROC_UNLOCK(tproc); 96f7b951a8SRobert Watson if (error) 97f7b951a8SRobert Watson return (error); 98f7b951a8SRobert Watson 99a163d034SWarner Losh elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 100f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 101f7b951a8SRobert Watson if (error) { 102f7b951a8SRobert Watson free(elements, M_MACTEMP); 103f7b951a8SRobert Watson crfree(tcred); 104f7b951a8SRobert Watson return (error); 105f7b951a8SRobert Watson } 106f7b951a8SRobert Watson 107a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 10830d239bcSRobert Watson error = mac_cred_externalize_label(tcred->cr_label, elements, 10983b7b0edSRobert Watson buffer, mac.m_buflen); 110f7b951a8SRobert Watson if (error == 0) 111f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 112f7b951a8SRobert Watson 113f7b951a8SRobert Watson free(buffer, M_MACTEMP); 114f7b951a8SRobert Watson free(elements, M_MACTEMP); 115f7b951a8SRobert Watson crfree(tcred); 116f7b951a8SRobert Watson return (error); 117f7b951a8SRobert Watson } 118f7b951a8SRobert Watson 11995fab37eSRobert Watson int 12095fab37eSRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 12195fab37eSRobert Watson { 122f7b951a8SRobert Watson char *elements, *buffer; 123f7b951a8SRobert Watson struct mac mac; 12495fab37eSRobert Watson int error; 12595fab37eSRobert Watson 126f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 127f7b951a8SRobert Watson if (error) 128f7b951a8SRobert Watson return (error); 12995fab37eSRobert Watson 130f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 131f7b951a8SRobert Watson if (error) 132f7b951a8SRobert Watson return (error); 133f7b951a8SRobert Watson 134a163d034SWarner Losh elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 135f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 136f7b951a8SRobert Watson if (error) { 137f7b951a8SRobert Watson free(elements, M_MACTEMP); 138f7b951a8SRobert Watson return (error); 139f7b951a8SRobert Watson } 140f7b951a8SRobert Watson 141a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 14230d239bcSRobert Watson error = mac_cred_externalize_label(td->td_ucred->cr_label, 14383b7b0edSRobert Watson elements, buffer, mac.m_buflen); 144f7b951a8SRobert Watson if (error == 0) 145f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 146f7b951a8SRobert Watson 147f7b951a8SRobert Watson free(buffer, M_MACTEMP); 148f7b951a8SRobert Watson free(elements, M_MACTEMP); 14995fab37eSRobert Watson return (error); 15095fab37eSRobert Watson } 15195fab37eSRobert Watson 15295fab37eSRobert Watson int 15395fab37eSRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 15495fab37eSRobert Watson { 15595fab37eSRobert Watson struct ucred *newcred, *oldcred; 156eca8a663SRobert Watson struct label *intlabel; 157f7b951a8SRobert Watson struct proc *p; 158f7b951a8SRobert Watson struct mac mac; 159f7b951a8SRobert Watson char *buffer; 16095fab37eSRobert Watson int error; 16195fab37eSRobert Watson 162f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 16395fab37eSRobert Watson if (error) 16495fab37eSRobert Watson return (error); 16595fab37eSRobert Watson 166f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 16795fab37eSRobert Watson if (error) 16895fab37eSRobert Watson return (error); 16995fab37eSRobert Watson 170a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 171f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 172f7b951a8SRobert Watson if (error) { 173f7b951a8SRobert Watson free(buffer, M_MACTEMP); 174f7b951a8SRobert Watson return (error); 175f7b951a8SRobert Watson } 176f7b951a8SRobert Watson 177eca8a663SRobert Watson intlabel = mac_cred_label_alloc(); 17830d239bcSRobert Watson error = mac_cred_internalize_label(intlabel, buffer); 179f7b951a8SRobert Watson free(buffer, M_MACTEMP); 180eca8a663SRobert Watson if (error) 181eca8a663SRobert Watson goto out; 182f7b951a8SRobert Watson 18395fab37eSRobert Watson newcred = crget(); 18495fab37eSRobert Watson 18595fab37eSRobert Watson p = td->td_proc; 18695fab37eSRobert Watson PROC_LOCK(p); 18795fab37eSRobert Watson oldcred = p->p_ucred; 18895fab37eSRobert Watson 18930d239bcSRobert Watson error = mac_cred_check_relabel(oldcred, intlabel); 19095fab37eSRobert Watson if (error) { 19195fab37eSRobert Watson PROC_UNLOCK(p); 19295fab37eSRobert Watson crfree(newcred); 193f7b951a8SRobert Watson goto out; 19495fab37eSRobert Watson } 19595fab37eSRobert Watson 19695fab37eSRobert Watson setsugid(p); 19795fab37eSRobert Watson crcopy(newcred, oldcred); 19830d239bcSRobert Watson mac_cred_relabel(newcred, intlabel); 19995fab37eSRobert Watson p->p_ucred = newcred; 200e5cb5e37SRobert Watson 201e5cb5e37SRobert Watson /* 20217041e67SRobert Watson * Grab additional reference for use while revoking mmaps, prior to 20317041e67SRobert Watson * releasing the proc lock and sharing the cred. 204e5cb5e37SRobert Watson */ 205e5cb5e37SRobert Watson crhold(newcred); 20695fab37eSRobert Watson PROC_UNLOCK(p); 207e5cb5e37SRobert Watson 208e5cb5e37SRobert Watson mac_cred_mmapped_drop_perms(td, newcred); 209e5cb5e37SRobert Watson 210e5cb5e37SRobert Watson crfree(newcred); /* Free revocation reference. */ 21195fab37eSRobert Watson crfree(oldcred); 212f7b951a8SRobert Watson 213f7b951a8SRobert Watson out: 214eca8a663SRobert Watson mac_cred_label_free(intlabel); 215f7b951a8SRobert Watson return (error); 21695fab37eSRobert Watson } 21795fab37eSRobert Watson 21895fab37eSRobert Watson int 21995fab37eSRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 22095fab37eSRobert Watson { 221f7b951a8SRobert Watson char *elements, *buffer; 222eca8a663SRobert Watson struct label *intlabel; 22395fab37eSRobert Watson struct file *fp; 224f7b951a8SRobert Watson struct mac mac; 22595fab37eSRobert Watson struct vnode *vp; 22695fab37eSRobert Watson struct pipe *pipe; 227b0323ea3SRobert Watson struct socket *so; 228f7b951a8SRobert Watson short label_type; 2299eea3d85SChristian S.J. Peron int vfslocked, error; 23095fab37eSRobert Watson 231f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 232f7b951a8SRobert Watson if (error) 233f7b951a8SRobert Watson return (error); 23495fab37eSRobert Watson 235f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 236f7b951a8SRobert Watson if (error) 237f7b951a8SRobert Watson return (error); 238f7b951a8SRobert Watson 239a163d034SWarner Losh elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 240f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 241f7b951a8SRobert Watson if (error) { 242f7b951a8SRobert Watson free(elements, M_MACTEMP); 243f7b951a8SRobert Watson return (error); 244f7b951a8SRobert Watson } 245f7b951a8SRobert Watson 246a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 247d1e405c5SAlfred Perlstein error = fget(td, uap->fd, &fp); 24895fab37eSRobert Watson if (error) 24995fab37eSRobert Watson goto out; 25095fab37eSRobert Watson 251f7b951a8SRobert Watson label_type = fp->f_type; 25295fab37eSRobert Watson switch (fp->f_type) { 25395fab37eSRobert Watson case DTYPE_FIFO: 25495fab37eSRobert Watson case DTYPE_VNODE: 2553b6d9652SPoul-Henning Kamp vp = fp->f_vnode; 256eca8a663SRobert Watson intlabel = mac_vnode_label_alloc(); 2579eea3d85SChristian S.J. Peron vfslocked = VFS_LOCK_GIANT(vp->v_mount); 258cb05b60aSAttilio Rao vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 25930d239bcSRobert Watson mac_vnode_copy_label(vp->v_label, intlabel); 26095fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 2619eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 26230d239bcSRobert Watson error = mac_vnode_externalize_label(intlabel, elements, 263f0ab0442SRobert Watson buffer, mac.m_buflen); 264f0ab0442SRobert Watson mac_vnode_label_free(intlabel); 26595fab37eSRobert Watson break; 266f0ab0442SRobert Watson 26795fab37eSRobert Watson case DTYPE_PIPE: 26848e3128bSMatthew Dillon pipe = fp->f_data; 269eca8a663SRobert Watson intlabel = mac_pipe_label_alloc(); 270f7b951a8SRobert Watson PIPE_LOCK(pipe); 27130d239bcSRobert Watson mac_pipe_copy_label(pipe->pipe_pair->pp_label, intlabel); 272f7b951a8SRobert Watson PIPE_UNLOCK(pipe); 27330d239bcSRobert Watson error = mac_pipe_externalize_label(intlabel, elements, 27483b7b0edSRobert Watson buffer, mac.m_buflen); 275eca8a663SRobert Watson mac_pipe_label_free(intlabel); 276f7b951a8SRobert Watson break; 27795fab37eSRobert Watson 278b0323ea3SRobert Watson case DTYPE_SOCKET: 279b0323ea3SRobert Watson so = fp->f_data; 280b0323ea3SRobert Watson intlabel = mac_socket_label_alloc(M_WAITOK); 281f0c2044bSRobert Watson SOCK_LOCK(so); 28230d239bcSRobert Watson mac_socket_copy_label(so->so_label, intlabel); 283f0c2044bSRobert Watson SOCK_UNLOCK(so); 28430d239bcSRobert Watson error = mac_socket_externalize_label(intlabel, elements, 285b0323ea3SRobert Watson buffer, mac.m_buflen); 286b0323ea3SRobert Watson mac_socket_label_free(intlabel); 287b0323ea3SRobert Watson break; 288b0323ea3SRobert Watson 289f0ab0442SRobert Watson default: 290f0ab0442SRobert Watson error = EINVAL; 291f0ab0442SRobert Watson } 292f0ab0442SRobert Watson fdrop(fp, td); 29395fab37eSRobert Watson if (error == 0) 294f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 29595fab37eSRobert Watson 29695fab37eSRobert Watson out: 297f7b951a8SRobert Watson free(buffer, M_MACTEMP); 298f7b951a8SRobert Watson free(elements, M_MACTEMP); 29995fab37eSRobert Watson return (error); 30095fab37eSRobert Watson } 30195fab37eSRobert Watson 30295fab37eSRobert Watson int 30395fab37eSRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 30495fab37eSRobert Watson { 305f7b951a8SRobert Watson char *elements, *buffer; 30695fab37eSRobert Watson struct nameidata nd; 307eca8a663SRobert Watson struct label *intlabel; 308f7b951a8SRobert Watson struct mac mac; 3099eea3d85SChristian S.J. Peron int vfslocked, error; 31095fab37eSRobert Watson 311f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 312f7b951a8SRobert Watson if (error) 313f7b951a8SRobert Watson return (error); 314f7b951a8SRobert Watson 315f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 316f7b951a8SRobert Watson if (error) 317f7b951a8SRobert Watson return (error); 318f7b951a8SRobert Watson 319a163d034SWarner Losh elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 320f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 321f7b951a8SRobert Watson if (error) { 322f7b951a8SRobert Watson free(elements, M_MACTEMP); 323f7b951a8SRobert Watson return (error); 324f7b951a8SRobert Watson } 325f7b951a8SRobert Watson 326a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3279eea3d85SChristian S.J. Peron NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE, 3289eea3d85SChristian S.J. Peron uap->path_p, td); 32995fab37eSRobert Watson error = namei(&nd); 33095fab37eSRobert Watson if (error) 33195fab37eSRobert Watson goto out; 33295fab37eSRobert Watson 333eca8a663SRobert Watson intlabel = mac_vnode_label_alloc(); 3349eea3d85SChristian S.J. Peron vfslocked = NDHASGIANT(&nd); 33530d239bcSRobert Watson mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); 33630d239bcSRobert Watson error = mac_vnode_externalize_label(intlabel, elements, buffer, 33783b7b0edSRobert Watson mac.m_buflen); 338f7b951a8SRobert Watson 33995fab37eSRobert Watson NDFREE(&nd, 0); 3409eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 341eca8a663SRobert Watson mac_vnode_label_free(intlabel); 342f7b951a8SRobert Watson if (error == 0) 343f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 344f7b951a8SRobert Watson 345f7b951a8SRobert Watson out: 346f7b951a8SRobert Watson free(buffer, M_MACTEMP); 347f7b951a8SRobert Watson free(elements, M_MACTEMP); 348f7b951a8SRobert Watson 349f7b951a8SRobert Watson return (error); 350f7b951a8SRobert Watson } 351f7b951a8SRobert Watson 352f7b951a8SRobert Watson int 353f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 354f7b951a8SRobert Watson { 355f7b951a8SRobert Watson char *elements, *buffer; 356f7b951a8SRobert Watson struct nameidata nd; 357eca8a663SRobert Watson struct label *intlabel; 358f7b951a8SRobert Watson struct mac mac; 3599eea3d85SChristian S.J. Peron int vfslocked, error; 360f7b951a8SRobert Watson 361f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 362f7b951a8SRobert Watson if (error) 363f7b951a8SRobert Watson return (error); 364f7b951a8SRobert Watson 365f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 366f7b951a8SRobert Watson if (error) 367f7b951a8SRobert Watson return (error); 368f7b951a8SRobert Watson 369a163d034SWarner Losh elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 370f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 371f7b951a8SRobert Watson if (error) { 372f7b951a8SRobert Watson free(elements, M_MACTEMP); 373f7b951a8SRobert Watson return (error); 374f7b951a8SRobert Watson } 375f7b951a8SRobert Watson 376a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3779eea3d85SChristian S.J. Peron NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE, 3789eea3d85SChristian S.J. Peron uap->path_p, td); 379f7b951a8SRobert Watson error = namei(&nd); 38095fab37eSRobert Watson if (error) 38195fab37eSRobert Watson goto out; 38295fab37eSRobert Watson 383eca8a663SRobert Watson intlabel = mac_vnode_label_alloc(); 3849eea3d85SChristian S.J. Peron vfslocked = NDHASGIANT(&nd); 38530d239bcSRobert Watson mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); 38630d239bcSRobert Watson error = mac_vnode_externalize_label(intlabel, elements, buffer, 38783b7b0edSRobert Watson mac.m_buflen); 388f7b951a8SRobert Watson NDFREE(&nd, 0); 3899eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 390eca8a663SRobert Watson mac_vnode_label_free(intlabel); 391f7b951a8SRobert Watson 392f7b951a8SRobert Watson if (error == 0) 393f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 39495fab37eSRobert Watson 39595fab37eSRobert Watson out: 396f7b951a8SRobert Watson free(buffer, M_MACTEMP); 397f7b951a8SRobert Watson free(elements, M_MACTEMP); 398f7b951a8SRobert Watson 39995fab37eSRobert Watson return (error); 40095fab37eSRobert Watson } 40195fab37eSRobert Watson 40295fab37eSRobert Watson int 40395fab37eSRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 40495fab37eSRobert Watson { 405eca8a663SRobert Watson struct label *intlabel; 406f7b951a8SRobert Watson struct pipe *pipe; 407b0323ea3SRobert Watson struct socket *so; 408f7b951a8SRobert Watson struct file *fp; 40995fab37eSRobert Watson struct mount *mp; 41095fab37eSRobert Watson struct vnode *vp; 411f7b951a8SRobert Watson struct mac mac; 412f7b951a8SRobert Watson char *buffer; 4139eea3d85SChristian S.J. Peron int error, vfslocked; 41495fab37eSRobert Watson 415f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 416f7b951a8SRobert Watson if (error) 417f7b951a8SRobert Watson return (error); 418f7b951a8SRobert Watson 419f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 420f7b951a8SRobert Watson if (error) 421f7b951a8SRobert Watson return (error); 422f7b951a8SRobert Watson 423a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 424f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 425f7b951a8SRobert Watson if (error) { 426f7b951a8SRobert Watson free(buffer, M_MACTEMP); 427f7b951a8SRobert Watson return (error); 428f7b951a8SRobert Watson } 429f7b951a8SRobert Watson 430d1e405c5SAlfred Perlstein error = fget(td, uap->fd, &fp); 43195fab37eSRobert Watson if (error) 432f7b951a8SRobert Watson goto out; 43395fab37eSRobert Watson 43495fab37eSRobert Watson switch (fp->f_type) { 43595fab37eSRobert Watson case DTYPE_FIFO: 43695fab37eSRobert Watson case DTYPE_VNODE: 437eca8a663SRobert Watson intlabel = mac_vnode_label_alloc(); 43830d239bcSRobert Watson error = mac_vnode_internalize_label(intlabel, buffer); 439f7b951a8SRobert Watson if (error) { 440eca8a663SRobert Watson mac_vnode_label_free(intlabel); 441f7b951a8SRobert Watson break; 442f7b951a8SRobert Watson } 4433b6d9652SPoul-Henning Kamp vp = fp->f_vnode; 4449eea3d85SChristian S.J. Peron vfslocked = VFS_LOCK_GIANT(vp->v_mount); 44595fab37eSRobert Watson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 446f7b951a8SRobert Watson if (error != 0) { 4479eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 448eca8a663SRobert Watson mac_vnode_label_free(intlabel); 44995fab37eSRobert Watson break; 450f7b951a8SRobert Watson } 451cb05b60aSAttilio Rao vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 452eca8a663SRobert Watson error = vn_setlabel(vp, intlabel, td->td_ucred); 45395fab37eSRobert Watson VOP_UNLOCK(vp, 0, td); 45495fab37eSRobert Watson vn_finished_write(mp); 4559eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 456eca8a663SRobert Watson mac_vnode_label_free(intlabel); 45795fab37eSRobert Watson break; 458f7b951a8SRobert Watson 45995fab37eSRobert Watson case DTYPE_PIPE: 460eca8a663SRobert Watson intlabel = mac_pipe_label_alloc(); 46130d239bcSRobert Watson error = mac_pipe_internalize_label(intlabel, buffer); 462f7b951a8SRobert Watson if (error == 0) { 46348e3128bSMatthew Dillon pipe = fp->f_data; 4641aa37f53SRobert Watson PIPE_LOCK(pipe); 4654795b82cSRobert Watson error = mac_pipe_label_set(td->td_ucred, 4664795b82cSRobert Watson pipe->pipe_pair, intlabel); 4671aa37f53SRobert Watson PIPE_UNLOCK(pipe); 468f7b951a8SRobert Watson } 469eca8a663SRobert Watson mac_pipe_label_free(intlabel); 47095fab37eSRobert Watson break; 471f7b951a8SRobert Watson 472b0323ea3SRobert Watson case DTYPE_SOCKET: 473b0323ea3SRobert Watson intlabel = mac_socket_label_alloc(M_WAITOK); 47430d239bcSRobert Watson error = mac_socket_internalize_label(intlabel, buffer); 475b0323ea3SRobert Watson if (error == 0) { 476b0323ea3SRobert Watson so = fp->f_data; 477b0323ea3SRobert Watson error = mac_socket_label_set(td->td_ucred, so, 478b0323ea3SRobert Watson intlabel); 479b0323ea3SRobert Watson } 480b0323ea3SRobert Watson mac_socket_label_free(intlabel); 481b0323ea3SRobert Watson break; 482b0323ea3SRobert Watson 48395fab37eSRobert Watson default: 48495fab37eSRobert Watson error = EINVAL; 48595fab37eSRobert Watson } 48695fab37eSRobert Watson fdrop(fp, td); 487f7b951a8SRobert Watson out: 488f7b951a8SRobert Watson free(buffer, M_MACTEMP); 48995fab37eSRobert Watson return (error); 49095fab37eSRobert Watson } 49195fab37eSRobert Watson 49295fab37eSRobert Watson int 49395fab37eSRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 49495fab37eSRobert Watson { 495eca8a663SRobert Watson struct label *intlabel; 496f7b951a8SRobert Watson struct nameidata nd; 49795fab37eSRobert Watson struct mount *mp; 498f7b951a8SRobert Watson struct mac mac; 499f7b951a8SRobert Watson char *buffer; 5009eea3d85SChristian S.J. Peron int vfslocked, error; 50195fab37eSRobert Watson 502f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 50395fab37eSRobert Watson if (error) 504f7b951a8SRobert Watson return (error); 50595fab37eSRobert Watson 506f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 50795fab37eSRobert Watson if (error) 508f7b951a8SRobert Watson return (error); 50995fab37eSRobert Watson 510a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 511f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 512f7b951a8SRobert Watson if (error) { 513f7b951a8SRobert Watson free(buffer, M_MACTEMP); 51495fab37eSRobert Watson return (error); 51595fab37eSRobert Watson } 51695fab37eSRobert Watson 517eca8a663SRobert Watson intlabel = mac_vnode_label_alloc(); 51830d239bcSRobert Watson error = mac_vnode_internalize_label(intlabel, buffer); 519f7b951a8SRobert Watson free(buffer, M_MACTEMP); 520eca8a663SRobert Watson if (error) 521eca8a663SRobert Watson goto out; 522f7b951a8SRobert Watson 5239eea3d85SChristian S.J. Peron NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE, 5249eea3d85SChristian S.J. Peron uap->path_p, td); 525f7b951a8SRobert Watson error = namei(&nd); 5269eea3d85SChristian S.J. Peron vfslocked = NDHASGIANT(&nd); 527f7b951a8SRobert Watson if (error == 0) { 528f7b951a8SRobert Watson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 529d50ef66dSTor Egge if (error == 0) { 530eca8a663SRobert Watson error = vn_setlabel(nd.ni_vp, intlabel, 531f7b951a8SRobert Watson td->td_ucred); 532f7b951a8SRobert Watson vn_finished_write(mp); 533f7b951a8SRobert Watson } 534d50ef66dSTor Egge } 535f7b951a8SRobert Watson 536f7b951a8SRobert Watson NDFREE(&nd, 0); 5379eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 538eca8a663SRobert Watson out: 539eca8a663SRobert Watson mac_vnode_label_free(intlabel); 540f7b951a8SRobert Watson return (error); 541f7b951a8SRobert Watson } 542f7b951a8SRobert Watson 543f7b951a8SRobert Watson int 544f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 545f7b951a8SRobert Watson { 546eca8a663SRobert Watson struct label *intlabel; 547f7b951a8SRobert Watson struct nameidata nd; 548f7b951a8SRobert Watson struct mount *mp; 549f7b951a8SRobert Watson struct mac mac; 550f7b951a8SRobert Watson char *buffer; 5519eea3d85SChristian S.J. Peron int vfslocked, error; 552f7b951a8SRobert Watson 553f7b951a8SRobert Watson error = copyin(uap->mac_p, &mac, sizeof(mac)); 554f7b951a8SRobert Watson if (error) 555f7b951a8SRobert Watson return (error); 556f7b951a8SRobert Watson 557f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 558f7b951a8SRobert Watson if (error) 559f7b951a8SRobert Watson return (error); 560f7b951a8SRobert Watson 561a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 562f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 563f7b951a8SRobert Watson if (error) { 564f7b951a8SRobert Watson free(buffer, M_MACTEMP); 565f7b951a8SRobert Watson return (error); 566f7b951a8SRobert Watson } 567f7b951a8SRobert Watson 568eca8a663SRobert Watson intlabel = mac_vnode_label_alloc(); 56930d239bcSRobert Watson error = mac_vnode_internalize_label(intlabel, buffer); 570f7b951a8SRobert Watson free(buffer, M_MACTEMP); 571eca8a663SRobert Watson if (error) 572eca8a663SRobert Watson goto out; 573f7b951a8SRobert Watson 5749eea3d85SChristian S.J. Peron NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE, 5759eea3d85SChristian S.J. Peron uap->path_p, td); 576f7b951a8SRobert Watson error = namei(&nd); 5779eea3d85SChristian S.J. Peron vfslocked = NDHASGIANT(&nd); 578f7b951a8SRobert Watson if (error == 0) { 579f7b951a8SRobert Watson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 580d50ef66dSTor Egge if (error == 0) { 581eca8a663SRobert Watson error = vn_setlabel(nd.ni_vp, intlabel, 582f7b951a8SRobert Watson td->td_ucred); 583f7b951a8SRobert Watson vn_finished_write(mp); 584f7b951a8SRobert Watson } 585d50ef66dSTor Egge } 586f7b951a8SRobert Watson 587f7b951a8SRobert Watson NDFREE(&nd, 0); 5889eea3d85SChristian S.J. Peron VFS_UNLOCK_GIANT(vfslocked); 589eca8a663SRobert Watson out: 590eca8a663SRobert Watson mac_vnode_label_free(intlabel); 591f7b951a8SRobert Watson return (error); 592f7b951a8SRobert Watson } 593f7b951a8SRobert Watson 59427f2eac7SRobert Watson int 59527f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap) 59627f2eac7SRobert Watson { 59727f2eac7SRobert Watson struct mac_policy_conf *mpc; 59827f2eac7SRobert Watson char target[MAC_MAX_POLICY_NAME]; 59941a17fe3SRobert Watson int entrycount, error; 60027f2eac7SRobert Watson 601d1e405c5SAlfred Perlstein error = copyinstr(uap->policy, target, sizeof(target), NULL); 60227f2eac7SRobert Watson if (error) 60327f2eac7SRobert Watson return (error); 60427f2eac7SRobert Watson 60527f2eac7SRobert Watson error = ENOSYS; 606a6a65b05SRobert Watson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 60727f2eac7SRobert Watson if (strcmp(mpc->mpc_name, target) == 0 && 60827f2eac7SRobert Watson mpc->mpc_ops->mpo_syscall != NULL) { 60927f2eac7SRobert Watson error = mpc->mpc_ops->mpo_syscall(td, 610d1e405c5SAlfred Perlstein uap->call, uap->arg); 61127f2eac7SRobert Watson goto out; 61227f2eac7SRobert Watson } 61327f2eac7SRobert Watson } 61427f2eac7SRobert Watson 61541a17fe3SRobert Watson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 61641a17fe3SRobert Watson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 61741a17fe3SRobert Watson if (strcmp(mpc->mpc_name, target) == 0 && 61841a17fe3SRobert Watson mpc->mpc_ops->mpo_syscall != NULL) { 61941a17fe3SRobert Watson error = mpc->mpc_ops->mpo_syscall(td, 62041a17fe3SRobert Watson uap->call, uap->arg); 62141a17fe3SRobert Watson break; 62241a17fe3SRobert Watson } 62341a17fe3SRobert Watson } 62441a17fe3SRobert Watson mac_policy_list_unbusy(); 62541a17fe3SRobert Watson } 62627f2eac7SRobert Watson out: 62727f2eac7SRobert Watson return (error); 62827f2eac7SRobert Watson } 62927f2eac7SRobert Watson 63095fab37eSRobert Watson #else /* !MAC */ 6317bc82500SRobert Watson 6327bc82500SRobert Watson int 633f7b951a8SRobert Watson __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 634f7b951a8SRobert Watson { 635f7b951a8SRobert Watson 636f7b951a8SRobert Watson return (ENOSYS); 637f7b951a8SRobert Watson } 638f7b951a8SRobert Watson 639f7b951a8SRobert Watson int 6407bc82500SRobert Watson __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 6417bc82500SRobert Watson { 6427bc82500SRobert Watson 6437bc82500SRobert Watson return (ENOSYS); 6447bc82500SRobert Watson } 6457bc82500SRobert Watson 6467bc82500SRobert Watson int 6477bc82500SRobert Watson __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 6487bc82500SRobert Watson { 6497bc82500SRobert Watson 6507bc82500SRobert Watson return (ENOSYS); 6517bc82500SRobert Watson } 6527bc82500SRobert Watson 6537bc82500SRobert Watson int 6547bc82500SRobert Watson __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 6557bc82500SRobert Watson { 6567bc82500SRobert Watson 6577bc82500SRobert Watson return (ENOSYS); 6587bc82500SRobert Watson } 6597bc82500SRobert Watson 6607bc82500SRobert Watson int 6617bc82500SRobert Watson __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 6627bc82500SRobert Watson { 6637bc82500SRobert Watson 6647bc82500SRobert Watson return (ENOSYS); 6657bc82500SRobert Watson } 6667bc82500SRobert Watson 6677bc82500SRobert Watson int 668f7b951a8SRobert Watson __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 669f7b951a8SRobert Watson { 670f7b951a8SRobert Watson 671f7b951a8SRobert Watson return (ENOSYS); 672f7b951a8SRobert Watson } 673f7b951a8SRobert Watson 674f7b951a8SRobert Watson int 6757bc82500SRobert Watson __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 6767bc82500SRobert Watson { 6777bc82500SRobert Watson 6787bc82500SRobert Watson return (ENOSYS); 6797bc82500SRobert Watson } 6807bc82500SRobert Watson 6817bc82500SRobert Watson int 6827bc82500SRobert Watson __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 6837bc82500SRobert Watson { 6847bc82500SRobert Watson 6857bc82500SRobert Watson return (ENOSYS); 6867bc82500SRobert Watson } 68795fab37eSRobert Watson 68827f2eac7SRobert Watson int 689f7b951a8SRobert Watson __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 690f7b951a8SRobert Watson { 691f7b951a8SRobert Watson 692f7b951a8SRobert Watson return (ENOSYS); 693f7b951a8SRobert Watson } 694f7b951a8SRobert Watson 695f7b951a8SRobert Watson int 69627f2eac7SRobert Watson mac_syscall(struct thread *td, struct mac_syscall_args *uap) 69727f2eac7SRobert Watson { 69827f2eac7SRobert Watson 69927f2eac7SRobert Watson return (ENOSYS); 70027f2eac7SRobert Watson } 70127f2eac7SRobert Watson 70219b78822SRobert Watson #endif /* !MAC */ 703