1100894Srwatson/*- 2189797Srwatson * Copyright (c) 1999-2002, 2006, 2009 Robert N. M. Watson 3100894Srwatson * Copyright (c) 2001 Ilmar S. Habibulin 4145160Srwatson * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 5163606Srwatson * Copyright (c) 2005-2006 SPARTA, Inc. 6182063Srwatson * Copyright (c) 2008 Apple Inc. 7100894Srwatson * All rights reserved. 8100894Srwatson * 9100894Srwatson * This software was developed by Robert Watson and Ilmar Habibulin for the 10100894Srwatson * TrustedBSD Project. 11100894Srwatson * 12106392Srwatson * This software was developed for the FreeBSD Project in part by Network 13106392Srwatson * Associates Laboratories, the Security Research Division of Network 14106392Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 15106392Srwatson * as part of the DARPA CHATS research program. 16100894Srwatson * 17147983Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract 18147983Srwatson * N66001-04-C-6019 ("SEFOS"). 19147983Srwatson * 20189797Srwatson * This software was developed at the University of Cambridge Computer 21189797Srwatson * Laboratory with support from a grant from Google, Inc. 22189797Srwatson * 23100894Srwatson * Redistribution and use in source and binary forms, with or without 24100894Srwatson * modification, are permitted provided that the following conditions 25100894Srwatson * are met: 26100894Srwatson * 1. Redistributions of source code must retain the above copyright 27100894Srwatson * notice, this list of conditions and the following disclaimer. 28100894Srwatson * 2. Redistributions in binary form must reproduce the above copyright 29100894Srwatson * notice, this list of conditions and the following disclaimer in the 30100894Srwatson * documentation and/or other materials provided with the distribution. 31100894Srwatson * 32100894Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 33100894Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34100894Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35100894Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 36100894Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37100894Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38100894Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39100894Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40100894Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41100894Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42100894Srwatson * SUCH DAMAGE. 43100894Srwatson */ 44116182Sobrien 45116182Sobrien#include <sys/cdefs.h> 46116182Sobrien__FBSDID("$FreeBSD$"); 47116182Sobrien 48100894Srwatson#include "opt_mac.h" 49101173Srwatson 50100894Srwatson#include <sys/param.h> 51224778Srwatson#include <sys/capability.h> 52177785Skib#include <sys/fcntl.h> 53100979Srwatson#include <sys/kernel.h> 54100979Srwatson#include <sys/lock.h> 55102949Sbde#include <sys/malloc.h> 56100979Srwatson#include <sys/mutex.h> 57100979Srwatson#include <sys/mac.h> 58100979Srwatson#include <sys/proc.h> 59100979Srwatson#include <sys/systm.h> 60219028Snetchild#include <sys/sysctl.h> 61100894Srwatson#include <sys/sysproto.h> 62100894Srwatson#include <sys/sysent.h> 63100979Srwatson#include <sys/vnode.h> 64100979Srwatson#include <sys/mount.h> 65100979Srwatson#include <sys/file.h> 66100979Srwatson#include <sys/namei.h> 67100979Srwatson#include <sys/socket.h> 68100979Srwatson#include <sys/pipe.h> 69100979Srwatson#include <sys/socketvar.h> 70100894Srwatson 71163606Srwatson#include <security/mac/mac_framework.h> 72121374Srwatson#include <security/mac/mac_internal.h> 73165469Srwatson#include <security/mac/mac_policy.h> 74121374Srwatson 75100979Srwatson#ifdef MAC 76100979Srwatson 77219258SnetchildFEATURE(security_mac, "Mandatory Access Control Framework support"); 78219028Snetchild 79105988Srwatsonint 80225617Skmacysys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 81105694Srwatson{ 82105694Srwatson char *elements, *buffer; 83105694Srwatson struct mac mac; 84105694Srwatson struct proc *tproc; 85105694Srwatson struct ucred *tcred; 86105694Srwatson int error; 87105694Srwatson 88107849Salfred error = copyin(uap->mac_p, &mac, sizeof(mac)); 89105694Srwatson if (error) 90105694Srwatson return (error); 91105694Srwatson 92105694Srwatson error = mac_check_structmac_consistent(&mac); 93105694Srwatson if (error) 94105694Srwatson return (error); 95105694Srwatson 96105694Srwatson tproc = pfind(uap->pid); 97105694Srwatson if (tproc == NULL) 98105694Srwatson return (ESRCH); 99105694Srwatson 100105694Srwatson tcred = NULL; /* Satisfy gcc. */ 101105694Srwatson error = p_cansee(td, tproc); 102105694Srwatson if (error == 0) 103105694Srwatson tcred = crhold(tproc->p_ucred); 104105694Srwatson PROC_UNLOCK(tproc); 105105694Srwatson if (error) 106105694Srwatson return (error); 107105694Srwatson 108111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 109105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 110105694Srwatson if (error) { 111105694Srwatson free(elements, M_MACTEMP); 112105694Srwatson crfree(tcred); 113105694Srwatson return (error); 114105694Srwatson } 115105694Srwatson 116111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 117172930Srwatson error = mac_cred_externalize_label(tcred->cr_label, elements, 118122159Srwatson buffer, mac.m_buflen); 119105694Srwatson if (error == 0) 120105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 121105694Srwatson 122105694Srwatson free(buffer, M_MACTEMP); 123105694Srwatson free(elements, M_MACTEMP); 124105694Srwatson crfree(tcred); 125105694Srwatson return (error); 126105694Srwatson} 127105694Srwatson 128100979Srwatsonint 129225617Skmacysys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 130100894Srwatson{ 131105694Srwatson char *elements, *buffer; 132105694Srwatson struct mac mac; 133100979Srwatson int error; 134100894Srwatson 135105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 136105694Srwatson if (error) 137105694Srwatson return (error); 138105694Srwatson 139105694Srwatson error = mac_check_structmac_consistent(&mac); 140105694Srwatson if (error) 141105694Srwatson return (error); 142105694Srwatson 143111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 144105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 145105694Srwatson if (error) { 146105694Srwatson free(elements, M_MACTEMP); 147105694Srwatson return (error); 148105694Srwatson } 149105694Srwatson 150111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 151172930Srwatson error = mac_cred_externalize_label(td->td_ucred->cr_label, 152122159Srwatson elements, buffer, mac.m_buflen); 153100979Srwatson if (error == 0) 154105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 155100979Srwatson 156105694Srwatson free(buffer, M_MACTEMP); 157105694Srwatson free(elements, M_MACTEMP); 158100979Srwatson return (error); 159100979Srwatson} 160100979Srwatson 161100979Srwatsonint 162225617Skmacysys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 163100979Srwatson{ 164100979Srwatson struct ucred *newcred, *oldcred; 165122524Srwatson struct label *intlabel; 166100979Srwatson struct proc *p; 167105694Srwatson struct mac mac; 168105694Srwatson char *buffer; 169100979Srwatson int error; 170100979Srwatson 171182063Srwatson if (!(mac_labeled & MPC_OBJECT_CRED)) 172182063Srwatson return (EINVAL); 173182063Srwatson 174105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 175100979Srwatson if (error) 176100979Srwatson return (error); 177100979Srwatson 178105694Srwatson error = mac_check_structmac_consistent(&mac); 179100979Srwatson if (error) 180100979Srwatson return (error); 181100979Srwatson 182111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 183105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 184105694Srwatson if (error) { 185105694Srwatson free(buffer, M_MACTEMP); 186105694Srwatson return (error); 187105694Srwatson } 188105694Srwatson 189122524Srwatson intlabel = mac_cred_label_alloc(); 190172930Srwatson error = mac_cred_internalize_label(intlabel, buffer); 191105694Srwatson free(buffer, M_MACTEMP); 192122524Srwatson if (error) 193122524Srwatson goto out; 194105694Srwatson 195100979Srwatson newcred = crget(); 196100979Srwatson 197100979Srwatson p = td->td_proc; 198100979Srwatson PROC_LOCK(p); 199100979Srwatson oldcred = p->p_ucred; 200100979Srwatson 201172930Srwatson error = mac_cred_check_relabel(oldcred, intlabel); 202100979Srwatson if (error) { 203100979Srwatson PROC_UNLOCK(p); 204100979Srwatson crfree(newcred); 205105694Srwatson goto out; 206100979Srwatson } 207100979Srwatson 208100979Srwatson setsugid(p); 209100979Srwatson crcopy(newcred, oldcred); 210172930Srwatson mac_cred_relabel(newcred, intlabel); 211102136Srwatson p->p_ucred = newcred; 212100979Srwatson 213100979Srwatson PROC_UNLOCK(p); 214100979Srwatson crfree(oldcred); 215184412Srwatson mac_proc_vm_revoke(td); 216105694Srwatson 217105694Srwatsonout: 218122524Srwatson mac_cred_label_free(intlabel); 219105694Srwatson return (error); 220100979Srwatson} 221100979Srwatson 222100979Srwatsonint 223225617Skmacysys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 224100979Srwatson{ 225105694Srwatson char *elements, *buffer; 226122524Srwatson struct label *intlabel; 227100979Srwatson struct file *fp; 228105694Srwatson struct mac mac; 229100979Srwatson struct vnode *vp; 230100979Srwatson struct pipe *pipe; 231122820Srwatson struct socket *so; 232255219Spjd cap_rights_t rights; 233105694Srwatson short label_type; 234241896Skib int error; 235100979Srwatson 236105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 237105694Srwatson if (error) 238105694Srwatson return (error); 239100979Srwatson 240105694Srwatson error = mac_check_structmac_consistent(&mac); 241105694Srwatson if (error) 242105694Srwatson return (error); 243105694Srwatson 244111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 245105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 246105694Srwatson if (error) { 247105694Srwatson free(elements, M_MACTEMP); 248105694Srwatson return (error); 249105694Srwatson } 250105694Srwatson 251111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 252255219Spjd error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_GET), &fp); 253100979Srwatson if (error) 254100979Srwatson goto out; 255100979Srwatson 256105694Srwatson label_type = fp->f_type; 257100979Srwatson switch (fp->f_type) { 258100979Srwatson case DTYPE_FIFO: 259100979Srwatson case DTYPE_VNODE: 260234032Srwatson if (!(mac_labeled & MPC_OBJECT_VNODE)) { 261234032Srwatson error = EINVAL; 262234032Srwatson goto out_fdrop; 263234032Srwatson } 264116678Sphk vp = fp->f_vnode; 265122524Srwatson intlabel = mac_vnode_label_alloc(); 266175202Sattilio vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 267172930Srwatson mac_vnode_copy_label(vp->v_label, intlabel); 268175294Sattilio VOP_UNLOCK(vp, 0); 269172930Srwatson error = mac_vnode_externalize_label(intlabel, elements, 270122584Srwatson buffer, mac.m_buflen); 271122584Srwatson mac_vnode_label_free(intlabel); 272122584Srwatson break; 273105694Srwatson 274100979Srwatson case DTYPE_PIPE: 275234032Srwatson if (!(mac_labeled & MPC_OBJECT_PIPE)) { 276234032Srwatson error = EINVAL; 277234032Srwatson goto out_fdrop; 278234032Srwatson } 279109153Sdillon pipe = fp->f_data; 280122524Srwatson intlabel = mac_pipe_label_alloc(); 281105694Srwatson PIPE_LOCK(pipe); 282172930Srwatson mac_pipe_copy_label(pipe->pipe_pair->pp_label, intlabel); 283105694Srwatson PIPE_UNLOCK(pipe); 284172930Srwatson error = mac_pipe_externalize_label(intlabel, elements, 285122159Srwatson buffer, mac.m_buflen); 286122524Srwatson mac_pipe_label_free(intlabel); 287105694Srwatson break; 288122584Srwatson 289122820Srwatson case DTYPE_SOCKET: 290234032Srwatson if (!(mac_labeled & MPC_OBJECT_SOCKET)) { 291234032Srwatson error = EINVAL; 292234032Srwatson goto out_fdrop; 293234032Srwatson } 294122820Srwatson so = fp->f_data; 295122820Srwatson intlabel = mac_socket_label_alloc(M_WAITOK); 296145160Srwatson SOCK_LOCK(so); 297172930Srwatson mac_socket_copy_label(so->so_label, intlabel); 298145160Srwatson SOCK_UNLOCK(so); 299172930Srwatson error = mac_socket_externalize_label(intlabel, elements, 300122820Srwatson buffer, mac.m_buflen); 301122820Srwatson mac_socket_label_free(intlabel); 302122820Srwatson break; 303122820Srwatson 304105694Srwatson default: 305122584Srwatson error = EINVAL; 306105694Srwatson } 307100979Srwatson if (error == 0) 308105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 309234032Srwatsonout_fdrop: 310234032Srwatson fdrop(fp, td); 311105694Srwatsonout: 312105694Srwatson free(buffer, M_MACTEMP); 313105694Srwatson free(elements, M_MACTEMP); 314100979Srwatson return (error); 315100979Srwatson} 316100979Srwatson 317100979Srwatsonint 318225617Skmacysys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 319100979Srwatson{ 320105694Srwatson char *elements, *buffer; 321100979Srwatson struct nameidata nd; 322122524Srwatson struct label *intlabel; 323105694Srwatson struct mac mac; 324241896Skib int error; 325100979Srwatson 326182063Srwatson if (!(mac_labeled & MPC_OBJECT_VNODE)) 327182063Srwatson return (EINVAL); 328182063Srwatson 329105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 330105694Srwatson if (error) 331105694Srwatson return (error); 332105694Srwatson 333105694Srwatson error = mac_check_structmac_consistent(&mac); 334105694Srwatson if (error) 335105694Srwatson return (error); 336105694Srwatson 337111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 338105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 339105694Srwatson if (error) { 340105694Srwatson free(elements, M_MACTEMP); 341105694Srwatson return (error); 342105694Srwatson } 343105694Srwatson 344111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 345241896Skib NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 346150914Scsjp uap->path_p, td); 347100979Srwatson error = namei(&nd); 348100979Srwatson if (error) 349100979Srwatson goto out; 350100979Srwatson 351122524Srwatson intlabel = mac_vnode_label_alloc(); 352172930Srwatson mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); 353172930Srwatson error = mac_vnode_externalize_label(intlabel, elements, buffer, 354122159Srwatson mac.m_buflen); 355105694Srwatson 356100979Srwatson NDFREE(&nd, 0); 357122524Srwatson mac_vnode_label_free(intlabel); 358105694Srwatson if (error == 0) 359105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 360105694Srwatson 361105694Srwatsonout: 362105694Srwatson free(buffer, M_MACTEMP); 363105694Srwatson free(elements, M_MACTEMP); 364105694Srwatson 365105694Srwatson return (error); 366105694Srwatson} 367105694Srwatson 368105694Srwatsonint 369225617Skmacysys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 370105694Srwatson{ 371105694Srwatson char *elements, *buffer; 372105694Srwatson struct nameidata nd; 373122524Srwatson struct label *intlabel; 374105694Srwatson struct mac mac; 375241896Skib int error; 376105694Srwatson 377182063Srwatson if (!(mac_labeled & MPC_OBJECT_VNODE)) 378182063Srwatson return (EINVAL); 379182063Srwatson 380105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 381100979Srwatson if (error) 382105694Srwatson return (error); 383105694Srwatson 384105694Srwatson error = mac_check_structmac_consistent(&mac); 385105694Srwatson if (error) 386105694Srwatson return (error); 387105694Srwatson 388111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 389105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 390105694Srwatson if (error) { 391105694Srwatson free(elements, M_MACTEMP); 392105694Srwatson return (error); 393105694Srwatson } 394105694Srwatson 395111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 396241896Skib NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, 397150914Scsjp uap->path_p, td); 398105694Srwatson error = namei(&nd); 399105694Srwatson if (error) 400100979Srwatson goto out; 401100979Srwatson 402122524Srwatson intlabel = mac_vnode_label_alloc(); 403172930Srwatson mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); 404172930Srwatson error = mac_vnode_externalize_label(intlabel, elements, buffer, 405122159Srwatson mac.m_buflen); 406105694Srwatson NDFREE(&nd, 0); 407122524Srwatson mac_vnode_label_free(intlabel); 408100979Srwatson 409105694Srwatson if (error == 0) 410105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 411105694Srwatson 412100979Srwatsonout: 413105694Srwatson free(buffer, M_MACTEMP); 414105694Srwatson free(elements, M_MACTEMP); 415105694Srwatson 416100979Srwatson return (error); 417100979Srwatson} 418100979Srwatson 419100979Srwatsonint 420225617Skmacysys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 421100979Srwatson{ 422122524Srwatson struct label *intlabel; 423105694Srwatson struct pipe *pipe; 424122820Srwatson struct socket *so; 425100979Srwatson struct file *fp; 426100979Srwatson struct mount *mp; 427100979Srwatson struct vnode *vp; 428105694Srwatson struct mac mac; 429255219Spjd cap_rights_t rights; 430105694Srwatson char *buffer; 431241896Skib int error; 432100979Srwatson 433105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 434100979Srwatson if (error) 435105694Srwatson return (error); 436100979Srwatson 437105694Srwatson error = mac_check_structmac_consistent(&mac); 438100979Srwatson if (error) 439105694Srwatson return (error); 440100979Srwatson 441111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 442105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 443105694Srwatson if (error) { 444105694Srwatson free(buffer, M_MACTEMP); 445105694Srwatson return (error); 446105694Srwatson } 447105694Srwatson 448255219Spjd error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_SET), &fp); 449100979Srwatson if (error) 450105694Srwatson goto out; 451100979Srwatson 452100979Srwatson switch (fp->f_type) { 453100979Srwatson case DTYPE_FIFO: 454100979Srwatson case DTYPE_VNODE: 455234032Srwatson if (!(mac_labeled & MPC_OBJECT_VNODE)) { 456234032Srwatson error = EINVAL; 457234032Srwatson goto out_fdrop; 458234032Srwatson } 459122524Srwatson intlabel = mac_vnode_label_alloc(); 460172930Srwatson error = mac_vnode_internalize_label(intlabel, buffer); 461105694Srwatson if (error) { 462122524Srwatson mac_vnode_label_free(intlabel); 463105694Srwatson break; 464105694Srwatson } 465116678Sphk vp = fp->f_vnode; 466100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 467105694Srwatson if (error != 0) { 468122524Srwatson mac_vnode_label_free(intlabel); 469100979Srwatson break; 470105694Srwatson } 471175202Sattilio vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 472122524Srwatson error = vn_setlabel(vp, intlabel, td->td_ucred); 473175294Sattilio VOP_UNLOCK(vp, 0); 474100979Srwatson vn_finished_write(mp); 475122524Srwatson mac_vnode_label_free(intlabel); 476100979Srwatson break; 477105694Srwatson 478100979Srwatson case DTYPE_PIPE: 479234032Srwatson if (!(mac_labeled & MPC_OBJECT_PIPE)) { 480234032Srwatson error = EINVAL; 481234032Srwatson goto out_fdrop; 482234032Srwatson } 483122524Srwatson intlabel = mac_pipe_label_alloc(); 484172930Srwatson error = mac_pipe_internalize_label(intlabel, buffer); 485105694Srwatson if (error == 0) { 486109153Sdillon pipe = fp->f_data; 487105694Srwatson PIPE_LOCK(pipe); 488125293Srwatson error = mac_pipe_label_set(td->td_ucred, 489125293Srwatson pipe->pipe_pair, intlabel); 490105694Srwatson PIPE_UNLOCK(pipe); 491105694Srwatson } 492122524Srwatson mac_pipe_label_free(intlabel); 493100979Srwatson break; 494105694Srwatson 495122820Srwatson case DTYPE_SOCKET: 496234032Srwatson if (!(mac_labeled & MPC_OBJECT_SOCKET)) { 497234032Srwatson error = EINVAL; 498234032Srwatson goto out_fdrop; 499234032Srwatson } 500122820Srwatson intlabel = mac_socket_label_alloc(M_WAITOK); 501172930Srwatson error = mac_socket_internalize_label(intlabel, buffer); 502122820Srwatson if (error == 0) { 503122820Srwatson so = fp->f_data; 504122820Srwatson error = mac_socket_label_set(td->td_ucred, so, 505122820Srwatson intlabel); 506122820Srwatson } 507122820Srwatson mac_socket_label_free(intlabel); 508122820Srwatson break; 509122820Srwatson 510100979Srwatson default: 511100979Srwatson error = EINVAL; 512100979Srwatson } 513234032Srwatsonout_fdrop: 514100979Srwatson fdrop(fp, td); 515105694Srwatsonout: 516105694Srwatson free(buffer, M_MACTEMP); 517100979Srwatson return (error); 518100979Srwatson} 519100979Srwatson 520100979Srwatsonint 521225617Skmacysys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 522100979Srwatson{ 523122524Srwatson struct label *intlabel; 524100979Srwatson struct nameidata nd; 525100979Srwatson struct mount *mp; 526105694Srwatson struct mac mac; 527105694Srwatson char *buffer; 528241896Skib int error; 529100979Srwatson 530182063Srwatson if (!(mac_labeled & MPC_OBJECT_VNODE)) 531182063Srwatson return (EINVAL); 532182063Srwatson 533105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 534100979Srwatson if (error) 535105694Srwatson return (error); 536100979Srwatson 537105694Srwatson error = mac_check_structmac_consistent(&mac); 538100979Srwatson if (error) 539105694Srwatson return (error); 540100979Srwatson 541111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 542105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 543105694Srwatson if (error) { 544105694Srwatson free(buffer, M_MACTEMP); 545105694Srwatson return (error); 546105694Srwatson } 547105694Srwatson 548122524Srwatson intlabel = mac_vnode_label_alloc(); 549172930Srwatson error = mac_vnode_internalize_label(intlabel, buffer); 550105694Srwatson free(buffer, M_MACTEMP); 551122524Srwatson if (error) 552122524Srwatson goto out; 553105694Srwatson 554241896Skib NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 555150914Scsjp uap->path_p, td); 556100979Srwatson error = namei(&nd); 557105694Srwatson if (error == 0) { 558105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 559156893Stegge if (error == 0) { 560122524Srwatson error = vn_setlabel(nd.ni_vp, intlabel, 561105694Srwatson td->td_ucred); 562156893Stegge vn_finished_write(mp); 563156893Stegge } 564105694Srwatson } 565105694Srwatson 566105694Srwatson NDFREE(&nd, 0); 567122524Srwatsonout: 568122524Srwatson mac_vnode_label_free(intlabel); 569105694Srwatson return (error); 570105694Srwatson} 571105694Srwatson 572105694Srwatsonint 573225617Skmacysys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 574105694Srwatson{ 575122524Srwatson struct label *intlabel; 576105694Srwatson struct nameidata nd; 577105694Srwatson struct mount *mp; 578105694Srwatson struct mac mac; 579105694Srwatson char *buffer; 580241896Skib int error; 581105694Srwatson 582182063Srwatson if (!(mac_labeled & MPC_OBJECT_VNODE)) 583182063Srwatson return (EINVAL); 584182063Srwatson 585105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 586100979Srwatson if (error) 587105694Srwatson return (error); 588105694Srwatson 589105694Srwatson error = mac_check_structmac_consistent(&mac); 590100979Srwatson if (error) 591105694Srwatson return (error); 592100979Srwatson 593111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 594105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 595105694Srwatson if (error) { 596105694Srwatson free(buffer, M_MACTEMP); 597105694Srwatson return (error); 598105694Srwatson } 599105694Srwatson 600122524Srwatson intlabel = mac_vnode_label_alloc(); 601172930Srwatson error = mac_vnode_internalize_label(intlabel, buffer); 602105694Srwatson free(buffer, M_MACTEMP); 603122524Srwatson if (error) 604122524Srwatson goto out; 605105694Srwatson 606241896Skib NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, 607150914Scsjp uap->path_p, td); 608105694Srwatson error = namei(&nd); 609105694Srwatson if (error == 0) { 610105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 611156893Stegge if (error == 0) { 612122524Srwatson error = vn_setlabel(nd.ni_vp, intlabel, 613105694Srwatson td->td_ucred); 614156893Stegge vn_finished_write(mp); 615156893Stegge } 616105694Srwatson } 617105694Srwatson 618100979Srwatson NDFREE(&nd, 0); 619122524Srwatsonout: 620122524Srwatson mac_vnode_label_free(intlabel); 621100979Srwatson return (error); 622100979Srwatson} 623100979Srwatson 624102123Srwatsonint 625225617Skmacysys_mac_syscall(struct thread *td, struct mac_syscall_args *uap) 626102123Srwatson{ 627102123Srwatson struct mac_policy_conf *mpc; 628102123Srwatson char target[MAC_MAX_POLICY_NAME]; 629189797Srwatson int error; 630102123Srwatson 631107849Salfred error = copyinstr(uap->policy, target, sizeof(target), NULL); 632102123Srwatson if (error) 633102123Srwatson return (error); 634102123Srwatson 635102123Srwatson error = ENOSYS; 636119494Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 637102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 638102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 639102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 640107849Salfred uap->call, uap->arg); 641102123Srwatson goto out; 642102123Srwatson } 643102123Srwatson } 644102123Srwatson 645189797Srwatson if (!LIST_EMPTY(&mac_policy_list)) { 646189797Srwatson mac_policy_slock_sleep(); 647114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 648114806Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 649114806Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 650114806Srwatson error = mpc->mpc_ops->mpo_syscall(td, 651114806Srwatson uap->call, uap->arg); 652114806Srwatson break; 653114806Srwatson } 654114806Srwatson } 655189797Srwatson mac_policy_sunlock_sleep(); 656114806Srwatson } 657102123Srwatsonout: 658102123Srwatson return (error); 659102123Srwatson} 660102123Srwatson 661100979Srwatson#else /* !MAC */ 662100979Srwatson 663100979Srwatsonint 664225617Skmacysys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 665105694Srwatson{ 666105694Srwatson 667105694Srwatson return (ENOSYS); 668105694Srwatson} 669105694Srwatson 670105694Srwatsonint 671225617Skmacysys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 672100979Srwatson{ 673100979Srwatson 674100894Srwatson return (ENOSYS); 675100894Srwatson} 676100894Srwatson 677100894Srwatsonint 678225617Skmacysys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 679100894Srwatson{ 680100894Srwatson 681100894Srwatson return (ENOSYS); 682100894Srwatson} 683100894Srwatson 684100894Srwatsonint 685225617Skmacysys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 686100894Srwatson{ 687100894Srwatson 688100894Srwatson return (ENOSYS); 689100894Srwatson} 690100894Srwatson 691100894Srwatsonint 692225617Skmacysys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 693100894Srwatson{ 694100894Srwatson 695100894Srwatson return (ENOSYS); 696100894Srwatson} 697100894Srwatson 698100894Srwatsonint 699225617Skmacysys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 700105694Srwatson{ 701105694Srwatson 702105694Srwatson return (ENOSYS); 703105694Srwatson} 704105694Srwatson 705105694Srwatsonint 706225617Skmacysys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 707100894Srwatson{ 708100894Srwatson 709100894Srwatson return (ENOSYS); 710100894Srwatson} 711100894Srwatson 712100894Srwatsonint 713225617Skmacysys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 714100894Srwatson{ 715100894Srwatson 716100894Srwatson return (ENOSYS); 717100894Srwatson} 718100979Srwatson 719102123Srwatsonint 720225617Skmacysys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 721105694Srwatson{ 722105694Srwatson 723105694Srwatson return (ENOSYS); 724105694Srwatson} 725105694Srwatson 726105694Srwatsonint 727225617Skmacysys_mac_syscall(struct thread *td, struct mac_syscall_args *uap) 728102123Srwatson{ 729102123Srwatson 730102123Srwatson return (ENOSYS); 731102123Srwatson} 732102123Srwatson 733128901Srwatson#endif /* !MAC */ 734