The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/security/mac_process.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2007-2010 Apple Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 
   29 /*-
   30  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
   31  * Copyright (c) 2001 Ilmar S. Habibulin
   32  * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc.
   33  *
   34  * This software was developed by Robert Watson and Ilmar Habibulin for the
   35  * TrustedBSD Project.
   36  *
   37  * This software was developed for the FreeBSD Project in part by Network
   38  * Associates Laboratories, the Security Research Division of Network
   39  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
   40  * as part of the DARPA CHATS research program.
   41  *
   42  * Redistribution and use in source and binary forms, with or without
   43  * modification, are permitted provided that the following conditions
   44  * are met:
   45  * 1. Redistributions of source code must retain the above copyright
   46  *    notice, this list of conditions and the following disclaimer.
   47  * 2. Redistributions in binary form must reproduce the above copyright
   48  *    notice, this list of conditions and the following disclaimer in the
   49  *    documentation and/or other materials provided with the distribution.
   50  *
   51  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   61  * SUCH DAMAGE.
   62  *
   63  */
   64 
   65 #include <string.h>
   66 #include <sys/param.h>
   67 #include <sys/ucred.h>
   68 #include <sys/malloc.h>
   69 #include <sys/sbuf.h>
   70 #include <sys/vnode.h>
   71 #include <sys/proc.h>
   72 #include <sys/proc_internal.h>
   73 #include <sys/kauth.h>
   74 #include <sys/imgact.h>
   75 #include <mach/mach_types.h>
   76 
   77 #include <security/mac_internal.h>
   78 #include <security/mac_mach_internal.h>
   79 
   80 #include <bsd/security/audit/audit.h>
   81 
   82 struct label *
   83 mac_cred_label_alloc(void)
   84 {
   85         struct label *label;
   86 
   87         label = mac_labelzone_alloc(MAC_WAITOK);
   88         if (label == NULL)
   89                 return (NULL);
   90         MAC_PERFORM(cred_label_init, label);
   91         return (label);
   92 }
   93 
   94 void
   95 mac_cred_label_init(struct ucred *cred)
   96 {
   97         cred->cr_label = mac_cred_label_alloc();
   98 }
   99 
  100 void
  101 mac_cred_label_free(struct label *label)
  102 {
  103         MAC_PERFORM(cred_label_destroy, label);
  104         mac_labelzone_free(label);
  105 }
  106 
  107 int
  108 mac_cred_label_compare(struct label *a, struct label *b)
  109 {
  110         return (bcmp(a, b, sizeof (*a)) == 0);
  111 }
  112 
  113 int
  114 mac_cred_label_externalize_audit(struct proc *p, struct mac *mac)
  115 {
  116         kauth_cred_t cr;
  117         int error;
  118 
  119         cr = kauth_cred_proc_ref(p);
  120 
  121         error = MAC_EXTERNALIZE_AUDIT(cred, cr->cr_label,
  122             mac->m_string, mac->m_buflen);
  123 
  124         kauth_cred_unref(&cr);
  125         return (error);
  126 }
  127 
  128 void
  129 mac_cred_label_destroy(kauth_cred_t cred)
  130 {
  131 
  132         mac_cred_label_free(cred->cr_label);
  133         cred->cr_label = NULL;
  134 }
  135 
  136 int
  137 mac_cred_label_externalize(struct label *label, char *elements,
  138     char *outbuf, size_t outbuflen, int flags __unused)
  139 {
  140         int error = 0;
  141 
  142         error = MAC_EXTERNALIZE(cred, label, elements, outbuf, outbuflen);
  143 
  144         return (error);
  145 }
  146 
  147 int
  148 mac_cred_label_internalize(struct label *label, char *string)
  149 {
  150         int error;
  151 
  152         error = MAC_INTERNALIZE(cred, label, string);
  153 
  154         return (error);
  155 }
  156 
  157 /*
  158  * By default, fork just adds a reference to the parent
  159  * credential.  Policies may need to know about this reference
  160  * if they are tracking exit calls to know when to free the
  161  * label.
  162  */
  163 void
  164 mac_cred_label_associate_fork(kauth_cred_t cred, proc_t proc)
  165 {
  166         MAC_PERFORM(cred_label_associate_fork, cred, proc);
  167 }
  168         
  169 /*
  170  * Initialize MAC label for the first kernel process, from which other
  171  * kernel processes and threads are spawned.
  172  */
  173 void
  174 mac_cred_label_associate_kernel(kauth_cred_t cred)
  175 {
  176 
  177         MAC_PERFORM(cred_label_associate_kernel, cred);
  178 }
  179 
  180 /*
  181  * Initialize MAC label for the first userland process, from which other
  182  * userland processes and threads are spawned.
  183  */
  184 void
  185 mac_cred_label_associate_user(kauth_cred_t cred)
  186 {
  187 
  188         MAC_PERFORM(cred_label_associate_user, cred);
  189 }
  190 
  191 /*
  192  * When a new process is created, its label must be initialized.  Generally,
  193  * this involves inheritence from the parent process, modulo possible
  194  * deltas.  This function allows that processing to take place.
  195  */
  196 void
  197 mac_cred_label_associate(struct ucred *parent_cred, struct ucred *child_cred)
  198 {
  199 
  200         MAC_PERFORM(cred_label_associate, parent_cred, child_cred);
  201 }
  202 
  203 int
  204 mac_execve_enter(user_addr_t mac_p, struct image_params *imgp)
  205 {
  206         struct user_mac mac;
  207         struct label *execlabel;
  208         char *buffer;
  209         int error;
  210         size_t ulen;
  211 
  212         if (mac_p == USER_ADDR_NULL)
  213                 return (0);
  214 
  215         if (IS_64BIT_PROCESS(current_proc())) {
  216                 struct user64_mac mac64;
  217                 error = copyin(mac_p, &mac64, sizeof(mac64));
  218                 mac.m_buflen = mac64.m_buflen;
  219                 mac.m_string = mac64.m_string;
  220         } else {
  221                 struct user32_mac mac32;
  222                 error = copyin(mac_p, &mac32, sizeof(mac32));
  223                 mac.m_buflen = mac32.m_buflen;
  224                 mac.m_string = mac32.m_string;
  225         }
  226         if (error)
  227                 return (error);
  228 
  229         error = mac_check_structmac_consistent(&mac);
  230         if (error)
  231                 return (error);
  232 
  233         execlabel = mac_cred_label_alloc();
  234         MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
  235         error = copyinstr(CAST_USER_ADDR_T(mac.m_string), buffer, mac.m_buflen, &ulen);
  236         if (error)
  237                 goto out;
  238         AUDIT_ARG(mac_string, buffer);
  239 
  240         error = mac_cred_label_internalize(execlabel, buffer);
  241 out:
  242         if (error) {
  243                 mac_cred_label_free(execlabel);
  244                 execlabel = NULL;
  245         }
  246         imgp->ip_execlabelp = execlabel;
  247         FREE(buffer, M_MACTEMP);
  248         return (error);
  249 }
  250 
  251 /*
  252  * When the subject's label changes, it may require revocation of privilege
  253  * to mapped objects.  This can't be done on-the-fly later with a unified
  254  * buffer cache.
  255  *
  256  * XXX:         CRF_MAC_ENFORCE should be in a kauth_cred_t field, rather
  257  * XXX:         than a posix_cred_t field.
  258  */
  259 void
  260 mac_cred_label_update(kauth_cred_t cred, struct label *newlabel)
  261 {
  262         posix_cred_t pcred = posix_cred_get(cred);
  263 
  264         /* force label to be part of "matching" for credential */
  265         pcred->cr_flags |= CRF_MAC_ENFORCE;
  266 
  267         /* inform the policies of the update */
  268         MAC_PERFORM(cred_label_update, cred, newlabel);
  269 }
  270 
  271 int
  272 mac_cred_check_label_update(kauth_cred_t cred, struct label *newlabel)
  273 {
  274         int error;
  275 
  276         if (!mac_proc_enforce)
  277                 return (0);
  278 
  279         MAC_CHECK(cred_check_label_update, cred, newlabel);
  280 
  281         return (error);
  282 }
  283 
  284 int
  285 mac_cred_check_visible(kauth_cred_t u1, kauth_cred_t u2)
  286 {
  287         int error;
  288 
  289 
  290 
  291         if (!mac_proc_enforce)
  292                 return (0);
  293 
  294 
  295 
  296         MAC_CHECK(cred_check_visible, u1, u2);
  297 
  298 
  299         return (error);
  300 }
  301 
  302 /*                                                                                                    
  303  * called with process locked.                                                                        
  304  */
  305 void mac_proc_set_enforce(proc_t p, int enforce_flags)
  306 {
  307         p->p_mac_enforce |= enforce_flags;
  308 }
  309 
  310 int
  311 mac_proc_check_debug(proc_t curp, struct proc *proc)
  312 {
  313         kauth_cred_t cred;
  314         int error;
  315 
  316 
  317 
  318         if (!mac_proc_enforce ||
  319             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  320                 return (0);
  321 
  322         cred = kauth_cred_proc_ref(curp);
  323         MAC_CHECK(proc_check_debug, cred, proc);
  324         kauth_cred_unref(&cred);
  325 
  326         return (error);
  327 }
  328 
  329 int
  330 mac_proc_check_fork(proc_t curp)
  331 {
  332         kauth_cred_t cred;
  333         int error;
  334 
  335         if (!mac_proc_enforce ||
  336             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  337                 return (0);
  338 
  339         cred = kauth_cred_proc_ref(curp);
  340         MAC_CHECK(proc_check_fork, cred, curp);
  341         kauth_cred_unref(&cred);
  342 
  343         return (error);
  344 }
  345 
  346 int
  347 mac_proc_check_get_task_name(struct ucred *cred, struct proc *p)
  348 {
  349         int error;
  350 
  351         MAC_CHECK(proc_check_get_task_name, cred, p);
  352 
  353         return (error);
  354 }
  355 
  356 int
  357 mac_proc_check_get_task(struct ucred *cred, struct proc *p)
  358 {
  359         int error;
  360 
  361         MAC_CHECK(proc_check_get_task, cred, p);
  362 
  363         return (error);
  364 }
  365 
  366 /*
  367  * The type of maxprot in proc_check_map_anon must be equivalent to vm_prot_t
  368  * (defined in <mach/vm_prot.h>). mac_policy.h does not include any header
  369  * files, so cannot use the typedef itself.
  370  */
  371 int
  372 mac_proc_check_map_anon(proc_t proc, user_addr_t u_addr,
  373     user_size_t u_size, int prot, int flags, int *maxprot)
  374 {
  375         kauth_cred_t cred;
  376         int error;
  377 
  378         if (!mac_vm_enforce ||
  379             !mac_proc_check_enforce(proc, MAC_VM_ENFORCE))
  380                 return (0);
  381 
  382         cred = kauth_cred_proc_ref(proc);
  383         MAC_CHECK(proc_check_map_anon, proc, cred, u_addr, u_size, prot, flags, maxprot);
  384         kauth_cred_unref(&cred);
  385 
  386         return (error);
  387 }
  388 
  389 int
  390 mac_proc_check_mprotect(proc_t proc,
  391     user_addr_t addr, user_size_t size, int prot)
  392 {
  393         kauth_cred_t cred;
  394         int error;
  395 
  396         if (!mac_vm_enforce ||
  397             !mac_proc_check_enforce(proc, MAC_VM_ENFORCE))
  398                 return (0);
  399 
  400         cred = kauth_cred_proc_ref(proc);
  401         MAC_CHECK(proc_check_mprotect, cred, proc, addr, size, prot);
  402         kauth_cred_unref(&cred);
  403 
  404         return (error);
  405 }
  406 
  407 int
  408 mac_proc_check_run_cs_invalid(proc_t proc)
  409 {
  410         int error;
  411         
  412         if (!mac_vm_enforce) return (0);
  413         
  414         MAC_CHECK(proc_check_run_cs_invalid, proc);
  415         
  416         return (error);
  417 }
  418                                    
  419 int
  420 mac_proc_check_sched(proc_t curp, struct proc *proc)
  421 {
  422         kauth_cred_t cred;
  423         int error;
  424 
  425 
  426 
  427         if (!mac_proc_enforce ||
  428             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  429                 return (0);
  430 
  431         cred = kauth_cred_proc_ref(curp);
  432         MAC_CHECK(proc_check_sched, cred, proc);
  433         kauth_cred_unref(&cred);
  434 
  435         return (error);
  436 }
  437 
  438 int
  439 mac_proc_check_signal(proc_t curp, struct proc *proc, int signum)
  440 {
  441         kauth_cred_t cred;
  442         int error;
  443 
  444 
  445 
  446         if (!mac_proc_enforce ||
  447             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  448                 return (0);
  449 
  450         cred = kauth_cred_proc_ref(curp);
  451         MAC_CHECK(proc_check_signal, cred, proc, signum);
  452         kauth_cred_unref(&cred);
  453 
  454         return (error);
  455 }
  456 
  457 int
  458 mac_proc_check_wait(proc_t curp, struct proc *proc)
  459 {
  460         kauth_cred_t cred;
  461         int error;
  462 
  463 
  464 
  465         if (!mac_proc_enforce ||
  466             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  467                 return (0);
  468 
  469         cred = kauth_cred_proc_ref(curp);
  470         MAC_CHECK(proc_check_wait, cred, proc);
  471         kauth_cred_unref(&cred);
  472 
  473         return (error);
  474 }
  475 
  476 #if CONFIG_LCTX
  477 /*
  478  * Login Context
  479  */
  480 
  481 int
  482 mac_proc_check_setlcid (struct proc *p0, struct proc *p,
  483                         pid_t pid, pid_t lcid)
  484 {
  485         int error;
  486 
  487         if (!mac_proc_enforce ||
  488             !mac_proc_check_enforce(p0, MAC_PROC_ENFORCE))
  489                 return (0);
  490 
  491         MAC_CHECK(proc_check_setlcid, p0, p, pid, lcid);
  492         return (error);
  493 }
  494 
  495 int
  496 mac_proc_check_getlcid (struct proc *p0, struct proc *p, pid_t pid)
  497 {
  498         int error;
  499 
  500         if (!mac_proc_enforce ||
  501             !mac_proc_check_enforce(p0, MAC_PROC_ENFORCE))
  502                 return (0);
  503 
  504         MAC_CHECK(proc_check_getlcid, p0, p, pid);
  505         return (error);
  506 }
  507 
  508 void
  509 mac_lctx_notify_create (struct proc *p, struct lctx *l)
  510 {
  511         MAC_PERFORM(lctx_notify_create, p, l);
  512 }
  513 
  514 void
  515 mac_lctx_notify_join (struct proc *p, struct lctx *l)
  516 {
  517         MAC_PERFORM(lctx_notify_join, p, l);
  518 }
  519 
  520 void
  521 mac_lctx_notify_leave (struct proc *p, struct lctx *l)
  522 {
  523         MAC_PERFORM(lctx_notify_leave, p, l);
  524 }
  525 
  526 struct label *
  527 mac_lctx_label_alloc(void)
  528 {
  529         struct label *label;
  530 
  531         label = mac_labelzone_alloc(MAC_WAITOK);
  532         if (label == NULL)
  533                 return (NULL);
  534         MAC_PERFORM(lctx_label_init, label);
  535         return (label);
  536 }
  537 
  538 void
  539 mac_lctx_label_free(struct label *label)
  540 {
  541 
  542         MAC_PERFORM(lctx_label_destroy, label);
  543         mac_labelzone_free(label);
  544 }
  545 
  546 int
  547 mac_lctx_label_externalize(struct label *label, char *elements,
  548     char *outbuf, size_t outbuflen)
  549 {
  550         int error;
  551 
  552         error = MAC_EXTERNALIZE(lctx, label, elements, outbuf, outbuflen);
  553 
  554         return (error);
  555 }
  556 
  557 int
  558 mac_lctx_label_internalize(struct label *label, char *string)
  559 {
  560         int error;
  561 
  562         error = MAC_INTERNALIZE(lctx, label, string);
  563 
  564         return (error);
  565 }
  566 
  567 void
  568 mac_lctx_label_update(struct lctx *l, struct label *newlabel)
  569 {
  570 
  571         MAC_PERFORM(lctx_label_update, l, newlabel);
  572 }
  573 
  574 int
  575 mac_lctx_check_label_update(struct lctx *l, struct label *newlabel)
  576 {
  577         int error;
  578 
  579         MAC_CHECK(lctx_check_label_update, l, newlabel);
  580 
  581         return (error);
  582 }
  583 #endif  /* LCTX */
  584 
  585 int
  586 mac_proc_check_suspend_resume(proc_t curp, int sr)
  587 {
  588         kauth_cred_t cred;
  589         int error;
  590 
  591         if (!mac_proc_enforce ||
  592             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  593                 return (0);
  594 
  595         cred = kauth_cred_proc_ref(curp);
  596         MAC_CHECK(proc_check_suspend_resume, cred, curp, sr);
  597         kauth_cred_unref(&cred);
  598 
  599         return (error);
  600 }
  601 
  602 int
  603 mac_proc_check_ledger(proc_t curp, proc_t proc, int ledger_op)
  604 {
  605         kauth_cred_t cred;
  606         int error = 0;
  607 
  608         if (!mac_proc_enforce ||
  609             !mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
  610                 return (0);
  611 
  612         cred = kauth_cred_proc_ref(curp);
  613         MAC_CHECK(proc_check_ledger, cred, proc, ledger_op);
  614         kauth_cred_unref(&cred);
  615 
  616         return (error);
  617 }
  618 
  619 struct label *
  620 mac_thread_label_alloc(void)
  621 {
  622         struct label *label;
  623 
  624         label = mac_labelzone_alloc(MAC_WAITOK);
  625         if (label == NULL)
  626                 return (NULL);
  627         MAC_PERFORM(thread_label_init, label);
  628         return (label);
  629 }
  630 
  631 void
  632 mac_thread_label_init(struct uthread *uthread)
  633 {
  634         uthread->uu_label = mac_thread_label_alloc();
  635 }
  636 
  637 void
  638 mac_thread_label_free(struct label *label)
  639 {
  640         MAC_PERFORM(thread_label_destroy, label);
  641         mac_labelzone_free(label);
  642 }
  643 
  644 void
  645 mac_thread_label_destroy(struct uthread *uthread)
  646 {
  647 
  648         mac_thread_label_free(uthread->uu_label);
  649         uthread->uu_label = NULL;
  650 }
  651 
  652 void
  653 mac_thread_userret(struct thread *td)
  654 {
  655 
  656         MAC_PERFORM(thread_userret, td);
  657 }
  658 
  659 struct label *
  660 mac_thread_get_uthreadlabel(struct uthread *uthread)
  661 {
  662 
  663         return (uthread->uu_label);
  664 }
  665 
  666 struct label *
  667 mac_thread_get_threadlabel(struct thread *thread)
  668 {
  669         struct uthread *uthread = get_bsdthread_info(thread);
  670 
  671         return (mac_thread_get_uthreadlabel(uthread));
  672 }

Cache object: 59748ea964fe9467dbf13dab62d80563


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.