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

Cache object: 36f064d2509626b75e4e2d2736758b50


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