<!--
    Copyright (c) 2002, 2003 Networks Associates Technology, Inc.
    All rights reserved.
    
    This software was developed for the FreeBSD Project by
    Chris Costello at Safeport Network Services and Network Associates Labs,
    the Security Research Division of Network Associates, Inc. under
    DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
    DARPA CHATS research program.
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:
    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    
    THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
    
    $FreeBSD$
-->

<chapter id="mac">
  <chapterinfo>
    <authorgroup>
      <author>
        <firstname>Chris</firstname>
        <surname>Costello</surname>
        
        <affiliation>
          <orgname>TrustedBSD Project</orgname>
          <address><email>chris@FreeBSD.org</email></address>
        </affiliation>
      </author>
      
      <author>
        <firstname>Robert</firstname>
        <surname>Watson</surname>
        
        <affiliation>
          <orgname>TrustedBSD Project</orgname>
          <address><email>rwatson@FreeBSD.org</email></address>
        </affiliation>
      </author>
    </authorgroup>
  </chapterinfo>
  
  <title>The TrustedBSD MAC Framework</title>

  <sect1 id="mac-copyright">
    <title>MAC Documentation Copyright</title>

    <para>This documentation was developed for the FreeBSD Project by
      Chris Costello at Safeport Network Services and Network
      Associates Laboratories, the Security Research Division of
      Network Associates, Inc.  under DARPA/SPAWAR contract
      N66001-01-C-8035 (<quote>CBOSS</quote>), as part of the DARPA
      CHATS research program.</para>

    <para>Redistribution and use in source (SGML DocBook) and
      'compiled' forms (SGML, HTML, PDF, PostScript, RTF and so forth)
      with or without modification, are permitted provided that the
      following conditions are met:</para>

    <orderedlist>
      <listitem>
        <para>Redistributions of source code (SGML DocBook) must
          retain the above copyright notice, this list of conditions
          and the following disclaimer as the first lines of this file
          unmodified.</para>
      </listitem>

      <listitem>
        <para>Redistributions in compiled form (transformed to other
          DTDs, converted to PDF, PostScript, RTF and other formats)
          must reproduce the above copyright notice, this list of
          conditions and the following disclaimer in the documentation
          and/or other materials provided with the
          distribution.</para>
      </listitem>
    </orderedlist>

    <important>
      <para>THIS DOCUMENTATION IS PROVIDED BY THE NETWORKS ASSOCIATES
        TECHNOLOGY, INC "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
        INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
        MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL NETWORKS ASSOCIATES TECHNOLOGY,
        INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
        OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN
        IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</para>
    </important>
  </sect1>
  
  <sect1 id="mac-synopsis">
    <title>Synopsis</title>
    
    <para>FreeBSD includes experimental support for several
      mandatory access control policies, as well as a framework
      for kernel security extensibility, the TrustedBSD MAC
      Framework.  The MAC Framework provides a pluggable access
      control framework, permitting new security policies to
      be easily linked into the kernel, loaded at boot, or loaded
      dynamically at run-time.  The framework provides a variety
      of features to make it easier to implement new policies,
      including the ability to easily tag security labels (such as
      confidentiality information) onto system objects.</para>

    <para>This chapter introduces the MAC policy framework and
      provides documentation for a sample MAC policy module.</para>
  </sect1>
  
  
  <sect1 id="mac-introduction">
    <title>Introduction</title>
    
    <para>The TrustedBSD MAC framework provides a mechanism to allow
      the compile-time or run-time extension of the kernel access
      control model.  New system policies may be implemented as
      kernel modules and linked to the kernel; if multiple policy
      modules are present, their results will be composed.  The
      MAC Framework provides a variety of access control infrastructure
      services to assist policy writers, including support for
      transient and persistent policy-agnostic object security
      labels.  This support is currently considered experimental.</para>
  </sect1>

  <sect1 id="mac-background">
    <title>Policy Background</title>

    <para>Mandatory Access Control (MAC), refers to a set of
      access control policies that are mandatorily enforced on
      users by the operating system.  MAC policies may be contrasted
      with Discretionary Access Control (DAC) protections, by which
      non-administrative users may (at their discretion) protect
      objects.  In traditional UNIX systems, DAC protections include
      file permissions and access control lists; MAC protections include
      process controls preventing inter-user debugging and firewalls.
      A variety of MAC policies have been formulated by operating system
      designers and security researches, including the Multi-Level
      Security (MLS) confidentiality policy, the Biba integrity policy,
      Role-Based Access Control (RBAC), and Type Enforcement (TE).  Each
      model bases decisions on a variety of factors, including user
      identity, role, and security clearance, as well as security labels
      on objects representing concepts such as data sensitivity and
      integrity.</para>

    <para>The TrustedBSD MAC Framework is capable of supporting policy
      modules that implement all of these policies, as well as a broad
      class of system hardening policies.  In addition, despite the
      name, the MAC Framework can also be used to implement purely
      discretionary policies, as policy modules are given substantial
      flexibility in how they authorize protections.</para>
  </sect1>
  
  <sect1 id="mac-framework-kernel-arch">
    <title>MAC Framework Kernel Architecture</title>
    
    <para>The TrustedBSD MAC Framework permits kernel modules to
      extend the operating system security policy, as well as
      providing infrastructure functionality required by many
      access control modules.  If multiple policies are
      simultaneously loaded, the MAC Framework will usefully (for
      some definition of useful) compose the results of the
      policies.</para>

    <sect2 id="mac-framework-kernel-arch-elements">
      <title>Kernel Elements</title>

      <para>The MAC Framework contains a number of kernel elements:</para>

      <itemizedlist>
	<listitem><para>Framework management interfaces</para></listitem>
	<listitem><para>Concurrency and synchronization 
	  primitives.</para></listitem>
	<listitem><para>Policy registration</para></listitem>
	<listitem><para>Extensible security label for kernel
	  objects</para></listitem>
	<listitem><para>Policy entry point composition
	  operators</para></listitem>
	<listitem><para>Label management primitives</para></listitem>
	<listitem><para>Entry point API invoked by kernel
	  services</para></listitem>
	<listitem><para>Entry point API to policy modules</para></listitem>
	<listitem><para>Entry points implementations (policy life cycle,
	  object life cycle/label management, access control
	  checks).</para></listitem>
	<listitem><para>Policy-agnostic label-management system
	  calls</para></listitem>
	<listitem><para><function>mac_syscall()</function> multiplex
	  system call</para></listitem>
	<listitem><para>Various security policies implemented as MAC
	  policy modules</para></listitem>
      </itemizedlist>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-management">
      <title>Management Interfaces</title>

      <para>The TrustedBSD MAC Framework may be directly managed using
	sysctls, loader tunables, and system calls.</para>

      <para>In most cases, sysctls and loader tunables modify the same
	parameters, and control behavior such as enforcement of
	protections relating to various kernel subsystems.  In addition,
	if MAC debugging support is compiled into the kernel, a variety
	of counters will be maintained tracking label allocation.  In
	most cases, it is advised that per-subsystem enforcement
	controls not be used to control policy behavior in production
	environments, as they broadly impact the operation of all
	active policies.  Instead, per-policy controls should be
	preferred to ensure proper policy operation.</para>

      <para>Loading and unloading of policy modules is performed
	using the system module management system calls and other
	system interfaces, including loader variables.</para>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-synchronization">
      <title>Concurrency and Synchronization</title>

      <para>As the set of active policies may change at run-time,
	and the invocation of entry points is non-atomic,
	synchronization is required to prevent unloading or
	loading of new policies while an entry point invocation
	is progress, freezing the list of policies for the
	duration.  This is accomplished by means of a Framework
	busy count.  Whenever an entry point is entered, the
	busy count is incremented; whenever it is exited, the
	busy count is decremented.  While the busy count is
	elevated, policy list changes are not permitted, and
	threads attempting to modify the policy list will sleep
	until the list is not busy.  The busy count is protected
	by a mutex, and a condition variable is used to wake up
	sleepers waiting on policy list modifications.</para>

      <para>Various optimizations are used to reduce the overhead
	of the busy count, including avoiding the full cost of
	incrementing and decrementing if the list is empty or
	contains only static entries (policies that are loaded
	before the system starts, and cannot be unloaded).</para>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-registration">
      <title>Policy Registration</title>

      <para>The MAC Framework maintains two lists of active
	policies: a static list, and a dynamic list.  The lists
	differ only with regards to their locking semantics: an
	elevated reference count is not required to make use of
	the static list.  When kernel modules containing MAC
	Framework policies are loaded, the policy module will
	use <literal>SYSINIT</literal> to invoke a registration
	function; when a policy module is unloaded,
	<literal>SYSINIT</literal> will likewise invoke a
	de-registration function.  Registration may fail if a
	policy module is loaded more than once, if insufficient
	resources are available for the registration (for
	example, the policy might require labeling and
	insufficient labeling state might be available), or
	other policy prerequisites might not be met (some
	policies may only be loaded prior to boot).  Likewise,
	de-registration may fail if a policy refuses an
	unload.</para>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-entrypoints">
      <title>Entry Points</title>

      <para>Kernel services interact with the MAC Framework in two ways:
	they invoke a series of APIs to notify the framework of relevant
	events, and they a policy-agnostic label structure in
	security-relevant objects.  This label structure is maintained by
	the MAC Framework via label management entry points, and permits
	the Framework to offer a labeling service to policy modules
	through relatively non-invasive changes to the kernel subsystem
	maintaining the object.  For example, label structures have been
	added to processes, process credentials, sockets, pipes, vnodes,
	Mbufs, network interfaces, IP reassembly queues, and a variety
	of other security-relevant structures.  Kernel services also
	invoke the MAC Framework when they perform important security
	decisions, permitting policy modules to augment those decisions
	based on their own criteria (possibly including data stored in
	security labels).</para>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-composition">
      <title>Policy Composition</title>

      <para>When more than one policy module is loaded into the kernel
	at a time, the results of the policy modules will be composed
	by the framework using a composition operator.  This operator
	is currently hard-coded, and requires that all active policies
	must approve a request for it to occur.  As policies may
	return a variety of error conditions (success, access denied,
	object doesn't exist, ...), a precedence operator selects the
	resulting error from the set of errors returned by policies.
	While it is not guaranteed that the resulting composition will
	be useful or secure, we've found that it is for many useful
	selections of policies.</para>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-labels">
      <title>Labeling Support</title>

      <para>As many interesting access control extensions rely on
	security labels on objects, the MAC Framework provides a set
	of policy-agnostic label management system calls covering
	a variety of user-exposed objects.  Common label types
	include partition identifiers, sensitivity labels, integrity
	labels, compartments, domains, roles, and types.  Policy
	modules participate in the internalization and externalization
	of string-based labels provides by user applications, and can
	expose multiple label elements to applications if desired.</para>

      <para>In-memory labels are stored in <structname>struct
	label</structname>, which consists of a fixed-length array
	of unions, each holding a <literal>void *</literal> pointer
	and a <literal>long</literal>.  Policies registering for
	label storage will be assigned a "slot" identifier, which
	may be used to dereference the label storage.  The semantics
	of the storage are left entirely up to the policy module:
	modules are provided with a variety of entry points
	associated with the kernel object life cycle, including
	initialization, association/creation, and destruction.  Using
	these interfaces, it is possible to implement reference
	counting and other storage mechanisms.  Direct access to
	the kernel object is generally not required by policy
	modules to retrieve a label, as the MAC Framework generally
	passes both a pointer to the object and a direct pointer
	to the object's label into entry points.</para>

      <para>Initialization entry points frequently include a blocking
	disposition flag indicating whether or not an initialization
	is permitted to block; if blocking is not permitted, a failure
	may be returned to cancel allocation of the label.  This may
	occur, for example, in the network stack during interrupt
	handling, where blocking is not permitted.  Due to the
	performance cost of maintaining labels on in-flight network
	packets (Mbufs), policies must specifically declare a
	requirement that Mbuf labels be allocated.  Dynamically
	loaded policies making use of labels must be able to handle
	the case where their init function has not been called on
	an object, as objects may already exist when the policy is
	loaded.</para>

      <para>In the case of file system labels, special support is
	provided for the persistent storage of security labels in
	extended attributes.  Where available, EA transactions
	are used to permit consistent compound updates of
	security labels on vnodes.</para>

      <note><para>Currently, if a labeled policy permits dynamic
	unloading, its state slot cannot be reclaimed.</para></note>
    </sect2>

    <sect2 id="mac-framework-kernel-arch-syscalls">
      <title>System Calls</title>

      <para>The MAC Framework implements a number of system calls:
	most of these calls support the policy-agnostic label
	retrieval and manipulation APIs exposed to user
	applications.</para>

      <para>The label management calls accept a label description
	structure, <structname>struct mac</structname>, which
	contains a series of MAC label elements.  Each element
	contains a character string name, and character string
	value.  Each policy will be given the chance to claim a
	particular element name, permitting policies to expose
	multiple independent elements if desired.  Policy modules
	perform the internalization and externalization between
	kernel labels and user-provided labels via entry points,
	permitting a variety of semantics.  Label management system
	calls are generally wrapped by user library functions to
	perform memory allocation and error handling.</para>

      <para>In addition, <function>mac_syscall()</function>
	permits policy modules to create new system calls without
	allocating system calls.  <function>mac_execve()</function>
	permits an atomic process credential label change when
	executing a new image.</para>
    </sect2>
  </sect1>

  <sect1 id="mac-policy-architecture">
    <title>MAC Policy Architecture</title>

    <para>Security policies are either linked directly into the kernel,
      or compiled into loadable kernel modules that may be loaded at
      boot, or dynamically using the module loading system calls at
      runtime.  Policy modules interact with the system through a
      set of declared entry points, providing access to a stream of
      system events and permitting the policy to influence access
      control decisions.  Each policy contains a number of elements:</para>

    <itemizedlist>
      <listitem><para>Optional configuration parameters for
	policy.</para></listitem>
      <listitem><para>Centralized implementation of the policy
	logic and parameters.</para></listitem>
      <listitem><para>Optional implementation of policy life cycle
	events, such as initialization and destruction.</para></listitem>
      <listitem><para>Optional support for initializing, maintaining, and
	destroying labels on selected kernel objects.</para></listitem>
      <listitem><para>Optional support for user process inspection and
	modification of labels on selected objects.</para></listitem>
      <listitem><para>Implementation of selected access control
	entry points that are of interest to the policy.</para></listitem>
      <listitem><para>Declaration of policy identity, module entry
	points, and policy properties.</para></listitem>
    </itemizedlist>

    <sect2 id="mac-policy-declaration">
      <title>Policy Declaration</title>
    
      <para>Modules may be declared using the
	<function>MAC_POLICY_SET()</function> macro, which names the
	policy, provides a reference to the MAC entry point vector,
	provides load-time flags determining how the policy framework
	should handle the policy, and optionally requests the
	allocation of label state by the framework.</para>

    <programlisting>static struct mac_policy_ops mac_<replaceable>policy</replaceable>_ops =
{                                   
        .mpo_destroy = mac_<replaceable>policy</replaceable>_destroy,
        .mpo_init = mac_<replaceable>policy</replaceable>_init,
        .mpo_init_bpfdesc_label = mac_<replaceable>policy</replaceable>_init_bpfdesc_label,  
        .mpo_init_cred_label = mac_<replaceable>policy</replaceable>_init_label,
/* ... */
        .mpo_check_vnode_setutimes = mac_<replaceable>policy</replaceable>_check_vnode_setutimes,
        .mpo_check_vnode_stat = mac_<replaceable>policy</replaceable>_check_vnode_stat,
        .mpo_check_vnode_write = mac_<replaceable>policy</replaceable>_check_vnode_write,
};</programlisting>
      
      <para>The MAC policy entry point vector,
	<varname>mac_<replaceable>policy</replaceable>_ops</varname> in this example, associates
	functions defined in the module with specific entry points. A
	complete listing of available entry points and their
	prototypes may be found in the MAC entry point reference
	section.  Of specific interest during module registration are
	the <symbol>.mpo_destroy</symbol> and <symbol>.mpo_init</symbol>
	entry points. <symbol>.mpo_init</symbol> will be invoked once a
	policy is successfully registered with the module framework
	but prior to any other entry points becoming active. This
	permits the policy to perform any policy-specific allocation
	and initialization, such as initialization of any data or
	locks.  <symbol>.mpo_destroy</symbol> will be invoked when a
	policy module is unloaded to permit releasing of any allocated
	memory and destruction of locks.  Currently, these two entry
	points are invoked with the MAC policy list mutex held to
	prevent any other entry points from being invoked: this will
	be changed, but in the mean time, policies should be careful
	about what kernel primitives they invoke so as to avoid lock
	ordering or sleeping problems.</para>
      
      <para>The policy declaration's module name field exists so that
	the module may be uniquely identified for the purposes of
	module dependencies. An appropriate string should be selected.
	The full string name of the policy is displayed to the user
	via the kernel log during load and unload events, and also
	exported when providing status information to userland
	processes.</para>
    </sect2>

    <sect2 id="mac-policy-flags">
      <title>Policy Flags</title>
      
      <para>The policy declaration flags field permits the module to
	provide the framework with information about its capabilities at
	the time the module is loaded.  Currently, three flags are
	defined:</para>
      
      <variablelist>
	<varlistentry>
	  <term>MPC_LOADTIME_FLAG_UNLOADOK</term>

	  <listitem>
	    <para>This flag indicates that the policy module may be
	      unloaded.  If this flag is not provided, then the policy
	      framework will reject requests to unload the module.
	      This flag might be used by modules that allocate label
	      state and are unable to free that state at
	      runtime.</para>
	  </listitem>
	</varlistentry>
        
	<varlistentry>
	  <term>MPC_LOADTIME_FLAG_NOTLATE</term>
        
	  <listitem>
	    <para>This flag indicates that the policy module
	      must be loaded and initialized early in the boot
	      process.  If the flag is specified, attempts to register
	      the module following boot will be rejected.  The flag
	      may be used by policies that require pervasive labeling
	      of all system objects, and cannot handle objects that
	      have not been properly initialized by the policy.</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>MPC_LOADTIME_FLAG_LABELMBUFS</term>

	  <listitem>
	    <para>This flag indicates that the policy module requires
	      labeling of Mbufs, and that memory should always be
	      allocated for the storage of Mbuf labels.  By default,
	      the MAC Framework will not allocate label storage for
	      Mbufs unless at least one loaded policy has this flag
	      set.  This measurably improves network performance when
	      policies do not require Mbuf labeling.  A kernel option,
	      <literal>MAC_ALWAYS_LABEL_MBUF</literal>, exists to
	      force the MAC Framework to allocate Mbuf label storage
	      regardless of the setting of this flag, and may be
	      useful in some environments.</para>
	  </listitem>
	</varlistentry>
      </variablelist>
      
      <note><para>Policies using the
	<literal>MPC_LOADTIME_FLAG_LABELMBUFS</literal> without the
	<literal>MPC_LOADTIME_FLAG_NOTLATE</literal> flag set
	must be able to correctly handle <literal>NULL</literal>
	Mbuf label pointers passed into entry points.  This is necessary
	as in-flight Mbufs without label storage may persist after a
	policy enabling Mbuf labeling has been loaded.  If a policy
	is loaded before the network subsystem is active (i.e., the
	policy is not being loaded late), then all Mbufs are guaranteed
	to have label storage.</para></note>
    </sect2>

    <sect2 id="mac-policy-entry-points">
      <title>Policy Entry Points</title>
    
      <para>Four classes of entry points are offered to policies
	registered with the framework: entry points associated with
	the registration and management of policies, entry points
	denoting initialization, creation, destruction, and other life
	cycle events for kernel objects, events associated with access
	control decisions that the policy module may influence, and
	calls associated with the management of labels on objects. In
	addition, a <function>mac_syscall()</function> entry point is
	provided so that policies may extend the kernel interface
	without registering new system calls.</para>
    
      <para>Policy module writers should be aware of the kernel
	locking strategy, as well as what object locks are available
	during which entry points. Writers should attempt to avoid
	deadlock scenarios by avoiding grabbing non-leaf locks inside
	of entry points, and also follow the locking protocol for
	object access and modification.  In particular, writers should
	be aware that while necessary locks to access objects and
	their labels are generally held, sufficient locks to modify an
	object or its label may not be present for all entry points.
	Locking information for arguments is documented in the MAC
	framework entry point document.</para>
    
      <para>Policy entry points will pass a reference to the object
	label along with the object itself.  This permits labeled
	policies to be unaware of the internals of the object yet
	still make decisions based on the label. The exception to this
	is the process credential, which is assumed to be understood
	by policies as a first class security object in the kernel.
	Policies that do not implement labels on kernel objects will
	be passed NULL pointers for label arguments to entry
	points.</para>
    </sect2>
  </sect1>

  <sect1 id="mac-entry-point-reference">
    <title>MAC Policy Entry Point Reference</title>
    
    <sect2 id="mac-mpo-general">
      <title>General-Purpose Module Entry Points</title>
      
      <sect3 id="mac-mpo-init">
        <title><function>&mac.mpo;_init</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init</function></funcdef>
            
            <paramdef>struct mac_policy_conf
              *<parameter>conf</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>conf</parameter></entry>
                <entry>MAC policy definition</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Policy load event.  The policy list mutex is held, so
          caution should be applied.</para>
      </sect3>
      
      <sect3 id="mpo-destroy">
        <title><function>&mac.mpo;_destroy</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy</function></funcdef>
            
            <paramdef>struct mac_policy_conf
              *<parameter>conf</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>conf</parameter></entry>
                <entry>MAC policy definition</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Policy load event.  The policy list mutex is held, so
          caution should be applied.</para>
      </sect3>

      <sect3 id="mac-mpo-syscall">
        <title><function>&mac.mpo;_syscall</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_syscall</function></funcdef>

            <paramdef>struct thread
              *<parameter>td</parameter></paramdef>
            <paramdef>int <parameter>call</parameter></paramdef>
            <paramdef>void *<parameter>arg</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>td</parameter></entry>
                <entry>Calling thread</entry>
              </row>

              <row>
                <entry><parameter>call</parameter></entry>
                <entry>Syscall number</entry>
              </row>

              <row>
                <entry><parameter>arg</parameter></entry>
                <entry>Pointer to syscall arguments</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>This entry point provides a policy-multiplexed system
          call so that policies may provide additional services to
          user processes without registering specific system calls.
          The policy name provided during registration is used to
          demux calls from userland, and the arguments will be
          forwarded to this entry point.  When implementing new
          services, security modules should be sure to invoke
          appropriate access control checks from the MAC framework as
          needed.  For example, if a policy implements an augmented
          signal functionality, it should call the necessary signal
          access control checks to invoke the MAC framework and other
          registered policies.</para>

        <note><para>Modules must currently perform the
            <function>copyin()</function> of the syscall data on their
            own.</para></note>
      </sect3>
      
      <sect3 id="mac-mpo-thread-userret">
        <title><function>&mac.mpo;_thread_userret</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_thread_userret</function></funcdef>

            <paramdef>struct thread
              *<parameter>td</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>td</parameter></entry>
                <entry>Returning thread</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <!-- XXX: Maybe rewrite this section. -->
        <para>This entry point permits policy modules to perform
          MAC-related events when a thread returns to user space.
          This is required for policies that have floating process
          labels, as it is not always possible to acquire the process
          lock at arbitrary points in the stack during system call
          processing; process labels might represent traditional
          authentication data, process history information, or other
          data.</para>
      </sect3>
    </sect2>

    <sect2 id="mac-label-ops">
      <title>Label Operations</title>

      <sect3 id="mac-mpo-init-bpfdesc">
        <title><function>&mac.mpo;_init_bpfdesc_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_bpfdesc_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to apply</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label on a newly instantiated bpfdesc (BPF
          descriptor)</para>
      </sect3>

      <sect3 id="mac-mpo-init-cred-label">
        <title><function>&mac.mpo;_init_cred_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_cred_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to initialize</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label for a newly instantiated
          user credential.</para>
      </sect3>

      <sect3 id="mac-mpo-init-devfsdirent">
        <title><function>&mac.mpo;_init_devfsdirent_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_devfsdirent_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to apply</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label on a newly instantiated devfs
          entry.</para>
      </sect3>

      <sect3 id="mac-mpo-init-ifnet">
        <title><function>&mac.mpo;_init_ifnet_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_ifnet_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to apply</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label on a newly instantiated network
          interface.</para>
      </sect3>
      
      <sect3 id="mac-mpo-init-ipq">
        <title><function>&mac.mpo;_init_ipq_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_ipq_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>flag</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to apply</entry>
              </row>

              <row>
                <entry><parameter>flag</parameter></entry>
                <entry>Blocking/non-blocking &man.malloc.9;; see
		  below</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label on a newly instantiated IP fragment
          reassembly queue.  The <parameter>flag</parameter> field may
	  be one of <symbol>M_WAITOK</symbol> and <symbol>M_NOWAIT</symbol>,
	  and should be employed to avoid performing a blocking
          &man.malloc.9; during this initialization call.  IP fragment
	  reassembly queue allocation frequently occurs in performance
	  sensitive environments, and the implementation should be careful
	  to avoid blocking or long-lived operations.  This entry point
          is permitted to fail resulting in the failure to allocate
          the IP fragment reassembly queue.</para>
      </sect3>

      <sect3 id="mac-mpo-init-mbuf">
        <title><function>&mac.mpo;_init_mbuf_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_mbuf_label</function></funcdef>
            
            <paramdef>int <parameter>flag</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>flag</parameter></entry>
                <entry>Blocking/non-blocking &man.malloc.9;; see
                  below</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label to initialize</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label on a newly instantiated mbuf packet
          header (<parameter>mbuf</parameter>).  The
          <parameter>flag</parameter> field may be one of
          <symbol>M_WAITOK</symbol> and <symbol>M_NOWAIT</symbol>, and
          should be employed to avoid performing a blocking
          &man.malloc.9; during this initialization call.  Mbuf
          allocation frequently occurs in performance sensitive
          environments, and the implementation should be careful to
          avoid blocking or long-lived operations.  This entry point
          is permitted to fail resulting in the failure to allocate
          the mbuf header.</para>
      </sect3>
      
      <sect3 id="mac-mpo-init-mount">
        <title><function>&mac.mpo;_init_mount_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_mount_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>mntlabel</parameter></paramdef>
            <paramdef>struct label
              *<parameter>fslabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <!-- XXX: Wording on label descriptions. -->
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>mntlabel</parameter></entry>
                <entry>Policy label to be initialized for the mount
                  itself</entry>
              </row>
              
              <row>
                <entry><parameter>fslabel</parameter></entry>
                <entry>Policy label to be initialized for the file
                  system</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the labels on a newly instantiated mount
          point.</para>
      </sect3>

      <sect3 id="mac-mpo-init-mount-fs-label">
        <title><function>&mac.mpo;_init_mount_fs_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_mount_fs_label</function></funcdef>

            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label to be initialized</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Initialize the label on a newly mounted file
          system.</para>
      </sect3>

      <sect3 id="mac-mpo-init-pipe-label">
        <title><function>&mac.mpo;_init_pipe_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_pipe_label</function></funcdef>

            <paramdef>struct
              label*<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label to be filled in</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Initialize a label for a newly instantiated pipe.</para>
      </sect3>
      
      <sect3 id="mac-mpo-init-socket">
        <title><function>&mac.mpo;_init_socket_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_socket_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>flag</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to initialize</entry>
              </row>
              
              <row>
                <entry><parameter>flag</parameter></entry>
                <entry>&man.malloc.9; flags</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize a label for a newly instantiated
          socket.</para>
      </sect3>

      <sect3 id="mac-mpo-init-socket-peer-label">
        <title><function>&mac.mpo;_init_socket_peer_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_socket_peer_label</function></funcdef>

            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>flag</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to initialize</entry>
              </row>

              <row>
                <entry><parameter>flag</parameter></entry>
                <entry>&man.malloc.9; flags</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Initialize the peer label for a newly instantiated
          socket.</para>
      </sect3>
      
      <sect3 id="mac-mpo-init-proc-label">
        <title><function>&mac.mpo;_init_proc_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_proc_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to initialize</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label for a newly instantiated
          process.</para>
      </sect3>


      <sect3 id="mac-mpo-init-vnode">
        <title><function>&mac.mpo;_init_vnode_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_init_vnode_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>New label to initialize</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Initialize the label on a newly instantiated vnode.</para>
      </sect3>
      <sect3 id="mac-mpo-destroy-bpfdesc">
        <title><function>&mac.mpo;_destroy_bpfdesc_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_bpfdesc_label</function></funcdef>

            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>bpfdesc label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Destroy the label on a BPF descriptor.  In this entry
          point a policy should free any internal storage associated
          with <parameter>label</parameter> so that it may be
          destroyed.</para>
      </sect3>
      
      <sect3 id="mac-mpo-destroy-cred">
        <title><function>&mac.mpo;_destroy_cred_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_cred_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the label on a credential.  In this entry point,
          a policy module should free any internal storage associated
          with <parameter>label</parameter> so that it may be
          destroyed.</para>
      </sect3>


      <sect3 id="mac-mpo-destroy-devfsdirent">
        <title><function>&mac.mpo;_destroy_devfsdirent_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_devfsdirent_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the label on a devfs entry.  In this entry
          point, a policy module should free any internal storage
          associated with <parameter>label</parameter> so that it may
          be destroyed.</para>
      </sect3>
      
      <sect3 id="mac-mpo-destroy-ifnet-label">
        <title><function>&mac.mpo;_destroy_ifnet_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_ifnet_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the label on a removed interface.  In this entry
          point, a policy module should free any internal storage
          associated with <parameter>label</parameter> so that it may
          be destroyed.</para>
      </sect3>
      
      <sect3 id="mac-mpo-destroy-ipq-label">
        <title><function>&mac.mpo;_destroy_ipq_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_ipq_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the label on an IP fragment queue.  In this
          entry point, a policy module should free any internal
          storage associated with <parameter>label</parameter> so that
          it may be destroyed.</para>
      </sect3>
      
      <sect3 id="mac-mpo-destroy-mbuf-label">
        <title><function>&mac.mpo;_destroy_mbuf_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_mbuf_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the label on an mbuf header.  In this entry
          point, a policy module should free any internal storage
          associated with <parameter>label</parameter> so that it may
          be destroyed.</para>
      </sect3>
      
      <sect3 id="mac-mpo-destroy-mount-label">
        <title><function>&mac.mpo;_destroy_mount_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_mount_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Mount point label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the labels on a mount point.  In this entry
          point, a policy module should free the internal storage
          associated with <parameter>mntlabel</parameter> so that they
          may be destroyed.</para>
      </sect3>

      <sect3 id="mac-mpo-destroy-mount">
        <title><function>&mac.mpo;_destroy_mount_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_mount_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>mntlabel</parameter></paramdef>
            <paramdef>struct label
              *<parameter>fslabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>mntlabel</parameter></entry>
                <entry>Mount point label being destroyed</entry>
              </row>
              
              <row>
                <entry><parameter>fslabel</parameter></entry>
                <entry>File system label being destroyed></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the labels on a mount point.  In this entry
          point, a policy module should free the internal storage
          associated with <parameter>mntlabel</parameter> and
          <parameter>fslabel</parameter> so that they may be
          destroyed.</para>
      </sect3>
      
      <sect3 id="mac-mpo-destroy-socket">
        <title><function>&mac.mpo;_destroy_socket_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_socket_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>

          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Socket label being destroyed</entry>
              </row>

            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Destroy the label on a socket.  In this entry point, a
          policy module should free any internal storage associated
          with <parameter>label</parameter> so that it may be
          destroyed.</para>
      </sect3>

      <sect3 id="mac-mpo-destroy-socket-peer-label">
        <title><function>&mac.mpo;_destroy_socket_peer_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_socket_peer_label</function></funcdef>

            <paramdef>struct label
              *<parameter>peerlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>peerlabel</parameter></entry>
                <entry>Socket peer label being destroyed</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Destroy the peer label on a socket.  In this entry
          point, a policy module should free any internal storage
          associated with <parameter>label</parameter> so that it may
          be destroyed.</para>
      </sect3>

      <sect3 id="mac-mpo-destroy-pipe-label">
        <title><function>&mac.mpo;_destroy_pipe_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_pipe_label</function></funcdef>

            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Pipe label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Destroy the label on a pipe.  In this entry point, a
          policy module should free any internal storage associated
          with <parameter>label</parameter> so that it may be
          destroyed.</para>
      </sect3>

      <sect3 id="mac-mpo-destroy-proc-label">
        <title><function>&mac.mpo;_destroy_proc_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_proc_label</function></funcdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Process label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Destroy the label on a process.  In this entry point, a
          policy module should free any internal storage associated
          with <parameter>label</parameter> so that it may be
          destroyed.</para>
      </sect3>

      <sect3 id="mac-mpo-destroy-vnode-label">
        <title><function>&mac.mpo;_destroy_vnode_label</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_destroy_vnode_label</function></funcdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Process label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Destroy the label on a vnode.  In this entry point, a
          policy module should free any internal storage associated
          with <parameter>label</parameter> so that it may be
          destroyed.</para>
      </sect3>

      <sect3 id="mac-mpo-copy-mbuf-label">
        <title><function>&mac.mpo;_copy_mbuf_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_copy_mbuf_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>src</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dest</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>src</parameter></entry>
                <entry>Source label</entry>
              </row>
              
              <row>
                <entry><parameter>dest</parameter></entry>
                <entry>Destination label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Copy the label information in
          <parameter>src</parameter> into
          <parameter>dest</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-copy-pipe-label">
        <title><function>&mac.mpo;_copy_pipe_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_copy_pipe_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>src</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dest</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>src</parameter></entry>
                <entry>Source label</entry>
              </row>
              
              <row>
                <entry><parameter>dest</parameter></entry>
                <entry>Destination label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Copy the label information in
          <parameter>src</parameter> into
          <parameter>dest</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-copy-vnode-label">
        <title><function>&mac.mpo;_copy_vnode_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_copy_vnode_label</function></funcdef>
            
            <paramdef>struct label
              *<parameter>src</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dest</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>src</parameter></entry>
                <entry>Source label</entry>
              </row>
              
              <row>
                <entry><parameter>dest</parameter></entry>
                <entry>Destination label</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Copy the label information in
          <parameter>src</parameter> into
          <parameter>dest</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-externalize-cred-label">
        <title><function>&mac.mpo;_externalize_cred_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_externalize_cred_label</function></funcdef>
            
            &mac.externalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.externalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.externalize.para;
      </sect3>

      <sect3 id="mac-mpo-externalize-ifnet-label">
        <title><function>&mac.mpo;_externalize_ifnet_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_externalize_ifnet_label</function></funcdef>
            
            &mac.externalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.externalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.externalize.para;
      </sect3>
      
      <sect3 id="mac-mpo-externalize-pipe-label">
        <title><function>&mac.mpo;_externalize_pipe_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_externalize_pipe_label</function></funcdef>
            
            &mac.externalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.externalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.externalize.para;
      </sect3>
      
      <sect3 id="mac-mpo-externalize-socket-label">
        <title><function>&mac.mpo;_externalize_socket_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_externalize_socket_label</function></funcdef>
            
            &mac.externalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.externalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.externalize.para;
      </sect3>
      
      <sect3 id="mac-mpo-externalize-socket-peer-label">
        <title><function>&mac.mpo;_externalize_socket_peer_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_externalize_socket_peer_label</function></funcdef>
            
            &mac.externalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.externalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.externalize.para;
      </sect3>
      
      <sect3 id="mac-mpo-externalize-vnode-label">
        <title><function>&mac.mpo;_externalize_vnode_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_externalize_vnode_label</function></funcdef>
            
            &mac.externalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.externalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.externalize.para;
      </sect3>    

      <sect3 id="mac-mpo-internalize-cred-label">
        <title><function>&mac.mpo;_internalize_cred_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_internalize_cred_label</function></funcdef>
            
            &mac.internalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.internalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.internalize.para;
      </sect3>

      <sect3 id="mac-mpo-internalize-ifnet-label">
        <title><function>&mac.mpo;_internalize_ifnet_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_internalize_ifnet_label</function></funcdef>
            
            &mac.internalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.internalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.internalize.para;
      </sect3>
      
      <sect3 id="mac-mpo-internalize-pipe-label">
        <title><function>&mac.mpo;_internalize_pipe_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_internalize_pipe_label</function></funcdef>
            
            &mac.internalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.internalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.internalize.para;
      </sect3>
      
      <sect3 id="mac-mpo-internalize-socket-label">
        <title><function>&mac.mpo;_internalize_socket_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_internalize_socket_label</function></funcdef>
            
            &mac.internalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.internalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.internalize.para;
      </sect3>

      <sect3 id="mac-mpo-internalize-vnode-label">
        <title><function>&mac.mpo;_internalize_vnode_label</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_internalize_vnode_label</function></funcdef>
            
            &mac.internalize.paramdefs;
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            &mac.internalize.tbody;
          </tgroup>
        </informaltable>
        
        &mac.internalize.para;
      </sect3>
    </sect2>
    
    <sect2 id="mac-label-events">
      <title>Label Events</title>
      
      <para>This class of entry points is used by the MAC framework to
        permit policies to maintain label information on kernel
        objects.  For each labeled kernel object of interest to a MAC
        policy, entry points may be registered for relevant life cycle
        events.  All objects implement initialization, creation, and
        destruction hooks.  Some objects will also implement
        relabeling, allowing user processes to change the labels on
        objects.  Some objects will also implement object-specific
        events, such as label events associated with IP reassembly.  A
        typical labeled object will have the following life cycle of
        entry points:</para>
      
      <programlisting>Label initialization          o
(object-specific wait)         \
Label creation                  o
                                 \
Relabel events,                   o--<--.
Various object-specific,          |     |
Access control events             ~-->--o
                                         \
Label destruction                         o</programlisting>
      
      <para>Label initialization permits policies to allocate memory
        and set initial values for labels without context for the use
        of the object.  The label slot allocated to a policy will be
        zeroed by default, so some policies may not need to perform
        initialization.</para>
      
      <para>Label creation occurs when the kernel structure is
        associated with an actual kernel object.  For example, Mbufs
        may be allocated and remain unused in a pool until they are
        required.  mbuf allocation causes label initialization on the
        mbuf to take place, but mbuf creation occurs when the mbuf is
        associated with a datagram.  Typically, context will be
        provided for a creation event, including the circumstances of
        the creation, and labels of other relevant objects in the
        creation process. For example, when an mbuf is created from a
        socket, the socket and its label will be presented to
        registered policies in addition to the new mbuf and its label.
        Memory allocation in creation events is discouraged, as it may
        occur in performance sensitive ports of the kernel; in
        addition, creation calls are not permitted to fail so a
        failure to allocate memory cannot be reported.</para>
      
      <para>Object specific events do not generally fall into the
        other broad classes of label events, but will generally
        provide an opportunity to modify or update the label on an
        object based on additional context.  For example, the label on
        an IP fragment reassembly queue may be updated during the
        <symbol>MAC_UPDATE_IPQ</symbol> entry point as a result of the
        acceptance of an additional mbuf to that queue.</para>
      
      <para>Access control events are discussed in detail in the
        following section.</para>
      
      <para>Label destruction permits policies to release storage or
        state associated with a label during its association with an
        object so that the kernel data structures supporting the
        object may be reused or released.</para>
      
      <para>In addition to labels associated with specific kernel
        objects, an additional class of labels exists: temporary
        labels.  These labels are used to store update information
        submitted by user processes. These labels are initialized and
        destroyed as with other label types, but the creation event is
        <symbol>MAC_INTERNALIZE</symbol>, which accepts a user label
        to be converted to an in-kernel representation.</para>
      
      <sect3 id="mac-fs-label-event-ops">
        <title>File System Object Labeling Event Operations</title>

        <sect4 id="mac-mpo-associate-vnode-devfs">
          <title><function>&mac.mpo;_associate_vnode_devfs</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_associate_vnode_devfs</function></funcdef>

              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fslabel</parameter></paramdef>
              <paramdef>struct devfs_dirent
                *<parameter>de</parameter></paramdef>
              <paramdef>struct label
                *<parameter>delabel</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>mp</parameter></entry>
                  <entry>Devfs mount point</entry>
                </row>

                <row>
                  <entry><parameter>fslabel</parameter></entry>
                  <entry>Devfs file system label
                    (<varname>mp->mnt_fslabel</varname>)</entry>
                </row>

                <row>
                  <entry><parameter>de</parameter></entry>
                  <entry>Devfs directory entry</entry>
                </row>

                <row>
                  <entry><parameter>delabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>de</parameter></entry>
                </row>

                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>vnode associated with
                    <parameter>de</parameter></entry>
                </row>

                <row>
                  <entry><parameter>vlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Fill in the label (<parameter>vlabel</parameter>) for
            a newly created devfs vnode based on the devfs directory
            entry passed in <parameter>de</parameter> and its
            label.</para>
        </sect4>

        <sect4 id="mac-mpo-associate-vnode-extattr">
          <title><function>&mac.mpo;_associate_vnode_extattr</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>int
                <function>&mac.mpo;_associate_vnode_extattr</function></funcdef>

              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fslabel</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>mp</parameter></entry>
                  <entry>File system mount point</entry>
                </row>

                <row>
                  <entry><parameter>fslabel</parameter></entry>
                  <entry>File system label</entry>
                </row>

                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>Vnode to label</entry>
                </row>

                <row>
                  <entry><parameter>vlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Attempt to retrieve the label for
            <parameter>vp</parameter> from the file system extended
            attributes.  Upon success, the value <literal>0</literal>
            is returned.  Should extended attribute retrieval not be
            supported, an accepted fallback is to copy
            <parameter>fslabel</parameter> into
            <parameter>vlabel</parameter>.  In the event of an error,
            an appropriate value for <varname>errno</varname> should
            be returned.</para>
        </sect4>

        <sect4 id="mac-mpo-associate-vnode-singlelabel">
          <title><function>&mac.mpo;_associate_vnode_singlelabel</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_associate_vnode_singlelabel</function></funcdef>

              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fslabel</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>mp</parameter></entry>
                  <entry>File system mount point</entry>
                </row>

                <row>
                  <entry><parameter>fslabel</parameter></entry>
                  <entry>File system label</entry>
                </row>

                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>Vnode to label</entry>
                </row>

                <row>
                  <entry><parameter>vlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>On non-multilabel file systems, this entry point is
            called to set the policy label for
            <parameter>vp</parameter> based on the file system label,
            <parameter>fslabel</parameter>.</para>
        </sect4>


        <sect4 id="mac-mpo-create-devfs-device">
          <title><function>&mac.mpo;_create_devfs_device</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_devfs_device</function></funcdef>
              
              <paramdef>dev_t <parameter>dev</parameter></paramdef>
              <paramdef>struct devfs_dirent
                *<parameter>devfs_dirent</parameter></paramdef>
              <paramdef>struct label
                *<parameter>label</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>dev</parameter></entry>
                  <entry>Device corresponding with
                    <parameter>devfs_dirent</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>devfs_dirent</parameter></entry>
                  <entry>Devfs directory entry to be labeled.</entry>
                </row>
                
                <row>
                  <entry><parameter>label</parameter></entry>
                  <entry>Label for <parameter>devfs_dirent</parameter>
                    to be filled in.</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Fill out the label on a devfs_dirent being created for
            the passed device. This call will be made when the device
            file system is mounted, regenerated, or a new device is made
            available.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-devfs-directory">
          <title><function>&mac.mpo;_create_devfs_directory</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_devfs_directory</function></funcdef>
              
              <paramdef>char *<parameter>dirname</parameter></paramdef>
              <paramdef>int <parameter>dirnamelen</parameter></paramdef>
              <paramdef>struct devfs_dirent
                *<parameter>devfs_dirent</parameter></paramdef>
              <paramdef>struct label
                *<parameter>label</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>dirname</parameter></entry>
                  <entry>Name of directory being created</entry>
                </row>
                
                <row>
                  <entry><parameter>namelen</parameter></entry>
                  <entry>Length of string
                    <parameter>dirname</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>devfs_dirent</parameter></entry>
                  <entry>Devfs directory entry for directory being
                    created.</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Fill out the label on a devfs_dirent being created for
            the passed directory. This call will be made when the device
            file system is mounted, regenerated, or a new device
            requiring a specific directory hierarchy is made
            available.</para>
        </sect4>

        <sect4 id="mac-mpo-create-devfs-symlink">
          <title><function>&mac.mpo;_create_devfs_symlink</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_devfs_symlink</function></funcdef>

              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct devfs_dirent
                *<parameter>dd</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ddlabel</parameter></paramdef>
              <paramdef>struct devfs_dirent
                *<parameter>de</parameter></paramdef>
              <paramdef>struct label
                *<parameter>delabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>

                <row>
                  <entry><parameter>mp</parameter></entry>
                  <entry>Devfs mount point</entry>
                </row>

                <row>
                  <entry><parameter>dd</parameter></entry>
                  <entry>Link destination</entry>
                </row>

                <row>
                  <entry><parameter>ddlabel</parameter></entry>
                  <entry>Label associated with
                    <parameter>dd</parameter></entry>
                </row>

                <row>
                  <entry><parameter>de</parameter></entry>
                  <entry>Symlink entry</entry>
                </row>

                <row>
                  <entry><parameter>delabel</parameter></entry>
                  <entry>Label associated with
                    <parameter>de</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Fill in the label (<parameter>delabel</parameter>) for
            a newly created &man.devfs.5; symbolic link entry.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-vnode-extattr">
          <title><function>&mac.mpo;_create_vnode_extattr</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>int
                <function>&mac.mpo;_create_vnode_extattr</function></funcdef>

              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fslabel</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>dvp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>dlabel</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vlabel</parameter></paramdef>
              <paramdef>struct componentname
                *<parameter>cnp</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>

                <row>
                  <entry><parameter>mount</parameter></entry>
                  <entry>File system mount point</entry>
                </row>

                <row>
                  <entry><parameter>label</parameter></entry>
                  <entry>File system label</entry>
                </row>

                <row>
                  <entry><parameter>dvp</parameter></entry>
                  <entry>Parent directory vnode</entry>
                </row>

                <row>
                  <entry><parameter>dlabel</parameter></entry>
                  <entry>Label associated with
                    <parameter>dvp</parameter></entry>
                </row>

                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>Newly created vnode</entry>
                </row>

                <row>
                  <entry><parameter>vlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>vp</parameter></entry>
                </row>

                <row>
                  <entry><parameter>cnp</parameter></entry>
                  <entry>Component name for
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Write out the label for <parameter>vp</parameter> to
            the appropriate extended attribute.  If the write
            succeeds, fill in <parameter>vlabel</parameter> with the
            label, and return <returnvalue>0</returnvalue>. Otherwise,
            return an appropriate error.</para>
        </sect4>

        <sect4 id="mac-mpo-create-mount">
          <title><function>&mac.mpo;_create_mount</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mount</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mnt</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fslabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>
                
                <row>
                  <entry><parameter>mp</parameter></entry>
                  <entry>Object; file system being mounted</entry>
                </row>
                
                <row>
                  <entry><parameter>mntlabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>mp</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>fslabel</parameter></entry>
                  <entry>Policy label for the file system
                    <parameter>mp</parameter> mounts.</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Fill out the labels on the mount point being created by
            the passed subject credential.  This call will be made when
            a new file system is mounted.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-root-mount">
          <title><function>&mac.mpo;_create_root_mount</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_root_mount</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct mount
                *<parameter>mp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mntlabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fslabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry namest="first" nameend="last">See <xref
                    linkend="mac-mpo-create-mount">.</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Fill out the labels on the mount point being created by
            the passed subject credential.  This call will be made when
            the root file system is mounted, after
            &mac.mpo;_create_mount;.</para>
        </sect4>

        <sect4 id="mac-mpo-relabel-vnode">
          <title><function>&mac.mpo;_relabel_vnode</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_relabel_vnode</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vnodelabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>
                
                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>vnode to relabel</entry>
                </row>
                
                <row>
                  <entry><parameter>vnodelabel</parameter></entry>
                  <entry>Existing policy label for
                    <parameter>vp</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newlabel</parameter></entry>
                  <entry>New, possibly partial label to replace
                    <parameter>vnodelabel</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the label on the passed vnode given the passed
            update vnode label and the passed subject credential.</para>
        </sect4>

        <sect4 id="mac-mpo-setlabel-vnode-extattr">
          <title><function>&mac.mpo;_setlabel_vnode_extattr</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>int
                <function>&mac.mpo;_setlabel_vnode_extattr</function></funcdef>

              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vlabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>intlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>

                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>Vnode for which the label is being
                    written</entry>
                </row>

                <row>
                  <entry><parameter>vlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>vp</parameter></entry>
                </row>

                <row>
                  <entry><parameter>intlabel</parameter></entry>
                  <entry>Label to write out</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Write out the policy from
            <parameter>intlabel</parameter> to an extended
            attribute.  This is called from
            <function>vop_stdcreatevnode_ea</function>.</para>
        </sect4>

        <sect4 id="mac-mpo-update-devfsdirent">
          <title><function>&mac.mpo;_update_devfsdirent</function></title>
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_update_devfsdirent</function></funcdef>
              
              <paramdef>struct devfs_dirent
                *<parameter>devfs_dirent</parameter></paramdef>
              <paramdef>struct label
                *<parameter>direntlabel</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vnodelabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>devfs_dirent</parameter></entry>
                  <entry>Object; devfs directory entry</entry>
                </row>
                
                <row>
                  <entry><parameter>direntlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>devfs_dirent</parameter> to be
                    updated.</entry>
                </row>
                
                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>Parent vnode</entry>
                  <entry>Locked</entry>
                </row>
                
                <row>
                  <entry><parameter>vnodelabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the <parameter>devfs_dirent</parameter> label
            from the passed devfs vnode label.  This call will be made
            when a devfs vnode has been successfully relabeled to commit
            the label change such that it lasts even if the vnode is
            recycled.  It will also be made when when a symlink is
            created in devfs, following a call to
            <function>mac_vnode_create_from_vnode</function> to
            initialize the vnode label.</para>
        </sect4>
      </sect3>
      
      <sect3 id="mac-ipc-label-ops">
        <title>IPC Object Labeling Event Operations</title>

        
        <sect4 id="mac-mpo-create-mbuf-from-socket">
          <title><function>&mac.mpo;_create_mbuf_from_socket</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_from_socket</function></funcdef>
              
              <paramdef>struct socket
                *<parameter>so</parameter></paramdef>
              <paramdef>struct label
                *<parameter>socketlabel</parameter></paramdef>
              <paramdef>struct mbuf *<parameter>m</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>socket</parameter></entry>
                  <entry>Socket</entry>
                  <entry>Socket locking WIP</entry>
                </row>
                
                <row>
                  <entry><parameter>socketlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>socket</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>m</parameter></entry>
                  <entry>Object; mbuf</entry>
                </row>
                
                <row>
                  <entry><parameter>mbuflabel</parameter></entry>
                  <entry>Policy label to fill in for
                    <parameter>m</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on a newly created mbuf header from the
            passed socket label.  This call is made when a new datagram
            or message is generated by the socket and stored in the
            passed mbuf.</para>
        </sect4>

        <sect4 id="mac-mpo-create-pipe">
          <title><function>&mac.mpo;_create_pipe</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_pipe</function></funcdef>

              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct pipe
                *<parameter>pipe</parameter></paramdef>
              <paramdef>struct label
                *<parameter>pipelabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>

                <row>
                  <entry><parameter>pipe</parameter></entry>
                  <entry>Pipe</entry>
                </row>

                <row>
                  <entry><parameter>pipelabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>pipe</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Set the label on a newly created pipe from the passed
            subject credential.  This call is made when a new pipe is
            created.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-socket">
          <title><function>&mac.mpo;_create_socket</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_socket</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct socket
                *<parameter>so</parameter></paramdef>
              <paramdef>struct label
                *<parameter>socketlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                  <entry>Immutable</entry>
                </row>
                
                <row>
                  <entry><parameter>so</parameter></entry>
                  <entry>Object; socket to label</entry>
                </row>
                
                <row>
                  <entry><parameter>socketlabel</parameter></entry>
                  <entry>Label to fill in for
                    <parameter>so</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on a newly created socket from the passed
            subject credential. This call is made when a socket is
            created.</para>
        </sect4>

        <sect4 id="mac-mpo-create-socket-from-socket">
          <title><function>&mac.mpo;_create_socket_from_socket</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_socket_from_socket</function></funcdef>

              <paramdef>struct socket
                *<parameter>oldsocket</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldsocketlabel</parameter></paramdef>
              <paramdef>struct socket
                *<parameter>newsocket</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newsocketlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>oldsocket</parameter></entry>
                  <entry>Listening socket</entry>
                </row>

                <row>
                  <entry><parameter>oldsocketlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>oldsocket</parameter></entry>
                </row>

                <row>
                  <entry><parameter>newsocket</parameter></entry>
                  <entry>New socket</entry>
                </row>

                <row>
                  <entry><parameter>newsocketlabel</parameter></entry>
                  <entry>Policy label associated with
                    <parameter>newsocketlabel</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Label a socket, <parameter>newsocket</parameter>,
            newly &man.accept.2;ed, based on the &man.listen.2;
            socket, <parameter>oldsocket</parameter>.</para>
        </sect4>

        <sect4 id="mac-mpo-relabel-pipe">
          <title><function>&mac.mpo;_relabel_pipe</function></title>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_relabel_pipe</function></funcdef>

              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct pipe
                *<parameter>pipe</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldlabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <informaltable>
            <tgroup cols="3">
              &mac.thead;

              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>

                <row>
                  <entry><parameter>pipe</parameter></entry>
                  <entry>Pipe</entry>
                </row>

                <row>
                  <entry><parameter>oldlabel</parameter></entry>
                  <entry>Current policy label associated with
                    <parameter>pipe</parameter></entry>
                </row>

                <row>
                  <entry><parameter>newlabel</parameter></entry>
                  <entry>Policy label update to apply to
                    <parameter>pipe</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>

          <para>Apply a new label, <parameter>newlabel</parameter>, to
            <parameter>pipe</parameter>.</para>
        </sect4>

        <sect4 id="mac-mpo-relabel-socket">
          <title><function>&mac.mpo;_relabel_socket</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_relabel_socket</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct socket
                *<parameter>so</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldlabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                  <entry>Immutable</entry>
                </row>
                
                <row>
                  <entry><parameter>so</parameter></entry>
                  <entry>Object; socket</entry>
                </row>
                
                <row>
                  <entry><parameter>oldlabel</parameter></entry>
                  <entry>Current label for
                    <parameter>so</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newlabel</parameter></entry>
                  <entry>Label update for
                    <parameter>so</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the label on a socket from the passed socket
            label update.</para>
        </sect4>
        
        <sect4 id="mpo-set-socket-peer-from-mbuf">
          <title><function>&mac.mpo;_set_socket_peer_from_mbuf</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_set_socket_peer_from_mbuf</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>mbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mbuflabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldlabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>mbuf</parameter></entry>
                  <entry>First datagram received over socket</entry>
                </row>
                
                <row>
                  <entry><parameter>mbuflabel</parameter></entry>
                  <entry>Label for <parameter>mbuf</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>oldlabel</parameter></entry>
                  <entry>Current label for the socket</entry>
                </row>
                
                <row>
                  <entry><parameter>newlabel</parameter></entry>
                  <entry>Policy label to be filled out for the
                    socket</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the peer label on a stream socket from the passed
            mbuf label.  This call will be made when the first datagram
            is received by the stream socket, with the exception of Unix
            domain sockets.</para>
        </sect4>
        
        <sect4 id="mac-mpo-set-socket-peer-from-socket">
          <title><function>&mac.mpo;_set_socket_peer_from_socket</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_set_socket_peer_from_socket</function></funcdef>
              
              <paramdef>struct socket
                *<parameter>oldsocket</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldsocketlabel</parameter></paramdef>
              <paramdef>struct socket
                *<parameter>newsocket</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newsocketpeerlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>oldsocket</parameter></entry>
                  <entry>Local socket</entry>
                </row>
                
                <row>
                  <entry><parameter>oldsocketlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>oldsocket</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newsocket</parameter></entry>
                  <entry>Peer socket</entry>
                </row>
                
                <row>
                  <entry><parameter>newsocketpeerlabel</parameter></entry>
                  <entry>Policy label to fill in for
                    <parameter>newsocket</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <!-- XXX Passed _remote_ socket endpoint ? -->
          <para>Set the peer label on a stream UNIX domain socket from
            the passed remote socket endpoint.  This call will be made
            when the socket pair is connected, and will be made for both
            endpoints.</para>
        </sect4>
      </sect3>
      
      <sect3 id="mac-net-labeling-event-ops">
        <title>Network Object Labeling Event Operations</title>
        
        <sect4 id="mac-mpo-create-bpfdesc">
          <title><function>&mac.mpo;_create_bpfdesc</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_bpfdesc</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct bpf_d
                *<parameter>bpf_d</parameter></paramdef>
              <paramdef>struct label
                *<parameter>bpflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                  <entry>Immutable</entry>
                </row>
                
                <row>
                  <entry><parameter>bpf_d</parameter></entry>
                  <entry>Object; bpf descriptor</entry>
                </row>
                
                <row>
                  <entry><parameter>bpf</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>bpf_d</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on a newly created BPF descriptor from the
            passed subject credential.  This call will be made when a
            BPF device node is opened by a process with the passed
            subject credential.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-ifnet">
          <title><function>&mac.mpo;_create_ifnet</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_ifnet</function></funcdef>
              
              <paramdef>struct ifnet
                *<parameter>ifnet</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ifnetlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>ifnet</parameter></entry>
                  <entry>Network interface</entry>
                </row>
                
                <row>
                  <entry><parameter>ifnetlabel</parameter></entry>
                  <entry>Policy label to fill in for
                    <parameter>ifnet</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on a newly created interface.  This call
            may be made when a new physical interface becomes available
            to the system, or when a pseudo-interface is instantiated
            during the boot or as a result of a user action.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-ipq">
          <title><function>&mac.mpo;_create_ipq</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_ipq</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>fragment</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fragmentlabel</parameter></paramdef>
              <paramdef>struct ipq
                *<parameter>ipq</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ipqlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>fragment</parameter></entry>
                  <entry>First received IP fragment</entry>
                </row>
                
                <row>
                  <entry><parameter>fragmentlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>fragment</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>ipq</parameter></entry>
                  <entry>IP reassembly queue to be labeled</entry>
                </row>
                
                <row>
                  <entry><parameter>ipqlabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>ipq</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on a newly created IP fragment reassembly
            queue from the mbuf header of the first received
            fragment.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-datagram-from-ipq">
          <title><function>&mac.mpo;_create_datagram_from_ipq</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_create_datagram_from_ipq</function></funcdef>
              
              <paramdef>struct ipq
                *<parameter>ipq</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ipqlabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>datagram</parameter></paramdef>
              <paramdef>struct label
                *<parameter>datagramlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>ipq</parameter></entry>
                  <entry>IP reassembly queue</entry>
                </row>
                
                <row>
                  <entry><parameter>ipqlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>ipq</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>datagram</parameter></entry>
                  <entry>Datagram to be labeled</entry>
                </row>
                
                <row>
                  <entry><parameter>datagramlabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>datagramlabel</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on a newly reassembled IP datagram from
            the IP fragment reassembly queue from which it was
            generated.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-fragment">
          <title><function>&mac.mpo;_create_fragment</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_fragment</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>datagram</parameter></paramdef>
              <paramdef>struct label
                *<parameter>datagramlabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>fragment</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fragmentlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>datagram</parameter></entry>
                  <entry>Datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>datagramlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>datagram</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>fragment</parameter></entry>
                  <entry>Fragment to be labeled</entry>
                </row>
                
                <row>
                  <entry><parameter>fragmentlabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>datagram</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created IP
            fragment from the label on the mbuf header of the datagram
            it was generate from.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-mbuf-from-mbuf">
          <title><function>&mac.mpo;_create_mbuf_from_mbuf</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_from_mbuf</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>oldmbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldmbuflabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>newmbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newmbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>oldmbuf</parameter></entry>
                  <entry>Existing (source) mbuf</entry>
                </row>
                
                <row>
                  <entry><parameter>oldmbuflabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>oldmbuf</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newmbuf</parameter></entry>
                  <entry>New mbuf to be labeled</entry>
                </row>
                
                <row>
                  <entry><parameter>newmbuflabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>newmbuf</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created
            datagram from the mbuf header of an existing datagram.  This
            call may be made in a number of situations, including when
            an mbuf is re-allocated for alignment purposes.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-mbuf-linklayer">
          <title><function>&mac.mpo;_create_mbuf_linklayer</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_linklayer</function></funcdef>
              
              <paramdef>struct ifnet
                *<parameter>ifnet</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ifnetlabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>mbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>ifnet</parameter></entry>
                  <entry>Network interface</entry>
                </row>
                
                <row>
                  <entry><parameter>ifnetlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>ifnet</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>mbuf</parameter></entry>
                  <entry>mbuf header for new datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>mbuflabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>mbuf</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created
            datagram generated for the purposes of a link layer response
            for the passed interface.  This call may be made in a number
            of situations, including for ARP or ND6 responses in the
            IPv4 and IPv6 stacks.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-mbuf-from-bpfdesc">
          <title><function>&mac.mpo;_create_mbuf_from_bpfdesc</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_from_bpfdesc</function></funcdef>
              
              <paramdef>struct bpf_d
                *<parameter>bpf_d</parameter></paramdef>
              <paramdef>struct label
                *<parameter>bpflabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>mbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>bpf_d</parameter></entry>
                  <entry>BPF descriptor</entry>
                </row>
                
                <row>
                  <entry><parameter>bpflabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>bpflabel</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>mbuf</parameter></entry>
                  <entry>New mbuf to be labeled</entry>
                </row>
                
                <row>
                  <entry><parameter>mbuflabel</parameter></entry>
                  <entry>Policy label to fill in for
                    <parameter>mbuf</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created
            datagram generated using the passed BPF descriptor.  This
            call is made when a write is performed to the BPF device
            associated with the passed BPF descriptor.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-mbuf-from-ifnet">
          <title><function>&mac.mpo;_create_mbuf_from_ifnet</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_from_ifnet</function></funcdef>
              
              <paramdef>struct ifnet
                *<parameter>ifnet</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ifnetlabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>mbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>mbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>ifnet</parameter></entry>
                  <entry>Network interface</entry>
                </row>
                
                <row>
                 <entry><parameter>ifnetlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>ifnetlabel</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>mbuf</parameter></entry>
                  <entry>mbuf header for new datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>mbuflabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>mbuf</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created
            datagram generated from the passed network interface.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-mbuf-multicast-encap">
          <title><function>&mac.mpo;_create_mbuf_multicast_encap</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_multicast_encap</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>oldmbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldmbuflabel</parameter></paramdef>
              <paramdef>struct ifnet
                *<parameter>ifnet</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ifnetlabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>newmbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newmbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>oldmbuf</parameter></entry>
                  <entry>mbuf header for existing datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>oldmbuflabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>oldmbuf</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>ifnet</parameter></entry>
                  <entry>Network interface</entry>
                </row>
                
                <row>
                  <entry><parameter>ifnetlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>ifnet</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newmbuf</parameter></entry>
                  <entry>mbuf header to be labeled for new
                    datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>newmbuflabel</parameter></entry>
                  <entry>Policy label to be filled in for
                    <parameter>newmbuf</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created
            datagram generated from the existing passed datagram when it
            is processed by the passed multicast encapsulation
            interface.  This call is made when an mbuf is to be
            delivered using the virtual interface.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-mbuf-netlayer">
          <title><function>&mac.mpo;_create_mbuf_netlayer</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_mbuf_netlayer</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>oldmbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>oldmbuflabel</parameter></paramdef>
              <paramdef>struct mbuf
                *<parameter>newmbuf</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newmbuflabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>oldmbuf</parameter></entry>
                  <entry>Received datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>oldmbuflabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>oldmbuf</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newmbuf</parameter></entry>
                  <entry>Newly created datagram</entry>
                </row>
                
                <row>
                  <entry><parameter>newmbuflabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>newmbuf</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label on the mbuf header of a newly created
            datagram generated by the IP stack in response to an
            existing received datagram (<parameter>oldmbuf</parameter>).
            This call may be made in a number of situations, including
            when responding to ICMP request datagrams.</para>
        </sect4>
        
        <sect4 id="mac-mpo-fragment-match">
          <title><function>&mac.mpo;_fragment_match</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>int
                <function>&mac.mpo;_fragment_match</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>fragment</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fragmentlabel</parameter></paramdef>
              <paramdef>struct ipq
                *<parameter>ipq</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ipqlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>fragment</parameter></entry>
                  <entry>IP datagram fragment</entry>
                </row>
                
                <row>
                  <entry><parameter>fragmentlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>fragment</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>ipq</parameter></entry>
                  <entry>IP fragment reassembly queue</entry>
                </row>
                
                <row>
                  <entry><parameter>ipqlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>ipq</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Determine whether an mbuf header containing an IP
            datagram (<parameter>fragment</parameter>) fragment matches
            the label of the passed IP fragment reassembly queue
            (<parameter>ipq</parameter>).  Return
            (<returnvalue>1</returnvalue>) for a successful match, or
            (<returnvalue>0</returnvalue>) for no match.  This call is
            made when the IP stack attempts to find an existing fragment
            reassembly queue for a newly received fragment; if this
            fails, a new fragment reassembly queue may be instantiated
            for the fragment. Policies may use this entry point to
            prevent the reassembly of otherwise matching IP fragments if
            policy does not permit them to be reassembled based on the
            label or other information.</para>
        </sect4>
        
        <sect4 id="mac-mpo-ifnet-relabel">
          <title><function>&mac.mpo;_relabel_ifnet</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_relabel_ifnet</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct ifnet
                *<parameter>ifnet</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ifnetlabel</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>
                
                <row>
                  <entry><parameter>ifnet</parameter></entry>
                  <entry>Object; Network interface</entry>
                </row>
                
                <row>
                  <entry><parameter>ifnetlabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>ifnet</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>newlabel</parameter></entry>
                  <entry>Label update to apply to
                    <parameter>ifnet</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the label of network interface,
            <parameter>ifnet</parameter>, based on the passed update
            label, <parameter>newlabel</parameter>, and the passed
            subject credential, <parameter>cred</parameter>.</para>
        </sect4>
        
        <sect4 id="mac-mpo-update-ipq">
          <title><function>&mac.mpo;_update_ipq</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_update_ipq</function></funcdef>
              
              <paramdef>struct mbuf
                *<parameter>fragment</parameter></paramdef>
              <paramdef>struct label
                *<parameter>fragmentlabel</parameter></paramdef>
              <paramdef>struct ipq
                *<parameter>ipq</parameter></paramdef>
              <paramdef>struct label
                *<parameter>ipqlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>mbuf</parameter></entry>
                  <entry>IP fragment</entry>
                </row>
                
                <row>
                  <entry><parameter>mbuflabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>mbuf</parameter></entry>
                </row>
                
                <row>
                  <entry><parameter>ipq</parameter></entry>
                  <entry>IP fragment reassembly queue</entry>
                </row>
                
                <row>
                  <entry><parameter>ipqlabel</parameter></entry>
                  <entry>Policy label to be updated for
                    <parameter>ipq</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the label on an IP fragment reassembly queue
            (<parameter>ipq</parameter>) based on the acceptance of the
            passed IP fragment mbuf header
            (<parameter>mbuf</parameter>).</para>
        </sect4>
      </sect3>
      
      <sect3 id="mac-proc-labeling-event-ops">
        <title>Process Labeling Event Operations</title>
        
        <sect4 id="mac-mpo-create-cred">
          <title><function>&mac.mpo;_create_cred</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_cred</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>parent_cred</parameter></paramdef>
              <paramdef>struct ucred
                *<parameter>child_cred</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>parent_cred</parameter></entry>
                  <entry>Parent subject credential</entry>
                </row>
                
                <row>
                  <entry><parameter>child_cred</parameter></entry>
                  <entry>Child subject credential</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Set the label of a newly created subject credential from
            the passed subject credential.  This call will be made when
            &man.crcopy.9; is invoked on a newly created <type>struct
              ucred</type>.  This call should not be confused with a
            process forking or creation event.</para>
        </sect4>
        
        <sect4 id="mac-mpo-execve-transition">
          <title><function>&mac.mpo;_execve_transition</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_execve_transition</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>old</parameter></paramdef>
              <paramdef>struct ucred
                *<parameter>new</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vnodelabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>old</parameter></entry>
                  <entry>Existing subject credential</entry>
                  <entry>Immutable</entry>
                </row>
                
                <row>
                  <entry><parameter>new</parameter></entry>
                  <entry>New subject credential to be labeled</entry>
                </row>
                
                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>File to execute</entry>
                  <entry>Locked</entry>
                </row>
                
                <row>
                  <entry><parameter>vnodelabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the label of a newly created subject credential
            (<parameter>new</parameter>) from the passed existing
            subject credential (<parameter>old</parameter>) based on a
            label transition caused by executing the passed vnode
            (<parameter>vp</parameter>).  This call occurs when a
            process executes the passed vnode and one of the policies
            returns a success from the
            <function>mpo_execve_will_transition</function> entry point.
            Policies may choose to implement this call simply by
            invoking <function>mpo_create_cred</function> and passing
            the two subject credentials so as not to implement a
            transitioning event.  Policies should not leave this entry
            point unimplemented if they implement
            <function>mpo_create_cred</function>, even if they do not
            implement
            <function>mpo_execve_will_transition</function>.</para>
        </sect4>
        
        <sect4 id="mac-mpo-execve-will-transition">
          <title><function>&mac.mpo;_execve_will_transition</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>int
                <function>&mac.mpo;_execve_will_transition</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>old</parameter></paramdef>
              <paramdef>struct vnode
                *<parameter>vp</parameter></paramdef>
              <paramdef>struct label
                *<parameter>vnodelabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>old</parameter></entry>
                  <entry>Subject credential prior to
                      &man.execve.2;</entry>
                  <entry>Immutable</entry>
                </row>
                
                <row>
                  <entry><parameter>vp</parameter></entry>
                  <entry>File to execute</entry>
                </row>
                
                <row>
                  <entry><parameter>vnodelabel</parameter></entry>
                  <entry>Policy label for
                    <parameter>vp</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Determine whether the policy will want to perform a
            transition event as a result of the execution of the passed
            vnode by the passed subject credential.  Return
            <returnvalue>1</returnvalue> if a transition is required,
            <returnvalue>0</returnvalue> if not.  Even if a policy
            returns <returnvalue>0</returnvalue>, it should behave
            correctly in the presence of an unexpected invocation of
            <function>mpo_execve_transition</function>, as that call may
            happen as a result of another policy requesting a
            transition.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-proc0">
          <title><function>&mac.mpo;_create_proc0</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_proc0</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential to be filled in</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Create the subject credential of process 0, the parent
            of all kernel processes.</para>
        </sect4>
        
        <sect4 id="mac-mpo-create-proc1">
          <title><function>&mac.mpo;_create_proc1</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_create_proc1</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential to be filled in</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Create the subject credential of process 1, the parent
            of all user processes.</para>
        </sect4>
        
        <sect4 id="mac-mpo-relabel-cred">
          <title><function>&mac.mpo;_relabel_cred</function></title>
          
          <funcsynopsis>
            <funcprototype>
              <funcdef>void
                <function>&mac.mpo;_relabel_cred</function></funcdef>
              
              <paramdef>struct ucred
                *<parameter>cred</parameter></paramdef>
              <paramdef>struct label
                *<parameter>newlabel</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>
          
          <informaltable>
            <tgroup cols="3">
              &mac.thead;
              
              <tbody>
                <row>
                  <entry><parameter>cred</parameter></entry>
                  <entry>Subject credential</entry>
                </row>
                
                <row>
                  <entry><parameter>newlabel</parameter></entry>
                  <entry>Label update to apply to
                    <parameter>cred</parameter></entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          
          <para>Update the label on a subject credential from the passed
            update label.</para>
        </sect4>



      </sect3>
    </sect2>
    
    <sect2 id="mac-access-control-checks">
      <title>Access Control Checks</title>
      
      <para>Access control entry points permit policy modules to
        influence access control decisions made by the kernel.
        Generally, although not always, arguments to an access control
        entry point will include one or more authorizing credentials,
        information (possibly including a label) for any other objects
        involved in the operation.  An access control entry point may
        return 0 to permit the operation, or an &man.errno.2; error
        value.  The results of invoking the entry point across various
        registered policy modules will be composed as follows: if all
        modules permit the operation to succeed, success will be
        returned.  If one or modules returns a failure, a failure will
        be returned.  If more than one module returns a failure, the
        errno value to return to the user will be selected using the
        following precedence, implemented by the
        <function>error_select()</function> function in
        <filename>kern_mac.c</filename>:</para>
      
      <informaltable>
        <tgroup cols="2">
          <tbody>
            <row>
              <entry>Most precedence</entry>
              <entry><errorcode>EDEADLK</errorcode></entry></row>
            
            <row>
              <entry></entry>
              <entry><errorcode>EINVAL</errorcode></entry>
            </row>
            <row>
              <entry></entry>
              <entry><errorcode>ESRCH</errorcode></entry>
            </row>
            <row>
              <entry></entry>
              <entry>EACCES</entry>
            </row>
            <row>
              <entry>Least precedence</entry>
              <entry>EPERM</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
      
      <para>If none of the error values returned by all modules are
        listed in the precedence chart then an arbitrarily selected
        value from the set will be returned.  In general, the rules
        provide precedence to errors in the following order: kernel
        failures, invalid arguments, object not present, access not
        permitted, other.</para>
      
      <sect3 id="mac-mpo-bpfdesc-check-receive-from-ifnet">
        <title><function>&mac.mpo;_check_bpfdesc_receive</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_bpfdesc_receive</function></funcdef>
            
            <paramdef>struct bpf_d
              *<parameter>bpf_d</parameter></paramdef>
            <paramdef>struct label
              *<parameter>bpflabel</parameter></paramdef>
            <paramdef>struct ifnet
              *<parameter>ifnet</parameter></paramdef>
            <paramdef>struct label
              *<parameter>ifnetlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>bpf_d</parameter></entry>
                <entry>Subject; BPF descriptor</entry>
              </row>
              
              <row>
                <entry><parameter>bpflabel</parameter></entry>
                <entry>Policy label for
                  <parameter>bpf_d</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>ifnet</parameter></entry>
                <entry>Object; network interface</entry>
              </row>
              
              <row>
                <entry><parameter>ifnetlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>ifnet</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the MAC framework should permit
          datagrams from the passed interface to be delivered to the
          buffers of the passed BPF descriptor.  Return
          (<returnvalue>0</returnvalue>) for success, or an
          <varname>errno</varname> value for failure Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatches,
          <errorcode>EPERM</errorcode> for lack of privilege.</para>
      </sect3>

      <sect3 id="mac-mpo-check-kenv-dump">
        <title><function>&mac.mpo;_check_kenv_dump</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kenv_dump</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          retrieve the kernel environment (see &man.kenv.2;).</para>
      </sect3>

      <sect3 id="mac-mpo-check-kenv-get">
        <title><function>&mac.mpo;_check_kenv_get</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kenv_get</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>char *<parameter>name</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>name</parameter></entry>
                <entry>Kernel environment variable name</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          retrieve the value of the specified kernel environment
          variable.</para>
      </sect3>

      <sect3 id="mac-mpo-check-kenv-set">
        <title><function>&mac.mpo;_check_kenv_set</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kenv_set</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>char *<parameter>name</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>name</parameter></entry>
                <entry>Kernel environment variable name</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to set
          the specified kernel environment variable.</para>
      </sect3>

      <sect3 id="mac-mpo-check-kenv-unset">
        <title><function>&mac.mpo;_check_kenv_unset</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kenv_unset</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>char *<parameter>name</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>name</parameter></entry>
                <entry>Kernel environment variable name</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to unset
          the specified kernel environment variable.</para>
      </sect3>

      <sect3 id="mac-mpo-check-kld-load">
        <title><function>&mac.mpo;_check_kld_load</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kld_load</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>vlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Kernel module vnode</entry>
              </row>

              <row>
                <entry><parameter>vlabel</parameter></entry>
                <entry>Label associated with
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to load
          the specified module file.</para>
      </sect3>

      <sect3 id="mac-mpo-check-kld-stat">
        <title><function>&mac.mpo;_check_kld_stat</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kld_stat</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          retrieve a list of loaded kernel module files and associated
          statistics.</para>
      </sect3>

      <sect3 id="mac-mpo-check-kld-unload">
        <title><function>&mac.mpo;_check_kld_unload</function></title>

        <funcsynopsis>
           <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_kld_unload</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          unload a kernel module.</para>
      </sect3>

      <sect3 id="mac-mpo-check-pipe-ioctl">
        <title><function>&mac.mpo;_check_pipe_ioctl</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_pipe_ioctl</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct pipe
              *<parameter>pipe</parameter></paramdef>
            <paramdef>struct label
              *<parameter>pipelabel</parameter></paramdef>
            <paramdef>unsigned long
              <parameter>cmd</parameter></paramdef>
            <paramdef>void *<parameter>data</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>pipe</parameter></entry>
                <entry>Pipe</entry>
              </row>

              <row>
                <entry><parameter>pipelabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>pipe</parameter></entry>
              </row>

              <row>
                <entry><parameter>cmd</parameter></entry>
                <entry>&man.ioctl.2; command</entry>
              </row>

              <row>
                <entry><parameter>data</parameter></entry>
                <entry>&man.ioctl.2; data</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to make
          the specified &man.ioctl.2; call.</para>
      </sect3>

      <sect3 id="mac-mpo-check-pipe-poll">
        <title><function>&mac.mpo;_check_pipe_poll</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_pipe_poll</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct pipe
              *<parameter>pipe</parameter></paramdef>
            <paramdef>struct label
              *<parameter>pipelabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>pipe</parameter></entry>
                <entry>Pipe</entry>
              </row>

              <row>
                <entry><parameter>pipelabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>pipe</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to poll
          <parameter>pipe</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-pipe-read">
        <title><function>&mac.mpo;_check_pipe_read</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_pipe_read</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct pipe
              *<parameter>pipe</parameter></paramdef>
            <paramdef>struct label
              *<parameter>pipelabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>pipe</parameter></entry>
                <entry>Pipe</entry>
              </row>

              <row>
                <entry><parameter>pipelabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>pipe</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed read
          access to <parameter>pipe</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-pipe-relabel">
        <title><function>&mac.mpo;_check_pipe_relabel</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_pipe_relabel</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct pipe
              *<parameter>pipe</parameter></paramdef>
            <paramdef>struct label
              *<parameter>pipelabel</parameter></paramdef>
            <paramdef>struct label
              *<parameter>newlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>pipe</parameter></entry>
                <entry>Pipe</entry>
              </row>

              <row>
                <entry><parameter>pipelabel</parameter></entry>
                <entry>Current policy label associated with
                  <parameter>pipe</parameter></entry>
              </row>

              <row>
                <entry><parameter>newlabel</parameter></entry>
                <entry>Label update to
                  <parameter>pipelabel</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          relabel <parameter>pipe</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-pipe-stat">
        <title><function>&mac.mpo;_check_pipe_stat</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_pipe_stat</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct pipe
              *<parameter>pipe</parameter></paramdef>
            <paramdef>struct label
              *<parameter>pipelabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>pipe</parameter></entry>
                <entry>Pipe</entry>
              </row>

              <row>
                <entry><parameter>pipelabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>pipe</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          retrieve statistics related to
          <parameter>pipe</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-pipe-write">
        <title><function>&mac.mpo;_check_pipe_write</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_pipe_write</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct pipe
              *<parameter>pipe</parameter></paramdef>
            <paramdef>struct label
              *<parameter>pipelabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>pipe</parameter></entry>
                <entry>Pipe</entry>
              </row>

              <row>
                <entry><parameter>pipelabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>pipe</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to write
          to <parameter>pipe</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-cred-check-socket-bind">
        <title><function>&mac.mpo;_check_socket_bind</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_bind</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>socket</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
            <paramdef>struct sockaddr
              *<parameter>sockaddr</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>socket</parameter></entry>
                <entry>Socket to be bound</entry>
              </row>
              
              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>socket</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>sockaddr</parameter></entry>
                <entry>Address of
                  <parameter>socket</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
      </sect3>
      
      
      <sect3 id="mac-mpo-cred-check-socket-connect">
        <title><function>&mac.mpo;_check_socket_connect</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_connect</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>socket</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
            <paramdef>struct sockaddr
              *<parameter>sockaddr</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>socket</parameter></entry>
                <entry>Socket to be connected</entry>
              </row>
              
              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>socket</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>sockaddr</parameter></entry>
                <entry>Address of
                  <parameter>socket</parameter></entry>
              </row>
            </tbody>            
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential
          (<parameter>cred</parameter>) can connect the passed socket
          (<parameter>socket</parameter>) to the passed socket address
          (<parameter>sockaddr</parameter>).  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatches,
          <errorcode>EPERM</errorcode> for lack of privilege.</para>
      </sect3>

      <sect3 id="mac-mpo-check-socket-receive">
        <title><function>&mac.mpo;_check_socket_receive</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_receive</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>so</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>so</parameter></entry>
                <entry>Socket</entry>
              </row>

              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>so</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          receive information from the socket
          <parameter>so</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-socket-send">
        <title><function>&mac.mpo;_check_socket_send</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_send</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>so</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>so</parameter></entry>
                <entry>Socket</entry>
              </row>

              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>so</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to send
          information across the socket
          <parameter>so</parameter>.</para>
      </sect3>
      
      <sect3 id="mac-mpo-check-cred-visible">
        <title><function>&mac.mpo;_check_cred_visible</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_cred_visible</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>u1</parameter></paramdef>
            <paramdef>struct ucred
              *<parameter>u2</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>u1</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>u2</parameter></entry>
                <entry>Object credential</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential
          <parameter>u1</parameter> can <quote>see</quote> other
          subjects with the passed subject credential
          <parameter>u2</parameter>.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatches,
          <errorcode>EPERM</errorcode> for lack of privilege, or
          <errorcode>ESRCH</errorcode> to hide visibility.  This call
          may be made in a number of situations, including
          inter-process status sysctls used by <command>ps</command>,
          and in procfs lookups.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-socket-visible">
        <title><function>&mac.mpo;_check_socket_visible</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_visible</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>socket</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>socket</parameter></entry>
                <entry>Object; socket</entry>
              </row>
              
              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>socket</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-ifnet-relabel">
        <title><function>&mac.mpo;_check_ifnet_relabel</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_ifnet_relabel</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct ifnet
              *<parameter>ifnet</parameter></paramdef>
            <paramdef>struct label
              *<parameter>ifnetlabel</parameter></paramdef>
            <paramdef>struct label
              *<parameter>newlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>ifnet</parameter></entry>
                <entry>Object; network interface</entry>
              </row>
              
              <row>
                <entry><parameter>ifnetlabel</parameter></entry>
                <entry>Existing policy label for
                  <parameter>ifnet</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>newlabel</parameter></entry>
                <entry>Policy label update to later be applied to
                  <parameter>ifnet</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can relabel the
          passed network interface to the passed label update.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-socket-relabel">
        <title><function>&mac.mpo;_check_socket_relabel</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_relabel</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>socket</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
            <paramdef>struct label
              *<parameter>newlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>socket</parameter></entry>
                <entry>Object; socket</entry>
              </row>
              
              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Existing policy label for
                  <parameter>socket</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>newlabel</parameter></entry>
                <entry>Label update to later be applied to
                  <parameter>socketlabel</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can relabel the
          passed socket to the passed label update.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-cred-relabel">
        <title><function>&mac.mpo;_check_cred_relabel</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_cred_relabel</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct label
              *<parameter>newlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>newlabel</parameter></entry>
                <entry>Label update to later be applied to
                  <parameter>cred</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can relabel
          itself to the passed label update.</para>
      </sect3>


      <sect3 id="mac-mpo-cred-check-vnode-relabel">
        <title><function>&mac.mpo;_check_vnode_relabel</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_relabel</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>vnodelabel</parameter></paramdef>
            <paramdef>struct label
              *<parameter>newlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
                <entry>Immutable</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
                <entry>Locked</entry>
              </row>
              
              <row>
                <entry><parameter>vnodelabel</parameter></entry>
                <entry>Existing policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>newlabel</parameter></entry>
                <entry>Policy label update to later be applied to
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can relabel the
          passed vnode to the passed label update.</para>
      </sect3>
      
      <sect3 id="mpo-cred-check-mount-stat">
        <title><function>&mac.mpo;_check_mount_stat</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int <function>&mac.mpo;_check_mount_stat</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct mount
              *<parameter>mp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>mountlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>mp</parameter></entry>
                <entry>Object; file system mount</entry>
              </row>
              
              <row>
                <entry><parameter>mountlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>mp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
	<!-- XXX Update ? -->
        <para>Determine whether the subject credential can see the
          results of a statfs performed on the file system.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatches
          or <errorcode>EPERM</errorcode> for lack of privilege.  This
          call may be made in a number of situations, including during
          invocations of &man.statfs.2; and related calls, as well as to
          determine what file systems to exclude from listings of file
          systems, such as when &man.getfsstat.2; is invoked. </para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-proc-debug">
        <title><function>&mac.mpo;_check_proc_debug</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_proc_debug</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct proc
              *<parameter>proc</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
                <entry>Immutable</entry>
              </row>
              
              <row>
                <entry><parameter>proc</parameter></entry>
                <entry>Object; process</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can debug the
          passed process.  Return <returnvalue>0</returnvalue> for
          success, or an <varname>errno</varname> value for failure.
          Suggested failure: <errorcode>EACCES</errorcode> for label
          mismatch, <errorcode>EPERM</errorcode> for lack of
          privilege, or <errorcode>ESRCH</errorcode> to hide
          visibility of the target.  This call may be made in a number
          of situations, including use of the &man.ptrace.2; and
            &man.ktrace.2; APIs, as well as for some types of procfs
          operations.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-access">
        <title><function>&mac.mpo;_check_vnode_access</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_access</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>flags</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>flags</parameter></entry>
                <entry>&man.access.2; flags</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine how invocations of &man.access.2; and related
          calls by the subject credential should return when performed
          on the passed vnode using the passed access flags.  This
          should generally be implemented using the same semantics
          used in <function>&mac.mpo;_check_vnode_open</function>.
          Return <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatches
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-chdir">
        <title><function>&mac.mpo;_check_vnode_chdir</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_chdir</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Object; vnode to &man.chdir.2; into</entry>
              </row>
              
              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>dvp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can change the
          process working directory to the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-chroot">
        <title><function>&mac.mpo;_check_vnode_chroot</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_chroot</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Directory vnode</entry>
              </row>

              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>dvp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
            &man.chroot.2; into the specified directory
          (<parameter>dvp</parameter>).</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-create">
        <title><function>&mac.mpo;_check_vnode_create</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_create</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
            <paramdef>struct componentname
              *<parameter>cnp</parameter></paramdef>
            <paramdef>struct vattr
              *<parameter>vap</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>dvp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>cnp</parameter></entry>
                <entry>Component name for
                  <parameter>dvp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>vap</parameter></entry>
                <entry>vnode attributes for <parameter>vap</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can create a
          vnode with the passed parent directory, passed name
          information, and passed attribute information.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode>. for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of privilege.
          This call may be made in a number of situations, including
          as a result of calls to &man.open.2; with
          <symbol>O_CREAT</symbol>, &man.mknod.2;, &man.mkfifo.2;, and
          others.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-delete">
        <title><function>&mac.mpo;_check_vnode_delete</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_delete</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>void *<parameter>label</parameter></paramdef>
            <paramdef>struct componentname
              *<parameter>cnp</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Parent directory vnode</entry>
              </row>
              
              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>dvp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode to delete</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>cnp</parameter></entry>
                <entry>Component name for
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can delete a
          vnode from the passed parent directory and passed name
          information.  Return <returnvalue>0</returnvalue> for
          success, or an <varname>errno</varname> value for failure.
          Suggested failure: <errorcode>EACCES</errorcode> for label
          mismatch, or <errorcode>EPERM</errorcode> for lack of
          privilege.  This call may be made in a number of situations,
          including as a result of calls to &man.unlink.2; and
            &man.rmdir.2;.  Policies implementing this entry point
          should also implement
          <function>mpo_check_rename_to</function> to authorize
          deletion of objects as a result of being the target of a
          rename.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-deleteacl">
        <title><function>&mac.mpo;_check_vnode_deleteacl</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_deleteacl</function></funcdef>
            
            <paramdef>struct ucred *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode *<parameter>vp</parameter></paramdef>
            <paramdef>struct label *<parameter>label</parameter></paramdef>
            <paramdef>acl_type_t <parameter>type</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
                <entry>Immutable</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
                <entry>Locked</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>type</parameter></entry>
                <entry>ACL type</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can delete the
          ACL of passed type from the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-exec">
        <title><function>&mac.mpo;_check_vnode_exec</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_exec</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode to execute</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can execute the
          passed vnode.  Determination of execute privilege is made
          separately from decisions about any transitioning event.
          Return <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mpo-cred-check-vnode-getacl">
        <title><function>&mac.mpo;_check_vnode_getacl</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_getacl</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>acl_type_t
              <parameter>type</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>type</parameter></entry>
                <entry>ACL type</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can retrieve
          the ACL of passed type from the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-getextattr">
        <title><function>&mac.mpo;_check_vnode_getextattr</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_getextattr</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int
              <parameter>attrnamespace</parameter></paramdef>
            <paramdef>const char
              *<parameter>name</parameter></paramdef>
            <paramdef>struct uio
              *<parameter>uio</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>attrnamespace</parameter></entry>
                <entry>Extended attribute namespace</entry>
              </row>
              
              <row>
                <entry><parameter>name</parameter></entry>
                <entry>Extended attribute name</entry>
              </row>
              
              <row>
                <entry><parameter>uio</parameter></entry>
                <entry>I/O structure pointer; see &man.uio.9;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can retrieve
          the extended attribute with the passed namespace and name
          from the passed vnode. Policies implementing labeling using
          extended attributes may be interested in special handling of
          operations on those extended attributes.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure. Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-link">
        <title><function>&mac.mpo;_check_vnode_link</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_link</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>struct componentname
              *<parameter>cnp</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Directory vnode</entry>
              </row>

              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>dvp</parameter></entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Link destination vnode</entry>
              </row>

              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label associated with
                  <parameter>vp</parameter></entry>
              </row>

              <row>
                <entry><parameter>cnp</parameter></entry>
                <entry>Component name for the link being created</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          create a link to the vnode <parameter>vp</parameter> with
          the name specified by <parameter>cnp</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-mmap">
        <title><function>&mac.mpo;_check_vnode_mmap</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_mmap</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>prot</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Vnode to map</entry>
              </row>

              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label associated with
                  <parameter>vp</parameter></entry>
              </row>

              <row>
                <entry><parameter>prot</parameter></entry>
                <entry>Mmap protections (see &man.mmap.2;)</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to map
          the vnode <parameter>vp</parameter> with the protections
          specified in <parameter>prot</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-mmap-downgrade">
        <title><function>&mac.mpo;_check_vnode_mmap_downgrade</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
              <function>&mac.mpo;_check_vnode_mmap_downgrade</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int *<parameter>prot</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry morerows="2">See
                  <xref linkend="mac-mpo-check-vnode-mmap">.</entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
              </row>

              <row>
                <entry><parameter>label</parameter></entry>
              </row>

              <row>
                <entry><parameter>prot</parameter></entry>
                <entry>Mmap protections to be downgraded</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Downgrade the mmap protections based on the subject and
          object labels.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-mprotect">
        <title><function>&mac.mpo;_check_vnode_mprotect</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_mprotect</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>prot</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Mapped vnode</entry>
              </row>

              <row>
                <entry><parameter>prot</parameter></entry>
                <entry>Memory protections</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          set the specified memory protections on memory mapped from
          the vnode <parameter>vp</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-poll">
        <title><function>&mac.mpo;_check_vnode_poll</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_poll</function></funcdef>

            <paramdef>struct ucred
              *<parameter>active_cred</parameter></paramdef>
            <paramdef>struct ucred
              *<parameter>file_cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>active_cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>file_cred</parameter></entry>
                <entry>Credential associated with the <type>struct
                    file</type></entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Polled vnode</entry>
              </row>

              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label associated with
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to poll
          the vnode <parameter>vp</parameter>.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-rename-from">
        <title><function>&mac.mpo;_check_vnode_rename_from</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_vnode_rename_from</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>struct componentname
              *<parameter>cnp</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Directory vnode</entry>
              </row>

              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>dvp</parameter></entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Vnode to be renamed</entry>
              </row>

              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label associated with
                  <parameter>vp</parameter></entry>
              </row>

              <row>
                <entry><parameter>cnp</parameter></entry>
                <entry>Component name for
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          rename the vnode <parameter>vp</parameter> to something
          else.</para>
      </sect3>

      <sect3 id="mac-mpo-check-vnode-rename-to">
        <title><function>&mac.mpo;_check_vnode_rename_to</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_rename_to</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>dvp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>dlabel</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int <parameter>samedir</parameter></paramdef>
            <paramdef>struct componentname
              *<parameter>cnp</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Directory vnode</entry>
              </row>

              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label associated with
                  <parameter>dvp</parameter></entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Overwritten vnode</entry>
              </row>

              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label associated with
                  <parameter>vp</parameter></entry>
              </row>

              <row>
                <entry><parameter>samedir</parameter></entry>
                <entry>Boolean; <literal>1</literal> if the source and
                  destination directories are the same</entry>
              </row>

              <row>
                <entry><parameter>cnp</parameter></entry>
                <entry>Destination component name</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          rename to the vnode <parameter>vp</parameter>, into the
          directory <parameter>dvp</parameter>, or to the name
          represented by <parameter>cnp</parameter>.  If there is no
          existing file to overwrite, <parameter>vp</parameter> and
          <parameter>label</parameter> will be NULL.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-socket-listen">
        <title><function>&mac.mpo;_check_socket_listen</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_listen</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>socket</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>socket</parameter></entry>
                <entry>Object; socket</entry>
              </row>
              
              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>socket</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can listen on
          the passed socket.  Return <returnvalue>0</returnvalue> for
          success, or an <varname>errno</varname> value for failure.
          Suggested failure: <errorcode>EACCES</errorcode> for label
          mismatch, or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-lookup">
        <title><function>&mac.mpo;_check_vnode_lookup</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_lookup</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter></parameter>cred</paramdef>
            <paramdef>struct vnode
              *<parameter></parameter>dvp</paramdef>
            <paramdef>struct label
              *<parameter></parameter>dlabel</paramdef>
            <paramdef>struct componentname
              *<parameter>cnp</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>dvp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>cnp</parameter></entry>
                <entry>Component name being looked up</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can perform a
          lookup in the passed directory vnode for the passed name.
          Return <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-open">
        <title><function>&mac.mpo;_check_vnode_open</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_open</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int
              <parameter>acc_mode</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>acc_mode</parameter></entry>
                <entry>&man.open.2; access mode</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can perform an
          open operation on the passed vnode with the passed access
          mode.  Return <returnvalue>0</returnvalue> for success, or
          an errno value for failure.  Suggested failure:
          <errorcode>EACCES</errorcode> for label mismatch, or
          <errorcode>EPERM</errorcode> for lack of privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-readdir">
        <title><function>&mac.mpo;_check_vnode_readdir</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_readdir</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter></parameter>cred</paramdef>
            <paramdef>struct vnode
              *<parameter></parameter>dvp</paramdef>
            <paramdef>struct label
              *<parameter></parameter>dlabel</paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>dvp</parameter></entry>
                <entry>Object; directory vnode</entry>
              </row>
              
              <row>
                <entry><parameter>dlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>dvp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can perform a
          <function>readdir</function> operation on the passed
          directory vnode.  Return <returnvalue>0</returnvalue> for
          success, or an <varname>errno</varname> value for failure.
          Suggested failure: <errorcode>EACCES</errorcode> for label
          mismatch, or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-readlink">
        <title><function>&mac.mpo;_check_vnode_readlink</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_readlink</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can perform a
          <function>readlink</function> operation on the passed
          symlink vnode.  Return <returnvalue>0</returnvalue> for
          success, or an <varname>errno</varname> value for failure.
          Suggested failure: <errorcode>EACCES</errorcode> for label
          mismatch, or <errorcode>EPERM</errorcode> for lack of
          privilege.  This call may be made in a number of situations,
          including an explicit <function>readlink</function> call by
          the user process, or as a result of an implicit
          <function>readlink</function> during a name lookup by the
          process.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-revoke">
        <title><function>&mac.mpo;_check_vnode_revoke</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_revoke</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can revoke
          access to the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure. Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-setacl">
        <title><function>&mac.mpo;_check_vnode_setacl</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_setacl</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>acl_type_t
              <parameter>type</parameter></paramdef>
            <paramdef>struct acl
              *<parameter>acl</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>type</parameter></entry>
                <entry>ACL type</entry>
              </row>
              
              <row>
                <entry><parameter>acl</parameter></entry>
                <entry>ACL</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can set the
          passed ACL of passed type on the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-setextattr">
        <title><function>&mac.mpo;_check_vnode_setextattr</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_setextattr</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>int
              <parameter>attrnamespace</parameter></paramdef>
            <paramdef>const char
              *<parameter>name</parameter></paramdef>
            <paramdef>struct uio
              *<parameter>uio</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>attrnamespace</parameter></entry>
                <entry>Extended attribute namespace</entry>
              </row>
              
              <row>
                <entry><parameter>name</parameter></entry>
                <entry>Extended attribute name</entry>
              </row>
              
              <row>
                <entry><parameter>uio</parameter></entry>
                <entry>I/O structure pointer; see &man.uio.9;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can set the
          extended attribute of passed name and passed namespace on
          the passed vnode.  Policies implementing security labels
          backed into extended attributes may want to provide
          additional protections for those attributes.  Additionally,
          policies should avoid making decisions based on the data
          referenced from <parameter>uio</parameter>, as there is a
          potential race condition between this check and the actual
          operation.  The <parameter>uio</parameter> may also be
          <literal>NULL</literal> if a delete operation is being
          performed.  Return <returnvalue>0</returnvalue> for success,
          or an <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-setflags">
        <title><function>&mac.mpo;_check_vnode_setflags</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_setflags</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>u_long <parameter>flags</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>flags</parameter></entry>
                <entry>File flags; see &man.chflags.2;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can set the
          passed flags on the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-setmode">
        <title><function>&mac.mpo;_check_vnode_setmode</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_setmode</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>mode_t <parameter>mode</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>mode</parameter></entry>
                <entry>File mode; see &man.chmod.2;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can set the
          passed mode on the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-setowner">
        <title><function>&mac.mpo;_check_vnode_setowner</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_setowner</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
            <paramdef>uid_t <parameter>uid</parameter></paramdef>
            <paramdef>gid_t <parameter>gid</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>uid</parameter></entry>
                <entry>User ID</entry>
              </row>
              
              <row>
                <entry><parameter>gid</parameter></entry>
                <entry>Group ID</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can set the
          passed uid and passed gid as file uid and file gid on the
          passed vnode.  The IDs may be set to (<literal>-1</literal>)
          to request no update.  Return <returnvalue>0</returnvalue>
          for success, or an <varname>errno</varname> value for
          failure.  Suggested failure: <errorcode>EACCES</errorcode>
          for label mismatch, or <errorcode>EPERM</errorcode> for lack
          of privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-setutimes">
        <title><function>&mac.mpo;_check_vnode_setutimes</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_setutimes</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter></parameter>cred</paramdef>
            <paramdef>struct vnode
              *<parameter></parameter>vp</paramdef>
            <paramdef>struct label
              *<parameter></parameter>label</paramdef>
            <paramdef>struct timespec
              <parameter></parameter>atime</paramdef>
            <paramdef>struct timespec
              <parameter></parameter>mtime</paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vp</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>atime</parameter></entry>
                <entry>Access time; see &man.utimes.2;</entry>
              </row>
              
              <row>
                <entry><parameter>mtime</parameter></entry>
                <entry>Modification time; see &man.utimes.2;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can set the
          passed access timestamps on the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-proc-sched">
        <title><function>&mac.mpo;_check_proc_sched</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_proc_sched</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>ucred</parameter></paramdef>
            <paramdef>struct proc
              *<parameter>proc</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>proc</parameter></entry>
                <entry>Object; process</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can change the
          scheduling parameters of the passed process.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          <errorcode>EPERM</errorcode> for lack of privilege, or
          <errorcode>ESRCH</errorcode> to limit visibility.</para>
        
        <para>See &man.setpriority.2; for more information.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-proc-signal">
        <title><function>&mac.mpo;_check_proc_signal</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_proc_signal</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct proc
              *<parameter>proc</parameter></paramdef>
            <paramdef>int <parameter>signal</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>proc</parameter></entry>
                <entry>Object; process</entry>
              </row>
              
              <row>
                <entry><parameter>signal</parameter></entry>
                <entry>Signal; see &man.kill.2;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can deliver the
          passed signal to the passed process.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          <errorcode>EPERM</errorcode> for lack of privilege, or
          <errorcode>ESRCH</errorcode> to limit visibility.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-vnode-stat">
        <title><function>&mac.mpo;_check_vnode_stat</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_vnode_stat</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>label</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Object; vnode</entry>
              </row>
              
              <row>
                <entry><parameter>label</parameter></entry>
                <entry>Policy label for
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential can
          <function>stat</function> the passed vnode.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
        
        <para>See &man.stat.2; for more information.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-ifnet-transmit">
        <title><function>&mac.mpo;_check_ifnet_transmit</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_ifnet_transmit</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct ifnet
              *<parameter>ifnet</parameter></paramdef>
            <paramdef>struct label
              *<parameter>ifnetlabel</parameter></paramdef>
            <paramdef>struct mbuf
              *<parameter>mbuf</parameter></paramdef>
            <paramdef>struct label
              *<parameter>mbuflabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>ifnet</parameter></entry>
                <entry>Network interface</entry>
              </row>
              
              <row>
                <entry><parameter>ifnetlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>ifnet</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>mbuf</parameter></entry>
                <entry>Object; mbuf to be sent</entry>
              </row>
              
              <row>
                <entry><parameter>mbuflabel</parameter></entry>
                <entry>Policy label for
                  <parameter>mbuf</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the network interface can transmit the
          passed mbuf.  Return <returnvalue>0</returnvalue> for
          success, or an <varname>errno</varname> value for failure.
          Suggested failure: <errorcode>EACCES</errorcode> for label
          mismatch, or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-cred-check-socket-deliver">
        <title><function>&mac.mpo;_check_socket_deliver</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_deliver</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct ifnet
              *<parameter>ifnet</parameter></paramdef>
            <paramdef>struct label
              *<parameter>ifnetlabel</parameter></paramdef>
            <paramdef>struct mbuf
              *<parameter>mbuf</parameter></paramdef>
            <paramdef>struct label
              *<parameter>mbuflabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
              
              <row>
                <entry><parameter>ifnet</parameter></entry>
                <entry>Network interface</entry>
              </row>
              
              <row>
                <entry><parameter>ifnetlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>ifnet</parameter></entry>
              </row>
              
              <row>
                <entry><parameter>mbuf</parameter></entry>
                <entry>Object; mbuf to be delivered</entry>
              </row>
              
              <row>
                <entry><parameter>mbuflabel</parameter></entry>
                <entry>Policy label for
                  <parameter>mbuf</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the socket may receive the datagram
          stored in the passed mbuf header.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failures: <errorcode>EACCES</errorcode> for label mismatch,
          or <errorcode>EPERM</errorcode> for lack of
          privilege.</para>
      </sect3>
      
      <sect3 id="mac-mpo-check-socket-visible">
        <title><function>&mac.mpo;_check_socket_visible</function></title>
        
        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_socket_visible</function></funcdef>
            
            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct socket
              *<parameter>so</parameter></paramdef>
            <paramdef>struct label
              *<parameter>socketlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
        
        <informaltable>
          <tgroup cols="3">
            &mac.thead;
            
            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
                <entry>Immutable</entry>
              </row>
              
              <row>
                <entry><parameter>so</parameter></entry>
                <entry>Object; socket</entry>
              </row>
              
              <row>
                <entry><parameter>socketlabel</parameter></entry>
                <entry>Policy label for
                  <parameter>so</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        
        <para>Determine whether the subject credential cred can "see"
          the passed socket (<parameter>socket</parameter>) using
          system monitoring functions, such as those employed by
            &man.netstat.8; and &man.sockstat.1;.  Return
          <returnvalue>0</returnvalue> for success, or an
          <varname>errno</varname> value for failure.  Suggested
          failure: <errorcode>EACCES</errorcode> for label mismatches,
          <errorcode>EPERM</errorcode> for lack of privilege, or
          <errorcode>ESRCH</errorcode> to hide visibility.</para>
      </sect3>

      <sect3 id="mac-mpo-check-system-acct">
        <title><function>&mac.mpo;_check_system_acct</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_system_acct</function></funcdef>

            <paramdef>struct ucred
              *<parameter>ucred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>vlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>ucred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Accounting file; &man.acct.5;</entry>
              </row>

              <row>
                <entry><parameter>vlabel</parameter></entry>
                <entry>Label associated with
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          enable accounting, based on its label and the label of the
          accounting log file.</para>
      </sect3>

      <sect3 id="mac-mpo-check-system-nfsd">
        <title><function>&mac.mpo;_check_system_nfsd</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_system_nfsd</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to call
            &man.nfssvc.2;.</para>
      </sect3>

      <sect3 id="mac-mpo-check-system-reboot">
        <title><function>&mac.mpo;_check_system_reboot</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_system_reboot</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>int <parameter>howto</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>howto</parameter></entry>
                <entry><parameter>howto</parameter> parameter from
                    &man.reboot.2;</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to
          reboot the system in the specified manner.</para>
      </sect3>

      <sect3 id="mac-mpo-check-system-settime">
        <title><function>&mac.mpo;_check_system_settime</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_system_settime</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the user should be allowed to set the
          system clock.</para>
      </sect3>

      <sect3 id="mac-mpo-check-system-swapon">
        <title><function>&mac.mpo;_check_system_swapon</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_system_swapon</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>struct vnode
              *<parameter>vp</parameter></paramdef>
            <paramdef>struct label
              *<parameter>vlabel</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>vp</parameter></entry>
                <entry>Swap device</entry>
              </row>

              <row>
                <entry><parameter>vlabel</parameter></entry>
                <entry>Label associated with
                  <parameter>vp</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to add
          <parameter>vp</parameter> as a swap device.</para>
      </sect3>

      <sect3 id="mac-mpo-check-system-sysctl">
        <title><function>&mac.mpo;_check_system_sysctl</function></title>

        <funcsynopsis>
          <funcprototype>
            <funcdef>int
              <function>&mac.mpo;_check_system_sysctl</function></funcdef>

            <paramdef>struct ucred
              *<parameter>cred</parameter></paramdef>
            <paramdef>int *<parameter>name</parameter></paramdef>
            <paramdef>u_int *<parameter>namelen</parameter></paramdef>
            <paramdef>void *<parameter>old</parameter></paramdef>
            <paramdef>size_t
              *<parameter>oldlenp</parameter></paramdef>
            <paramdef>int <parameter>inkernel</parameter></paramdef>
            <paramdef>void *<parameter>new</parameter></paramdef>
            <paramdef>size_t <parameter>newlen</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <informaltable>
          <tgroup cols="3">
            &mac.thead;

            <tbody>
              <row>
                <entry><parameter>cred</parameter></entry>
                <entry>Subject credential</entry>
              </row>

              <row>
                <entry><parameter>name</parameter></entry>
                <entry morerows="3">See &man.sysctl.3;</entry>
              </row>

              <row>
                <entry><parameter>namelen</parameter></entry>
              </row>

              <row>
                <entry><parameter>old</parameter></entry>
              </row>

              <row>
                <entry><parameter>oldlenp</parameter></entry>
              </row>

              <row>
                <entry><parameter>inkernel</parameter></entry>
                <entry>Boolean; <literal>1</literal> if called from
                  kernel</entry>
              </row>

              <row>
                <entry><parameter>new</parameter></entry>
                <entry morerows="1">See &man.sysctl.3;</entry>
              </row>

              <row>
                <entry><parameter>newlen</parameter></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>Determine whether the subject should be allowed to make
          the specified &man.sysctl.3; transaction.</para>
      </sect3>
    </sect2>
    
    <sect2 id="mac-label-management">
      <title>Label Management Calls</title>
      
      <para>Relabel events occur when a user process has requested
        that the label on an object be modified.  A two-phase update
        occurs: first, an access control check will be performed to
        determine if the update is both valid and permitted, and then
        the update itself is performed via a separate entry point.
        Relabel entry points typically accept the object, object label
        reference, and an update label submitted by the process.
        Memory allocation during relabel is discouraged, as relabel
        calls are not permitted to fail (failure should be reported
        earlier in the relabel check).</para>
      
    </sect2>
  </sect1>
  
  <sect1 id="mac-userland-arch">
    <title>Userland Architecture</title>
    
    <para>The TrustedBSD MAC Framework includes a number of
      policy-agnostic elements, including MAC library interfaces
      for abstractly managing labels, modifications to the system
      credential management and login libraries to support the
      assignment of MAC labels to users, and a set of tools to
      monitor and modify labels on processes, files, and network
      interfaces.  More details on the user architecture will
      be added to this section in the near future.</para>

    <sect2 id="mac-userland-labels">
      <title>APIs for Policy-Agnostic Label Management</title>

      <para>The TrustedBSD MAC Framework provides a number of
	library and system calls permitting applications to
	manage MAC labels on objects using a policy-agnostic
	interface.  This permits applications to manipulate
	labels for a variety of policies without being
	written to support specific policies.  These interfaces
	are used by general-purpose tools such as &man.ifconfig.8;,
	&man.ls.1; and &man.ps.1; to view labels on network
	interfaces, files, and processes.  The APIs also support
	MAC management tools including &man.getfmac.8;,
	&man.getpmac.8;, &man.setfmac.8;, &man.setfsmac.8;,
	and &man.setpmac.8;.  The MAC APIs are documented in
	&man.mac.3;.</para>

      <para>Applications handle MAC labels in two forms: an
	internalized form used to return and set labels on
	processes and objects (<literal>mac_t</literal>),
	and externalized form based on C strings appropriate for
	storage in configuration files, display to the user, or
	input from the user.  Each MAC label contains a number of
	elements, each consisting of a name and value pair.
	Policy modules in the kernel bind to specific names
	and interpret the values in policy-specific ways.  In
	the externalized string form, labels are represented
	by a comma-delimited list of name and value pairs separated
	by the <literal>/</literal> character.  Labels may be
	directly converted to and from text using provided APIs;
	when retrieving labels from the kernel, internalized
	label storage must first be prepared for the desired
	label element set.  Typically, this is done in one of
	two ways: using &man.mac.prepare.3; and an arbitrary
	list of desired label elements, or one of the variants
	of the call that loads a default element set from the
	&man.mac.conf.5; configuration file.  Per-object
	defaults permit application writers to usefully display
	labels associated with objects without being aware of
	the policies present in the system.</para>

      <note><para>Currently, direct manipulation of label elements
	other than by conversion to a text string, string editing,
	and conversion back to an internalized label is not supported
	by the MAC library.  Such interfaces may be added in the
	future if they prove necessary for application
	writers.</para></note>
    </sect2>

    <sect2 id="mac-userland-credentials">
      <title>Binding of Labels to Users</title>

      <para>The standard user context management interface,
	&man.setusercontext.3;, has been modified to retrieve
	MAC labels associated with a user's class from
	&man.login.conf.5;.  These labels are then set along
	with other user context when either
	<literal>LOGIN_SETALL</literal> is specified, or when
	<literal>LOGIN_SETMAC</literal> is explicitly
	specified.</para>

      <note><para>It is expected that, in a future version of FreeBSD,
	the MAC label database will be separated from the
	<filename>login.conf</filename> user class abstraction,
	and be maintained in a separate database.  However, the
	&man.setusercontext.3; API should remain the same
	following such a change.</para></note>
    </sect2>
  </sect1>

  <sect1 id="mac-conclusion">
    <title>Conclusion</title>
    
    <para>The TrustedBSD MAC framework permits kernel modules to
      augment the system security policy in a highly integrated
      manner.  They may do this based on existing object properties,
      or based on label data that is maintained with the assistance of
      the MAC framework.  The framework is sufficiently flexible to
      implement a variety of policy types, including information flow
      security policies such as MLS and Biba, as well as policies
      based on existing BSD credentials or file protections.  Policy
      authors may wish to consult this documentation as well as
      existing security modules when implementing a new security
      service.</para>
  </sect1>
</chapter>

<!--
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "part" "chapter")
     End:
-->
