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/mac_framework.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) 1999-2002, 2006, 2009 Robert N. M. Watson
    3  * Copyright (c) 2001 Ilmar S. Habibulin
    4  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
    5  * Copyright (c) 2005-2006 SPARTA, Inc.
    6  * Copyright (c) 2008-2009 Apple Inc.
    7  * All rights reserved.
    8  *
    9  * This software was developed by Robert Watson and Ilmar Habibulin for the
   10  * TrustedBSD Project.
   11  *
   12  * This software was developed for the FreeBSD Project in part by Network
   13  * Associates Laboratories, the Security Research Division of Network
   14  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
   15  * as part of the DARPA CHATS research program.
   16  *
   17  * This software was enhanced by SPARTA ISSO under SPAWAR contract 
   18  * N66001-04-C-6019 ("SEFOS").
   19  *
   20  * This software was developed at the University of Cambridge Computer
   21  * Laboratory with support from a grant from Google, Inc.
   22  *
   23  * Redistribution and use in source and binary forms, with or without
   24  * modification, are permitted provided that the following conditions
   25  * are met:
   26  * 1. Redistributions of source code must retain the above copyright
   27  *    notice, this list of conditions and the following disclaimer.
   28  * 2. Redistributions in binary form must reproduce the above copyright
   29  *    notice, this list of conditions and the following disclaimer in the
   30  *    documentation and/or other materials provided with the distribution.
   31  *
   32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   42  * SUCH DAMAGE.
   43  */
   44 
   45 /*-
   46  * Framework for extensible kernel access control.  This file contains core
   47  * kernel infrastructure for the TrustedBSD MAC Framework, including policy
   48  * registration, versioning, locking, error composition operator, and system
   49  * calls.
   50  *
   51  * The MAC Framework implements three programming interfaces:
   52  *
   53  * - The kernel MAC interface, defined in mac_framework.h, and invoked
   54  *   throughout the kernel to request security decisions, notify of security
   55  *   related events, etc.
   56  *
   57  * - The MAC policy module interface, defined in mac_policy.h, which is
   58  *   implemented by MAC policy modules and invoked by the MAC Framework to
   59  *   forward kernel security requests and notifications to policy modules.
   60  *
   61  * - The user MAC API, defined in mac.h, which allows user programs to query
   62  *   and set label state on objects.
   63  *
   64  * The majority of the MAC Framework implementation may be found in
   65  * src/sys/security/mac.  Sample policy modules may be found in
   66  * src/sys/security/mac_*.
   67  */
   68 
   69 #include "opt_kdtrace.h"
   70 #include "opt_mac.h"
   71 
   72 #include <sys/cdefs.h>
   73 __FBSDID("$FreeBSD: releng/10.1/sys/security/mac/mac_framework.c 270045 2014-08-16 13:11:59Z bz $");
   74 
   75 #include <sys/param.h>
   76 #include <sys/systm.h>
   77 #include <sys/condvar.h>
   78 #include <sys/kernel.h>
   79 #include <sys/lock.h>
   80 #include <sys/mac.h>
   81 #include <sys/module.h>
   82 #include <sys/rmlock.h>
   83 #include <sys/sdt.h>
   84 #include <sys/sx.h>
   85 #include <sys/sysctl.h>
   86 
   87 #include <security/mac/mac_framework.h>
   88 #include <security/mac/mac_internal.h>
   89 #include <security/mac/mac_policy.h>
   90 
   91 /*
   92  * DTrace SDT providers for MAC.
   93  */
   94 SDT_PROVIDER_DEFINE(mac);
   95 SDT_PROVIDER_DEFINE(mac_framework);
   96 
   97 SDT_PROBE_DEFINE2(mac, kernel, policy, modevent, "int",
   98     "struct mac_policy_conf *");
   99 SDT_PROBE_DEFINE1(mac, kernel, policy, register,
  100     "struct mac_policy_conf *");
  101 SDT_PROBE_DEFINE1(mac, kernel, policy, unregister,
  102     "struct mac_policy_conf *");
  103 
  104 /*
  105  * Root sysctl node for all MAC and MAC policy controls.
  106  */
  107 SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
  108     "TrustedBSD MAC policy controls");
  109 
  110 /*
  111  * Declare that the kernel provides MAC support, version 3 (FreeBSD 7.x).
  112  * This permits modules to refuse to be loaded if the necessary support isn't
  113  * present, even if it's pre-boot.
  114  */
  115 MODULE_VERSION(kernel_mac_support, MAC_VERSION);
  116 
  117 static unsigned int     mac_version = MAC_VERSION;
  118 SYSCTL_UINT(_security_mac, OID_AUTO, version, CTLFLAG_RD, &mac_version, 0,
  119     "");
  120 
  121 /*
  122  * Labels consist of a indexed set of "slots", which are allocated policies
  123  * as required.  The MAC Framework maintains a bitmask of slots allocated so
  124  * far to prevent reuse.  Slots cannot be reused, as the MAC Framework
  125  * guarantees that newly allocated slots in labels will be NULL unless
  126  * otherwise initialized, and because we do not have a mechanism to garbage
  127  * collect slots on policy unload.  As labeled policies tend to be statically
  128  * loaded during boot, and not frequently unloaded and reloaded, this is not
  129  * generally an issue.
  130  */
  131 #if MAC_MAX_SLOTS > 32
  132 #error "MAC_MAX_SLOTS too large"
  133 #endif
  134 
  135 static unsigned int mac_max_slots = MAC_MAX_SLOTS;
  136 static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1;
  137 SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, &mac_max_slots,
  138     0, "");
  139 
  140 /*
  141  * Has the kernel started generating labeled objects yet?  All read/write
  142  * access to this variable is serialized during the boot process.  Following
  143  * the end of serialization, we don't update this flag; no locking.
  144  */
  145 static int      mac_late = 0;
  146 
  147 /*
  148  * Each policy declares a mask of object types requiring labels to be
  149  * allocated for them.  For convenience, we combine and cache the bitwise or
  150  * of the per-policy object flags to track whether we will allocate a label
  151  * for an object type at run-time.
  152  */
  153 uint64_t        mac_labeled;
  154 SYSCTL_UQUAD(_security_mac, OID_AUTO, labeled, CTLFLAG_RD, &mac_labeled, 0,
  155     "Mask of object types being labeled");
  156 
  157 MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
  158 
  159 /*
  160  * MAC policy modules are placed in one of two lists: mac_static_policy_list,
  161  * for policies that are loaded early and cannot be unloaded, and
  162  * mac_policy_list, which holds policies either loaded later in the boot
  163  * cycle or that may be unloaded.  The static policy list does not require
  164  * locks to iterate over, but the dynamic list requires synchronization.
  165  * Support for dynamic policy loading can be compiled out using the
  166  * MAC_STATIC kernel option.
  167  *
  168  * The dynamic policy list is protected by two locks: modifying the list
  169  * requires both locks to be held exclusively.  One of the locks,
  170  * mac_policy_rm, is acquired over policy entry points that will never sleep;
  171  * the other, mac_policy_sx, is acquire over policy entry points that may
  172  * sleep.  The former category will be used when kernel locks may be held
  173  * over calls to the MAC Framework, during network processing in ithreads,
  174  * etc.  The latter will tend to involve potentially blocking memory
  175  * allocations, extended attribute I/O, etc.
  176  */
  177 #ifndef MAC_STATIC
  178 static struct rmlock mac_policy_rm;     /* Non-sleeping entry points. */
  179 static struct sx mac_policy_sx;         /* Sleeping entry points. */
  180 #endif
  181 
  182 struct mac_policy_list_head mac_policy_list;
  183 struct mac_policy_list_head mac_static_policy_list;
  184 u_int mac_policy_count;                 /* Registered policy count. */
  185 
  186 static void     mac_policy_xlock(void);
  187 static void     mac_policy_xlock_assert(void);
  188 static void     mac_policy_xunlock(void);
  189 
  190 void
  191 mac_policy_slock_nosleep(struct rm_priotracker *tracker)
  192 {
  193 
  194 #ifndef MAC_STATIC
  195         if (!mac_late)
  196                 return;
  197 
  198         rm_rlock(&mac_policy_rm, tracker);
  199 #endif
  200 }
  201 
  202 void
  203 mac_policy_slock_sleep(void)
  204 {
  205 
  206         WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
  207             "mac_policy_slock_sleep");
  208 
  209 #ifndef MAC_STATIC
  210         if (!mac_late)
  211                 return;
  212 
  213         sx_slock(&mac_policy_sx);
  214 #endif
  215 }
  216 
  217 void
  218 mac_policy_sunlock_nosleep(struct rm_priotracker *tracker)
  219 {
  220 
  221 #ifndef MAC_STATIC
  222         if (!mac_late)
  223                 return;
  224 
  225         rm_runlock(&mac_policy_rm, tracker);
  226 #endif
  227 }
  228 
  229 void
  230 mac_policy_sunlock_sleep(void)
  231 {
  232 
  233 #ifndef MAC_STATIC
  234         if (!mac_late)
  235                 return;
  236 
  237         sx_sunlock(&mac_policy_sx);
  238 #endif
  239 }
  240 
  241 static void
  242 mac_policy_xlock(void)
  243 {
  244 
  245         WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
  246             "mac_policy_xlock()");
  247 
  248 #ifndef MAC_STATIC
  249         if (!mac_late)
  250                 return;
  251 
  252         sx_xlock(&mac_policy_sx);
  253         rm_wlock(&mac_policy_rm);
  254 #endif
  255 }
  256 
  257 static void
  258 mac_policy_xunlock(void)
  259 {
  260 
  261 #ifndef MAC_STATIC
  262         if (!mac_late)
  263                 return;
  264 
  265         rm_wunlock(&mac_policy_rm);
  266         sx_xunlock(&mac_policy_sx);
  267 #endif
  268 }
  269 
  270 static void
  271 mac_policy_xlock_assert(void)
  272 {
  273 
  274 #ifndef MAC_STATIC
  275         if (!mac_late)
  276                 return;
  277 
  278         /* XXXRW: rm_assert(&mac_policy_rm, RA_WLOCKED); */
  279         sx_assert(&mac_policy_sx, SA_XLOCKED);
  280 #endif
  281 }
  282 
  283 /*
  284  * Initialize the MAC subsystem, including appropriate SMP locks.
  285  */
  286 static void
  287 mac_init(void)
  288 {
  289 
  290         LIST_INIT(&mac_static_policy_list);
  291         LIST_INIT(&mac_policy_list);
  292         mac_labelzone_init();
  293 
  294 #ifndef MAC_STATIC
  295         rm_init_flags(&mac_policy_rm, "mac_policy_rm", RM_NOWITNESS |
  296             RM_RECURSE);
  297         sx_init_flags(&mac_policy_sx, "mac_policy_sx", SX_NOWITNESS);
  298 #endif
  299 }
  300 
  301 /*
  302  * For the purposes of modules that want to know if they were loaded "early",
  303  * set the mac_late flag once we've processed modules either linked into the
  304  * kernel, or loaded before the kernel startup.
  305  */
  306 static void
  307 mac_late_init(void)
  308 {
  309 
  310         mac_late = 1;
  311 }
  312 
  313 /*
  314  * Given a policy, derive from its set of non-NULL label init methods what
  315  * object types the policy is interested in.
  316  */
  317 static uint64_t
  318 mac_policy_getlabeled(struct mac_policy_conf *mpc)
  319 {
  320         uint64_t labeled;
  321 
  322 #define MPC_FLAG(method, flag)                                  \
  323         if (mpc->mpc_ops->mpo_ ## method != NULL)                       \
  324                 labeled |= (flag);                                      \
  325 
  326         labeled = 0;
  327         MPC_FLAG(cred_init_label, MPC_OBJECT_CRED);
  328         MPC_FLAG(proc_init_label, MPC_OBJECT_PROC);
  329         MPC_FLAG(vnode_init_label, MPC_OBJECT_VNODE);
  330         MPC_FLAG(inpcb_init_label, MPC_OBJECT_INPCB);
  331         MPC_FLAG(socket_init_label, MPC_OBJECT_SOCKET);
  332         MPC_FLAG(devfs_init_label, MPC_OBJECT_DEVFS);
  333         MPC_FLAG(mbuf_init_label, MPC_OBJECT_MBUF);
  334         MPC_FLAG(ipq_init_label, MPC_OBJECT_IPQ);
  335         MPC_FLAG(ifnet_init_label, MPC_OBJECT_IFNET);
  336         MPC_FLAG(bpfdesc_init_label, MPC_OBJECT_BPFDESC);
  337         MPC_FLAG(pipe_init_label, MPC_OBJECT_PIPE);
  338         MPC_FLAG(mount_init_label, MPC_OBJECT_MOUNT);
  339         MPC_FLAG(posixsem_init_label, MPC_OBJECT_POSIXSEM);
  340         MPC_FLAG(posixshm_init_label, MPC_OBJECT_POSIXSHM);
  341         MPC_FLAG(sysvmsg_init_label, MPC_OBJECT_SYSVMSG);
  342         MPC_FLAG(sysvmsq_init_label, MPC_OBJECT_SYSVMSQ);
  343         MPC_FLAG(sysvsem_init_label, MPC_OBJECT_SYSVSEM);
  344         MPC_FLAG(sysvshm_init_label, MPC_OBJECT_SYSVSHM);
  345         MPC_FLAG(syncache_init_label, MPC_OBJECT_SYNCACHE);
  346         MPC_FLAG(ip6q_init_label, MPC_OBJECT_IP6Q);
  347 
  348 #undef MPC_FLAG
  349         return (labeled);
  350 }
  351 
  352 /*
  353  * When policies are loaded or unloaded, walk the list of registered policies
  354  * and built mac_labeled, a bitmask representing the union of all objects
  355  * requiring labels across all policies.
  356  */
  357 static void
  358 mac_policy_update(void)
  359 {
  360         struct mac_policy_conf *mpc;
  361 
  362         mac_policy_xlock_assert();
  363 
  364         mac_labeled = 0;
  365         mac_policy_count = 0;
  366         LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
  367                 mac_labeled |= mac_policy_getlabeled(mpc);
  368                 mac_policy_count++;
  369         }
  370         LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
  371                 mac_labeled |= mac_policy_getlabeled(mpc);
  372                 mac_policy_count++;
  373         }
  374 }
  375 
  376 static int
  377 mac_policy_register(struct mac_policy_conf *mpc)
  378 {
  379         struct mac_policy_conf *tmpc;
  380         int error, slot, static_entry;
  381 
  382         error = 0;
  383 
  384         /*
  385          * We don't technically need exclusive access while !mac_late, but
  386          * hold it for assertion consistency.
  387          */
  388         mac_policy_xlock();
  389 
  390         /*
  391          * If the module can potentially be unloaded, or we're loading late,
  392          * we have to stick it in the non-static list and pay an extra
  393          * performance overhead.  Otherwise, we can pay a light locking cost
  394          * and stick it in the static list.
  395          */
  396         static_entry = (!mac_late &&
  397             !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK));
  398 
  399         if (static_entry) {
  400                 LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
  401                         if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
  402                                 error = EEXIST;
  403                                 goto out;
  404                         }
  405                 }
  406         } else {
  407                 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
  408                         if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
  409                                 error = EEXIST;
  410                                 goto out;
  411                         }
  412                 }
  413         }
  414         if (mpc->mpc_field_off != NULL) {
  415                 slot = ffs(mac_slot_offsets_free);
  416                 if (slot == 0) {
  417                         error = ENOMEM;
  418                         goto out;
  419                 }
  420                 slot--;
  421                 mac_slot_offsets_free &= ~(1 << slot);
  422                 *mpc->mpc_field_off = slot;
  423         }
  424         mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
  425 
  426         /*
  427          * If we're loading a MAC module after the framework has initialized,
  428          * it has to go into the dynamic list.  If we're loading it before
  429          * we've finished initializing, it can go into the static list with
  430          * weaker locker requirements.
  431          */
  432         if (static_entry)
  433                 LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list);
  434         else
  435                 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
  436 
  437         /*
  438          * Per-policy initialization.  Currently, this takes place under the
  439          * exclusive lock, so policies must not sleep in their init method.
  440          * In the future, we may want to separate "init" from "start", with
  441          * "init" occuring without the lock held.  Likewise, on tear-down,
  442          * breaking out "stop" from "destroy".
  443          */
  444         if (mpc->mpc_ops->mpo_init != NULL)
  445                 (*(mpc->mpc_ops->mpo_init))(mpc);
  446         mac_policy_update();
  447 
  448         SDT_PROBE(mac, kernel, policy, register, mpc, 0, 0, 0, 0);
  449         printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
  450             mpc->mpc_name);
  451 
  452 out:
  453         mac_policy_xunlock();
  454         return (error);
  455 }
  456 
  457 static int
  458 mac_policy_unregister(struct mac_policy_conf *mpc)
  459 {
  460 
  461         /*
  462          * If we fail the load, we may get a request to unload.  Check to see
  463          * if we did the run-time registration, and if not, silently succeed.
  464          */
  465         mac_policy_xlock();
  466         if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
  467                 mac_policy_xunlock();
  468                 return (0);
  469         }
  470 #if 0
  471         /*
  472          * Don't allow unloading modules with private data.
  473          */
  474         if (mpc->mpc_field_off != NULL) {
  475                 mac_policy_xunlock();
  476                 return (EBUSY);
  477         }
  478 #endif
  479         /*
  480          * Only allow the unload to proceed if the module is unloadable by
  481          * its own definition.
  482          */
  483         if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
  484                 mac_policy_xunlock();
  485                 return (EBUSY);
  486         }
  487         if (mpc->mpc_ops->mpo_destroy != NULL)
  488                 (*(mpc->mpc_ops->mpo_destroy))(mpc);
  489 
  490         LIST_REMOVE(mpc, mpc_list);
  491         mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
  492         mac_policy_update();
  493         mac_policy_xunlock();
  494 
  495         SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0);
  496         printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
  497             mpc->mpc_name);
  498 
  499         return (0);
  500 }
  501 
  502 /*
  503  * Allow MAC policy modules to register during boot, etc.
  504  */
  505 int
  506 mac_policy_modevent(module_t mod, int type, void *data)
  507 {
  508         struct mac_policy_conf *mpc;
  509         int error;
  510 
  511         error = 0;
  512         mpc = (struct mac_policy_conf *) data;
  513 
  514 #ifdef MAC_STATIC
  515         if (mac_late) {
  516                 printf("mac_policy_modevent: MAC_STATIC and late\n");
  517                 return (EBUSY);
  518         }
  519 #endif
  520 
  521         SDT_PROBE(mac, kernel, policy, modevent, type, mpc, 0, 0, 0);
  522         switch (type) {
  523         case MOD_LOAD:
  524                 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
  525                     mac_late) {
  526                         printf("mac_policy_modevent: can't load %s policy "
  527                             "after booting\n", mpc->mpc_name);
  528                         error = EBUSY;
  529                         break;
  530                 }
  531                 error = mac_policy_register(mpc);
  532                 break;
  533         case MOD_UNLOAD:
  534                 /* Don't unregister the module if it was never registered. */
  535                 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
  536                     != 0)
  537                         error = mac_policy_unregister(mpc);
  538                 else
  539                         error = 0;
  540                 break;
  541         default:
  542                 error = EOPNOTSUPP;
  543                 break;
  544         }
  545 
  546         return (error);
  547 }
  548 
  549 /*
  550  * Define an error value precedence, and given two arguments, selects the
  551  * value with the higher precedence.
  552  */
  553 int
  554 mac_error_select(int error1, int error2)
  555 {
  556 
  557         /* Certain decision-making errors take top priority. */
  558         if (error1 == EDEADLK || error2 == EDEADLK)
  559                 return (EDEADLK);
  560 
  561         /* Invalid arguments should be reported where possible. */
  562         if (error1 == EINVAL || error2 == EINVAL)
  563                 return (EINVAL);
  564 
  565         /* Precedence goes to "visibility", with both process and file. */
  566         if (error1 == ESRCH || error2 == ESRCH)
  567                 return (ESRCH);
  568 
  569         if (error1 == ENOENT || error2 == ENOENT)
  570                 return (ENOENT);
  571 
  572         /* Precedence goes to DAC/MAC protections. */
  573         if (error1 == EACCES || error2 == EACCES)
  574                 return (EACCES);
  575 
  576         /* Precedence goes to privilege. */
  577         if (error1 == EPERM || error2 == EPERM)
  578                 return (EPERM);
  579 
  580         /* Precedence goes to error over success; otherwise, arbitrary. */
  581         if (error1 != 0)
  582                 return (error1);
  583         return (error2);
  584 }
  585 
  586 int
  587 mac_check_structmac_consistent(struct mac *mac)
  588 {
  589 
  590         if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
  591                 return (EINVAL);
  592 
  593         return (0);
  594 }
  595 
  596 SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
  597 SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);

Cache object: 47526bdd058c1439ed4cdca1545856e2


[ 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.