aboutsummaryrefslogtreecommitdiff
path: root/zh_CN.GB2312/books/arch-handbook/mac
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2006-03-15 19:54:49 +0000
committerXin LI <delphij@FreeBSD.org>2006-03-15 19:54:49 +0000
commitd6aa1908eb7dac606d9c0c4f4c46abb47f205022 (patch)
tree8fefbf336a4556ffff6e7e3e7748f1986b8f7d8b /zh_CN.GB2312/books/arch-handbook/mac
parent639205b60c99afefb07be3bccecf1b6eb04c0629 (diff)
Notes
Diffstat (limited to 'zh_CN.GB2312/books/arch-handbook/mac')
-rw-r--r--zh_CN.GB2312/books/arch-handbook/mac/chapter.sgml7259
1 files changed, 7259 insertions, 0 deletions
diff --git a/zh_CN.GB2312/books/arch-handbook/mac/chapter.sgml b/zh_CN.GB2312/books/arch-handbook/mac/chapter.sgml
new file mode 100644
index 0000000000..f8f59862ab
--- /dev/null
+++ b/zh_CN.GB2312/books/arch-handbook/mac/chapter.sgml
@@ -0,0 +1,7259 @@
+<!--
+ Copyright (c) 2002-2005 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.
+
+ Original Revision: 1.43
+ $FreeBSD$
+-->
+
+<chapter id="mac">
+ <chapterinfo>
+ <authorgroup>
+ <author>
+ <firstname>Chris</firstname>
+ <surname>Costello</surname>
+
+ <affiliation>
+ <orgname>TrustedBSD 项目</orgname>
+ <address><email>chris@FreeBSD.org</email></address>
+ </affiliation>
+ </author>
+
+ <author>
+ <firstname>Robert</firstname>
+ <surname>Watson</surname>
+
+ <affiliation>
+ <orgname>TrustedBSD 项目</orgname>
+ <address><email>rwatson@FreeBSD.org</email></address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <authorgroup>
+ <author>
+ &author.cn.coolcoold;
+ <contrib>&cnproj.translated.by;</contrib>
+ </author>
+ </authorgroup>
+
+ </chapterinfo>
+
+ <title>TrustedBSD MAC 框架</title>
+
+ <sect1 id="mac-copyright">
+ <title>MAC 文档版权声明</title>
+
+ <para>本文档是作为 DARPA CHATS 研究计划的一部分,由供职于 Security Research Division of Network Associates
+ 公司Safeport Network Services and Network Associates Laboratories 的Chris Costello依据 DARPA/SPAWAR 合同
+ N66001-01-C-8035 (<quote>CBOSS</quote>),为 FreeBSD 项目编写的。</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>
+
+ <important><para>本文中许可证的非官方中文翻译仅供参考,
+ 不作为判定任何责任的依据。如与英文原文有出入,则以英文原文为准。</para></important>
+
+ <para>在满足下列许可条件的前提下,允许再分发或以源代码 (SGML DocBook) 或 “编译” (SGML, HTML, PDF, PostScript, RTF 等)
+ 的经过修改或未修改的形式:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>再分发源代码 (SGML DocBook) 必须不加修改的保留上述版权告示、本条件清单和下述弃权书作为该文件的最先若干行。</para>
+ </listitem>
+
+ <listitem>
+ <para>再分发编译的形式 (转换为其它DTD、 PDF、 PostScript、 RTF 或其它形式),必须将上述版权告示、
+ 本条件清单和下述弃权书复制到与分发品一同提供的文件,以及其它材料中。</para>
+ </listitem>
+ </orderedlist>
+
+ <important>
+ <para>本文档由 NETWORKS ASSOCIATES TECHNOLOGY, INC “按现状条件”提供,并在此明示不提供任何明示或暗示的保障,
+ 包括但不限于对商业适销性、对特定目的的适用性的暗示保障。任何情况下,
+ NETWORKS ASSOCIATES TECHNOLOGY, INC 均不对任何直接、 间接、 偶然、 特殊、 惩罚性的,
+ 或必然的损失 (包括但不限于替代商品或服务的采购、 使用、 数据或利益的损失或营业中断) 负责,
+ 无论是如何导致的并以任何有责任逻辑的, 无论是否是在本文档使用以外以任何方式产生的契约、严格责任或是民事侵权行为(包括疏忽或其它)中的,
+ 即使已被告知发生该损失的可能性。</para>
+ </important>
+ </sect1>
+
+ <sect1 id="mac-synopsis">
+ <title>术语解析</title>
+
+ <para>FreeBSD 以一个内核安全扩展性框架(TrustedBSD MAC 框架)的方式,为若干强制访问控制策略(也称“集权式访问控制策略”)
+ 提供试验性支持。MAC 框架是一个插入式的访问控制框架,允许新的安全策略更方便地融入内核:安全策略可以静态链入内核,也可以
+ 在引导时加载,甚至在运行时动态加载。该框架所提供的标准化接口,使得运行在其上的安全策略模块能对系统对象的安全属性进行诸如标记等一系列操作。
+ MAC 框架的存在,简化了这些操作在策略模块中的实现,从而显著降低了新安全策略模块的开发难度。</para>
+
+ <para>本章将介绍 MAC 策略框架,为读者提供一个示例性的 MAC 策略模块文档。</para>
+ </sect1>
+
+
+ <sect1 id="mac-introduction">
+ <title>概述</title>
+
+ <para>TrustedBSD MAC 框架提供的机制,允许在其上运行的内核模块在内核编译或者运行时,对内核的访问控制模型进行扩展。
+ 新的系统安全策略作为一个内核模块实现,并被链接到内核中;如果系统中同时存在多个安全策略模块,则它们的决策结果将以某种确定的方式组合。
+ 为了给简化新安全策略的开发,MAC 向上提供了大量用于访问控制的基础设施,特别是,对临时的或者持久的、策略无关的对象安全标记的支持。
+ 该支持目前仍是试验性质的。</para>
+
+ <para>本章所提供的信息不仅将使在 MAC 使能环境下工作的潜在用户受益,
+ 也可以为需要了解 MAC 框架是如何支持对内核访问控制进行扩展的策略模块开发人员所用。</para>
+ </sect1>
+
+ <sect1 id="mac-background">
+ <title>安全策略背景知识</title>
+
+ <para>强制访问控制(简称 MAC),是指由操作系统强制实施的一组针对用户的访问控制策略。
+ 在某些情况下,强制访问控制的策略可能会与自主访问控制(简称 DAC)所提供的保护措施发生冲突,
+ 后者是用来向非管理员用户对数据采取保护措施提供支持的。在传统的 UNIX 系统中,
+ DAC 保护措施包括文件访问模式和访问控制列表;而 MAC 则提供进程控制和防火墙等。
+ 操作系统设计者和安全机制研究人员对许多经典的 MAC 安全策略作了形式化的表述,比如,
+ 多级安全(MLS)机密性策略,Biba 完整性策略,基于角色的访问控制策略(RBAC),域和型裁决策略(DTE),以及型裁决策略(TE)。
+ 安全策略的形式化表述被称为安全模型。每个模型根据一系列条件做出安全相关的决策,这些条件包括,
+ 用户的身份、角色和安全信任状,以及对象的安全标记(用来代表该对象数据的机密性/完整性级别)。</para>
+
+ <para>TrustedBSD MAC 框架所提供的对策略模块的支持,不仅可以用来实现上述所有策略,
+ 还能用于实现其他利用已有安全属性(如,用户和组ID、文件扩展属性等)决策的系统安全强化策略。
+ 此外,因为具体策略模块在访问授权方面所拥有的高度灵活性和自主性,所以MAC 框架同样可以用来实现完全自主式的安全策略.</para>
+ </sect1>
+
+ <sect1 id="mac-framework-kernel-arch">
+ <title>MAC 框架的内核体系结构</title>
+
+ <para>TrustedBSD MAC 框架为大多数的访问控制模块提供基本设施,允许它们以内核模块的形式灵活地扩展系统中实施的安全策略。
+ 如果系统中同时加载了多个策略,MAC 框架将负责将各个策略的授权结果以一种(某种程度上)有意义的方式组合,形成最后的决策。</para>
+
+ <sect2 id="mac-framework-kernel-arch-elements">
+ <title>内核元素</title>
+
+ <para>MAC 框架由下列内核元素组成:</para>
+
+ <itemizedlist>
+ <listitem><para>框架管理接口</para></listitem>
+ <listitem><para>并发与同步原语</para></listitem>
+ <listitem><para>策略注册</para></listitem>
+ <listitem><para>内核对象的扩展性安全标记</para></listitem>
+ <listitem><para>策略入口函数的组合操作</para></listitem>
+ <listitem><para>标记管理原语</para></listitem>
+ <listitem><para>由内核服务调用的入口函数 API</para></listitem>
+ <listitem><para>策略模块的入口函数 API</para></listitem>
+ <listitem><para>入口函数的实现(包括策略生命周期管理、标记管理和访问控制检查三部分)</para></listitem>
+ <listitem><para>管理策略无关标记的系统调用</para></listitem>
+ <listitem><para>复用的<function>mac_syscall()</function> 系统调用</para></listitem>
+ <listitem><para>以 MAC 的策略加载模块形式实现的各种安全策略</para></listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-management">
+ <title>框架管理接口</title>
+
+ <para>对 TrustedBSD MAC 框架进行直接管理的方式有三种:通过 sysctl 子系统、通过 loader 配置, 或者使用系统调用。</para>
+
+ <para>多数情况下,与同一个内核内部变量相关联的 sysctl 变量和 loader 参数的名字是相同的,
+ 通过设置它们,可以控制保护措施的实施细节,比如,某个策略在各个内核子系统中的实施与否等等。
+ 另外,如果在内核编译时选择支持 MAC 调试选项,内核将维护若干计数器以跟踪标记的分配使用情况。
+ 通常不建议在实用环境下通过在不同子系统上设置不同的变量或参数来实施控制,因为这种方法将会作用于系统中所有的活跃策略。
+ 如果希望对具体策略实施管理而不相影响其他活跃策略,则应当使用策略级别的控制,因为这种方法的控制粒度更细,
+ 并能更好地保证策略模块的功能一致性。</para>
+
+ <para>与其他内核模块一样,系统管理员可以通过系统的模块管理系统调用和其他系统接口,包括 boot loader 变量,对策略模块执行加载与卸载操作;
+ 策略模块可以在加载时,设置加载标志,来指示系统对其加载、卸载操作进行相应控制,比如阻止非期望的卸载操作。</para>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-synchronization">
+ <title>策略链表的并发与同步</title>
+
+ <para>在运行时,系统中活跃的策略集合可能发生变化,然而对策略入口函数的使用操作并不是原子性的,因此,当某一个入口函数正被使用时,
+ 系统需要提供额外的同步机制来阻止对该策略模块的加载与卸载,以确保当前活跃的策略集合不会在此过程中发生改变。
+ 通过使用"框架忙”计数器,就可以做到这一点:一旦某个入口函数被调用,计数器的值被增加1;而每当一个入口函数调用结束时,计数器的值被减少1。
+ 检查计数器的值,如果其值为正,框架将阻止对策略链表的修改操作,请求操作的线程将被迫进入睡眠,直到计数器的值重新减少到0为止。
+ 计数器本身由一个互斥锁保护,同时结合一个条件变量(用于唤醒等待对策略链表进行修改操作的睡眠线程)。
+ 采用这种同步模型的一个副作用是,在同一个策略模块内部,允许嵌套地调用框架,不过这种情况其实很少出现。</para>
+
+ <para>为了减少由于采用计数器引入的额外开销,设计者采用了各种优化措施。其中包括,当策略链表为空或者其中仅含有静态表项
+ (那些只能在系统运行之前加载而且不能动态卸载的策略)时,框架不对计数器进行操作,其值总是为0,从而将此时的同步开销减到0。
+ 另一个极端的办法是,使用一个编译选项来禁止在运行时对加载的策略链表进行修改,此时不再需要对策略链表的使用进行同步保护。</para>
+
+ <para>因为 MAC 框架不允许在某些入口函数之内阻塞,所以不能使用普通的睡眠锁。
+ 故而,加载或卸载操作可能会为等待框架空闲而被阻塞相当长的一段时间。</para>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-label-synchronization">
+ <title>标记同步</title>
+
+ <para>MAC 框架必须对其负责维护的安全属性标记的存储访问提供同步保护。下列两种情形,可能导致对安全属性标记的不一致访问:
+ 第一,作为安全属性标记的持有者,内核对象本身可能同时被多个线程访问;第二,MAC 框架代码是可重入的,
+ 即允许多个线程同时在框架内执行。通常,MAC 框架使用内核对象数据上已有的内核同步机制来保护该其上附加的 MAC 安全标记。
+ 例如,套接字上的 MAC 标记由已有的套接字互斥锁保护。类似的,对于安全标记的并发访问的过程与对其所在对象进行的并发访问在语义上是一样的,
+ 例如,信任状安全标记,将保持与该数据结构中其他内容一致的"写时复制"的更新过程。
+ MAC 框架在引用一个内核对象时,将首先对访问该对象上的标记需要用到的锁进行断言。
+ 策略模块的编写者必须了解这些同步语义, 因为它们可能会限制对安全标记所能进行的访问类型。
+ 举个例子,如果通过入口函数传给策略模块的是对某个信任状的只读引用,那么在策略内部,只能读该结构对应的标记状态。</para>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-policy-synchronization">
+ <title>策略间的同步与并发</title>
+
+ <para>FreeBSD 内核是一个可抢占式的内核,因此,作为内核一部分的策略模块也必须是可重入的,也就是说,
+ 在开发策略模块时必须假设多个内核线程可以同时通过不同的入口函数进入该模块。
+ 如果策略模块使用可被修改的内核状态,那么还需要在策略内部使用恰当的同步原语,确保在策略内部的多个线程不会因此观察到不一致的内核状态,
+ 从而避免由此产生的策略误操作。为此,策略可以使用 FreeBSD 现有的同步原语,包括互斥锁、睡眠锁、条件变量和计数信号量。
+ 对这些同步原语的使用必须慎重,需要特别注意两点:第一,保持现有的内核上锁次序;
+ 第二,在非睡眠的入口函数之内不要使用互斥锁和唤醒操作。</para>
+
+ <para>为避免违反内核上锁次序或造成递归上锁,策略模块在调用其他内核子系统之前,通常要释放所有在策略内部申请的锁。
+ 这样做的结果是,在全局上锁次序形成的拓朴结构中,策略内部的锁总是作为叶子节点,
+ 从而保证了这些锁的使用不会导致由于上锁次序混乱造成的死锁。</para>
+
+ <sect2 id="mac-framework-kernel-arch-registration">
+ <title>策略注册</title>
+
+ <para>为了记录当前使用的策略模块集合,MAC 框架维护两个链表:一个静态链表和一个动态链表。
+ 两个链表的数据结构和操作基本相同,只是动态链表还额外使用了一个"引用计数"以同步对其的访问操作。
+ 当包含 MAC 框架策略的内核模块被加载时,该策略模块会通过 <literal>SYSINIT</literal> 调用一个注册函数;
+ 相对应的,每当一个策略模块被卸载,<literal>SYSINIT</literal> 也会调用一个注销函数。
+ 只有当遇到下列情况之一时,注册过程才会失败: 一个策略模块被加载多次,或者系统资源不足不能满足注册过程的需要(
+ 例如,策略模块需要对内核对象添加标记而可用资源不足),或者其他的策略加载前提条件不满足(有些策略要求只能在系统引导之前加载)。
+ 类似的,如果一个策略被标记为不可卸载的,对其调用注销过程将会失败。</para>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-entrypoints">
+ <title>入口函数</title>
+
+ <para>内核服务与 MAC 框架之间进行交互有两种途径:
+ 一是,内核服务调用一系列 API 通知 MAC 框架安全事件的发生;
+ 二是,内核服务向 MAC 框架提供一个指向安全对象的策略无关安全标记数据结构的指针。
+ 标记指针由 MAC 框架经由标记管理入口函数进行维护,
+ 并且,只要对管理相关对象的内核子系统稍作修改,就可以允许 MAC 框架向策略模块提供标记服务。
+ 例如,在进程、进程信任状、套接字、管道、Mbuf、网络接口、IP 重组队列和其他各种安全相关的数据结构中均增加了指向安全标记的指针。
+ 另外,当需要做出重要的安全决策时,内核服务也会调用 MAC 框架,以便各个策略模块根据其自己的标准(可以使用存储在安全标记中的数据)完善这些决策。
+ 绝大多数安全相关的关键决策是显式的访问控制检查;
+ 也有少数涉及更加一般的决策函数,比如,套接字的数据包匹配和程序执行时刻的标记转换。</para>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-composition">
+ <title>策略组合</title>
+
+ <para>如果内核中同时加载了多个策略模块,这些策略的决策结果将由框架使用一个合成运算子来进行组合汇总,得出最终的结果。
+ 目前,该算子是硬编码的,并且只有当所有的活跃策略均对请求表示同意时才会返回成功。
+ 由于各个策略返回的出错条件可能并不相同(成功、访问被拒绝、请求对象不存在等等),
+ 需要使用一个选择子先从各个策略返回的错误条件集合中选择出一个作为最终返回结果。
+ 一般情况下,与“访问被拒绝”相比,将更倾向于选择“请求对象不存在”。
+ 尽管不能从理论上保证合成结果的有效性与安全性,但试验结果表明,对于许多实用的策略集合来说,事实的确如此。
+ 例如,传统的可信系统常常采用类似的方法对多个安全策略进行组合。</para>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-labels">
+ <title>标记支持</title>
+
+ <para>与许多需要给对象添加安全标记的访问控制扩展一样,MAC 框架为各种用户可见的对象提供了一组用于管理策略无关标记的系统调用。
+ 常用的标记类型有,partition标识符、机密性标记、完整性标记、区间(非等级类别)、域、角色和型。
+ “策略无关”的意思是指,标记的语法与使用它的具体策略模块无关,而同时策略模块能够完全独立地定义和使用与对象相关联的元数据的语义。
+ 用户应用程序提供统一格式的基于字符串的标记,由使用它的策略模块负责解析其内在含义并决定其外在表示。
+ 如果需要,应用程序可以使用多重标记元素。</para>
+
+ <para>内存中的标记实例被存放在由 slab 分配的<structname>struct label</structname>数据结构中。
+ 该结构是一个固定长度的数组,每个元素是由一个 <literal>void *</literal>
+ 指针和一个 <literal>long</literal>组成的联合结构。
+ 申请标记存储的策略模块在向 MAC 注册时,将被分配一个“slot”值,作为框架分配给其使用的策略标记元素在整个标记存储结构中的位置索引。
+ 而所分配的存储空间的语义则完全由该策略模块来决定:MAC 框架向策略模块提供了一系列入口函数用于对内核对象生命周期的各种事件进行控制,包括,
+ 对象的初始化、标记的关联/创建和对象的注销。使用这些接口,可以实现诸如访问计数等存储模型。
+ MAC 框架总是给入口函数传入一个指向相关对象的指针和一个指向该对象标记的指针,因此,策略模块能够直接访问标记而无需知悉该对象的内部结构。
+ 唯一的例外是进程信任状结构,指向其标记的指针必须由策略模块手动解析计算。今后的 MAC 框架实现可能会对此进行改进。</para>
+
+ <para>初始化入口函数通常有一个睡眠标志位,用来表明一个初始化操作是否允许中途睡眠等待;
+ 如果不允许,则可能会失败返回,并要求撤销此次标记分配操作(乃至对象分配操作)。
+ 例如,如果在网络栈上处理中断时因为不允许睡眠或者调用者持有一个互斥锁,就可能出现这种情况。
+ 考虑到在处理中的网络数据包(Mbufs)上维护标记的性能损失太大,策略必须就自己对 Mbuf 进行标记的要求向 MAC 框架做出特别声明。
+ 动态加载到系统中而又使用标记的策略必须为处理未被其初始化函数处理过的对象作好准备,
+ 这些对象在策略加载之前就已经存在,故而无法在初始化时调用策略的相关函数进行处理。
+ MAC 框架向策略保证,没有被初始化的标记 slot 的值必为0或者 NULL,策略可以借此检测到未初始化的标记。
+ 需要注意的是,因为对 Mbuf 标记的存储分配是有条件的,因此需要使用其标记的动态加载策略还可能需要处理 Mbuf 中值为 NULL 的标记指针。</para>
+
+ <para>对于文件系统对象的标记,MAC 框架在文件的扩展属性中为其分配永久存储。
+ 只要可能,扩展属性的原子化的事务操作就被用于保证对 vnode 上安全标记的复合更新操作的一致性--目前,该特性只被 UFS2 文件系统支持。
+ 为了实现细粒度的文件系统对象标记(即每个文件系统对象一个标记),策略编写者可能选择使用一个(或者若干)扩展属性块。
+ 为了提高性能, vnode 数据结构中有一个标记 (<literal>v_label</literal>)字段,用作磁盘标记的缓冲;
+ vnode 结构实例化时,策略可以将标记值装入该缓冲,并在需要时对其进行更新。
+ 如此,不必在每次进行访问控制检查时,均无条件地访问磁盘上的扩展属性。</para>
+
+ <note><para>目前,如果一个使用标记的策略允许被动态卸载,则卸载该模块之后,其状态 slot 尚无法被系统回收重用,
+ 由此导致了 MAC 框架对标记策略卸载-重载操作数目上的严格限制。</para></note>
+ </sect2>
+
+ <sect2 id="mac-framework-kernel-arch-syscalls">
+ <title>相关系统调用</title>
+
+ <para>MAC 框架向应用程序提供了一组系统调用:其中大多数用于向进行查询和修改策略无关标记操作的应用 API提供支持。</para>
+
+ <para>这些标记管理系统调用,接受一个标记描述结构, <structname>struct mac</structname>,作为输入参数。
+ 这个结构的主体是一个数组,其中每个元素包含了一个应用级的 MAC 标记形式。每个元素又由两部分组成:一个字符串名字,和其对应的值。
+ 每个策略可以向系统声明一个特定的元素名字,这样一来,如果需要,就可以将若干个相互独立的元素作为一个整体进行处理。
+ 策略模块经由入口函数,在内核标记和用户提供的标记之间作翻译转换的工作,这种实现提供了标记元素语义上的高度灵活性。
+ 标记管理系统调用通常有对应的库函数包装,这些包装函数可以提供内存分配和错误处理功能,从而简化了用户应用程序的标记管理工作。</para>
+
+ <para>目前的FreeBSD 内核提供了下列 MAC 相关的系统调用:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><function>mac_get_proc()</function> 用于查询当前进程的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_set_proc()</function> 用于请求改变当前进程的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_get_fd()</function> 用于查询由文件描述符所引用的对象( 文件、
+ 套接字、 管道文件等等) 的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_get_file()</function> 用于查询由文件系统路径所描述的对象的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_set_fd()</function> 用于请求改变由文件描述符所引用的对象(
+ 文件、套接字、 管道文件等等) 的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_set_file()</function> 用于请求改变由文件系统路径所描述的对象的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_syscall()</function> 通过复用该系统调用,策略模块能够在不修改系统调用表的前提下创建新的系统调用;
+ 其调用参数包括:目标策略名字、 操作编号和将被该策略内部使用的参数。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_get_pid()</function> 用于查询由进程号指定的另一个进程的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_get_link()</function> 与
+ <function>mac_get_file()</function> 功能相同,
+ 只是当路径参数的最后一项为符号链接时,
+ 前者将返回该符号链接的安全标记,
+ 而后者将返回其所指文件的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_set_link()</function> 与
+ <function>mac_set_file()</function> 功能相同,
+ 只是当路径参数的最后一项为符号链接时,
+ 前者将设置该符号链接的安全标记,
+ 而后者将设置其所指文件的安全标记。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_execve()</function> 与
+ <function>execve()</function> 功能类似,
+ 只是前者还可以在开始执行一个新程序时,根据传入的请求参数,设置执行进程的安全标记。
+ 由于执行一个新程序而导致的进程安全标记的改变,被称为“转换”。</para>
+ </listitem>
+
+ <listitem>
+ <para><function>mac_get_peer()</function>,
+ 通过一个套接字选项自动实现,
+ 用于查询一个远程套接字对等实体的安全标记。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>除了上述系统调用之外,
+ 也可以通过 <literal>SIOCSIGMAC</literal> 和 <literal>SIOCSIFMAC</literal>
+ 网络接口的 ioctl 类系统调用来查询和设置网络接口的安全标记。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mac-policy-architecture">
+ <title>MAC策略模块体系结构</title>
+
+ <para>安全策略可以直接编入内核,也可以编译成独立的内核模块,在系统引导时或者运行时使用模块加载命令加载。
+ 策略模块通过一组预先定义好的入口函数与系统交互。通过它们,策略模块能够掌握某些系统事件的发生,并且在必要的时候影响系统的访问控制决策。
+ 每个策略模块包含下列组成部分:</para>
+
+ <itemizedlist>
+ <listitem><para>可选:策略配置参数</para></listitem>
+ <listitem><para>策略逻辑和参数的集中实现</para></listitem>
+ <listitem><para>可选:策略生命周期事件的实现,比如,策略的初始化和销毁</para></listitem>
+ <listitem><para>可选:对所选内核对象的安全标记进行初始化、维护和销毁的支持</para></listitem>
+ <listitem><para>可选:对所选对象的使用进程进行监控以及修改对象安全标记的支持</para></listitem>
+ <listitem><para>策略相关的访问控制入口函数的实现</para></listitem>
+ <listitem><para>对策略标志、模块入口函数和策略特性的声明</para></listitem>
+ </itemizedlist>
+
+ <sect2 id="mac-policy-declaration">
+ <title>策略注销</title>
+
+ <para>策略模块可以使用 <function>MAC_POLICY_SET()</function> 宏来声明。
+ 该宏完成以下工作:为该策略命名(向系统声明该策略提供的名字);提交策略定义的 MAC 入口函数向量的地址;
+ 按照策略的要求设置该策略的加载标志位,保证 MAC 框架将以策略所期望的方式对其进行操作;
+ 另外,还可能请求框架为策略分配标记状态 slot 值。</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>如上所示,MAC 策略入口函数向量,<varname>mac_<replaceable>policy</replaceable>_ops</varname>,
+ 将策略模块中定义的功能函数挂接到特定的入口函数地址上。
+ 在稍后的“入口函数参考”小节中,将提供可用入口函数功能描述和原型的完整列表。
+ 与模块注册相关的入口函数有两个:<symbol>.mpo_destroy</symbol>和<symbol>.mpo_init</symbol>。
+ 当某个策略向模块框架注册操作成功时,<symbol>.mpo_init</symbol>将被调用,此后其他的入口函数才能被使用。
+ 这种特殊的设计使得策略有机会根据自己的需要,进行特定的分配和初始化操作,比如对特殊数据或锁的初始化。
+ 卸载一个策略模块时,将调用 <symbol>.mpo_destroy</symbol> 用来释放策略分配的内存空间或注销其申请的锁。
+ 目前,为了防止其他入口函数被同时调用,调用上述两个入口函数的进程必须持有 MAC 策略链表的互斥锁:这种限制将被放开,
+ 但与此同时,将要求策略必须谨慎使用内核原语,以避免由于上锁次序或睡眠造成死锁。</para>
+
+ <para>之所以向策略声明提供模块名字域,是为了能够唯一标识该模块,以便解析模块依赖关系。选择使用恰当的字符串作为名字。
+ 在策略加载和卸载时,策略的完整字符串名字将经由内核日志显示给用户。另外,当向用户进程报告状态信息时也会包含该字符串。</para>
+ </sect2>
+
+ <sect2 id="mac-policy-flags">
+ <title>策略标志</title>
+
+ <para>在声明时提供标志参数域的机制,允许策略模块在作为模块被加载时,就自身特性向 MAC 框架提供说明。
+ 目前,已经定义的标志有三个:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>MPC_LOADTIME_FLAG_UNLOADOK</term>
+
+ <listitem>
+ <para>表示该策略模块可以被卸载。
+ 如果未提供该标志,则表示该策略模块拒绝被卸载。
+ 那些使用安全标记的状态,而又不能在运行时释放该状态的模块可能会设置该标志。
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>MPC_LOADTIME_FLAG_NOTLATE</term>
+
+ <listitem>
+ <para>表示该策略模块必须在系统引导过程时进行加载和初始化。
+ 如果该标志被设置,那么在系统引导之后注册该模块的请求将被 MAC 框架所拒绝。
+ 那些需要为大范围的系统对象进行安全标记初始化工作,而又不能处理含有未被正确初始化安全标记的对象的策略模块可能会设置该标志。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>MPC_LOADTIME_FLAG_LABELMBUFS</term>
+
+ <listitem>
+ <para>表示该策略模块要求为 Mbuf 指定安全标记,并且为存储其标记所需的内存空间总是提前分配好的。
+ 缺省情况下,MAC 框架并不会为 Mbuf 分配标记存储,除非系统中注册的策略模块中至少有一个设置了该标志。
+ 这种做法在没有策略需要对 Mbuf 做标记时,显著地提升了系统网络性能。另外,在某些特殊环境下,可以通过设置内核选项,
+ <literal>MAC_ALWAYS_LABEL_MBUF</literal>,强制 MAC 框架为 Mbuf 的安全标记分配存储,而不论上述标志如何设置。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <note><para>那些使用了
+ <literal>MPC_LOADTIME_FLAG_LABELMBUFS</literal> 标志但没有设置
+ <literal>MPC_LOADTIME_FLAG_NOTLATE</literal> 标志的
+ 策略模块必须能够正确地处理通过入口函数传入的值为 <literal>NULL</literal>
+ 的 Mbuf 安全标记指针。
+ 这是因为那些没有分配标记存储的处理中的 Mbuf 在一个需要 Mbuf 安全标记的策略模块加载之后,
+ 其安全标记的指针将仍然为空。
+ 如果策略在网络子系统活跃之前被加载(即,该策略不是被推迟加载的),那么所有的 Mbuf 的标记存储的分配就可以得到保证。</para></note>
+ </sect2>
+
+ <sect2 id="mac-policy-entry-points">
+ <title>策略入口函数</title>
+
+ <para>MAC 框架为注册的策略提供四种类型的入口函数:
+ 策略注册和管理入口函数;
+ 用于处理内核对象声明周期事件,如初始化、
+ 创建和销毁,的入口函数;
+ 处理该策略模块感兴趣的访问控制决策事件的入口函数;
+ 以及用于管理对象安全标记的调用入口函数。
+ 此外,
+ 还有一个 <function>mac_syscall()</function> 入口函数,
+ 被策略模块用于在不注册新的系统调用的前提下,
+ 扩展内核接口。</para>
+
+ <para>策略模块的编写人员除了必须清楚在进入特定入口函数之后,
+ 哪些对象锁是可用的之外,
+ 还应该熟知内核所采用的加锁策略。
+ 编程人员在入口函数之内应该避免使用非叶节点锁,
+ 并且遵循访问和修改对象时的加锁规程,
+ 以降低导致死锁的可能性。
+ 特别地,
+ 程序员应该清楚,
+ 虽然在通常情况下,
+ 进入入口函数之后,
+ 已经上了一些锁,
+ 可以安全地访问对象及其安全标记,
+ 但是这并不能保证对它们进行修改(
+ 包括对象本身和其安全标记)
+ 也是安全的。
+ 相关的上锁信息,可以参考 MAC 框架入口函数的相关文档。</para>
+
+ <para>策略入口函数把两个分别指向对象本身和其安全标记的指针传递给策略模块。
+ 这样一来,即使策略并不熟悉对象内部结构,也能基于标记作出正确决策。
+ 只有进程信任状这个对象例外:MAC 框架总是假设所有的策略模块是理解其内部结构的。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mac-entry-point-reference">
+ <title>MAC策略入口函数参考</title>
+
+ <sect2 id="mac-mpo-general">
+ <title>通用的模块入口函数</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>conf</parameter></entry>
+ <entry>MAC 策略定义</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>策略加载事件。当前进程正持有策略链表上的互斥锁,因此是非睡眠的,对其他内核子系统的调用也须慎重。
+ 如果需要在策略初始化阶段进行可能造成睡眠阻塞的存储分配操作,可以将它们放在一个单独的模块 SYSINIT()
+ 过程中集中进行。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>conf</parameter></entry>
+ <entry>MAC 策略定义</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>策略加载事件。必须持有策略链表互斥锁,因此需要慎重行事。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>td</parameter></entry>
+ <entry>调用线程</entry>
+ </row>
+
+ <row>
+ <entry><parameter>call</parameter></entry>
+ <entry>策略特有的系统调用编号</entry>
+ </row>
+
+ <row>
+ <entry><parameter>arg</parameter></entry>
+ <entry>系统调用参数的指针</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>该入口函数提供策略复用的系统调用,这样策略模块不需要为其向用户进程提供的每一个额外服务而注册专用的系统调用。
+ 由应用程序提供的策略注册名字来确定提供其所申请服务的特定策略,所有参数将通过该入口函数传递给被调用的策略。
+ 当实现新服务时,安全模块必须在必要时通过 MAC 框架调用相应的访问控制检查机制。
+ 比方说,假如一个策略实现了某种额外的信号功能,那么它应该调用相关的信号访问控制检查,以接受 MAC 框架中注册的其他策略的检查。</para>
+
+ <note><para>不同的模块需要并发地手动进行<function>copyin()</function>拷贝系统调用数据。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>td</parameter></entry>
+ <entry>返回线程</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <!-- XXX: Maybe rewrite this section. -->
+ <para>使用该入口函数,策略模块能够在线程返回用户空间时(系统调用返回、异常返回等等)进行 MAC 相关的处理工作。
+ 使用动态进程标记的策略需要使用该入口函数,因为在处理系统调用的过程中,并不是在任意时刻都能申请到进程锁的;
+ 进程的标记可能表示传统的认证信息、进程历史记录或者其他数据。为使用该入口函数,对进程信任状所作的修改
+ 可能被存放在 <literal>p_label</literal> ,该域受一个进程级自旋锁的保护;接下来,设置线程级的<literal>TDF_ASTPENDING</literal>
+ 标志位和进程级的<literal>PS_MACPENDM</literal>标志位,表明将调度一个对 userret 入口函数的调用。通过该入口函数,
+ 策略可以在相对简单的同步上下文中创建信任状的替代品。策略编程人员必须清楚,需要保证与调度一个 AST 相关的事件执行次序,
+ 同时所执行的 AST 可能很复杂,而且在处理多线程应用程序时可能被重入。</para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="mac-label-ops">
+ <title>操作标记</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被应用的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的 bpfdesc(BPF 描述子)初始化标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的用户信任状初始化标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被应用的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的 devfs 表项初始化标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被应用的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的网络接口初始化标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被应用的新标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>flag</parameter></entry>
+ <entry>睡眠/不睡眠 &man.malloc.9;; 参见下文</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的 IP 分片重组队列初始化标记。其中的<parameter>flag</parameter>域可能取<symbol>M_WAITOK</symbol>
+ 或<symbol>M_NOWAIT</symbol>之一,用来避免在该初始化调用中因为 &man.malloc.9; 而进入睡眠。IP 分片重组队列的分配操作通常是在
+ 对性能有严格要求的环境下进行的,因此实现代码必须小心地避免睡眠和长时间的操作。IP 分片重组队列分配操作失败时上述入口函数将失败返回。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>flag</parameter></entry>
+ <entry>睡眠/不睡眠 &man.malloc.9;; 参见下文</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的 mbuf 数据包头部(<parameter>mbuf</parameter>)初始化标记。
+ 其中的<parameter>flag</parameter>的值可能取<symbol>M_WAITOK</symbol>和<symbol>M_NOWAIT</symbol>之一,
+ 用来避免在该初始化调用中因为 &man.malloc.9; 而进入睡眠。Mbuf 头部的分配操作常常在对性能有严格要求的环境下被频繁执行,
+ 因此实现代码必须小心地避免睡眠和长时间的操作。上述入口函数在 Mbuf 头部分配操作失败时将失败返回。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mntlabel</parameter></entry>
+ <entry>将被初始化的mount 结构策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fslabel</parameter></entry>
+ <entry>将被初始化的文件系统策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近实例化的 mount 点初始化标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个新近加载的文件系统初始化标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被填写的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个刚刚实例化的管道初始化安全标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的新标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>flag</parameter></entry>
+ <entry>&man.malloc.9; flags</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个刚刚实例化的套接字初始化安全标记。其中的 <parameter>flag</parameter> 域的值必须被指定为
+ <symbol>M_WAITOK</symbol>和<symbol>M_NOWAIT</symbol>之一,以避免在该初始化程中使用可能睡眠的&man.malloc.9; 。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的新标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>flag</parameter></entry>
+ <entry>&man.malloc.9; flags</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为刚刚实例化的套接字对等体进行标记的初始化。其中的 <parameter>flag</parameter> 域的值必须被指定为
+ <symbol>M_WAITOK</symbol> 和 <symbol>M_NOWAIT</symbol> 之一,以避免在该初始化程中使用可能睡眠的
+ &man.malloc.9;。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个刚刚实例化的进程初始化安全标记。可以睡眠。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被初始化的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为一个刚刚实例化的 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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>bpfdesc 标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁一个 BPF 描述子上的标记。在该入口函数中,策略应当释放所有在内部分配与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁一个信任状上的标记。在该入口函数中,策略应当释放所有在内部分配的与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁一个 devfs 表项上的标记。在该入口函数中,策略应当释放所有在内部分配的与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个已删除接口相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个 IP 分片队列相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个 Mbuf 相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的 Mount 点标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个 mount 点相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 <parameter>mntlabel</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mntlabel</parameter></entry>
+ <entry>将被销毁的 Mount 点标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fslabel</parameter></entry>
+ <entry>File system label being destroyed></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个 mount 点相关联的标记。在该入口函数中,策略应当释放所有在内部分配的,与 <parameter>mntlabel</parameter>
+ 和<parameter>fslabel</parameter> 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被销毁的套接字标记</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个套接字相关联的标记。在该入口函数中,策略应当释放所有在内部分配的,与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>peerlabel</parameter></entry>
+ <entry>将被销毁的套接字对等实体标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁与一个套接字相关联的对等实体标记。在该入口函数中,策略应当释放所有在内部分配的,与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>管道标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁一个管道的标记。在该入口函数中,策略应当释放所有在内部分配的,与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>进程标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁一个进程的标记。在该入口函数中,策略应当释放所有在内部分配的,与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>进程标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>销毁一个 vnode 的标记。在该入口函数中,策略应当释放所有在内部分配的,与 <parameter>label</parameter>
+ 相关联的存储空间,以便销毁该标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>src</parameter></entry>
+ <entry>源标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dest</parameter></entry>
+ <entry>目标标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>将 <parameter>src</parameter> 中的标记信息拷贝到 <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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>src</parameter></entry>
+ <entry>源标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dest</parameter></entry>
+ <entry>目标标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>将 <parameter>src</parameter> 中的标记信息拷贝至 <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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>src</parameter></entry>
+ <entry>源标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dest</parameter></entry>
+ <entry>目标标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>将 <parameter>src</parameter> 中的标记信息拷贝至 <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ &mac.internalize.tbody;
+ </tgroup>
+ </informaltable>
+
+ &mac.internalize.para;
+ </sect3>
+ </sect2>
+
+ <sect2 id="mac-label-events">
+ <title>标记事件</title>
+
+ <para>策略模块使用MAC 框架提供的“标记事件”类入口函数,对内核对象的标记进行操作。策略模块将感兴趣的被标记内核对象的相关生命周期事件
+ 注册在恰当的入口点上。对象的初始化、创建和销毁事件均提供了钩子点。在某些对象上还可以实现重新标记,即,允许用户进程改变对象上的标记值。
+ 对某些对象可以实现其特定的对象事件,比如与 IP 重组相关的标记事件。一个典型的被标记对象在其生命周期中将拥有下列入口函数:</para>
+
+ <programlisting>标记初始化 o
+(对象相关的等待) \
+标记创建 o
+ \
+重新标记事件, o--&lt;--.
+各种对象相关的, | |
+访问控制事件 ~--&gt;--o
+ \
+标记销毁 o</programlisting>
+
+ <para>使用标记初始化入口函数,策略可以以一种统一的、与对象使用环境无关的方式设置标记的初始值。
+ 分配给一个策略的缺省 slot 值为0,这样不使用标记的策略可能并不需要执行专门的初始化操作。</para>
+
+ <para>标记的创建事件发生在将一个内核数据结构同一个真实的内核对象相关联(内核对象实例化)的时刻。
+ 例如,在真正被使用之前,在一个缓冲池内已分配的 mbuf 数据结构,将保持为“未使用”状态。
+ 因此,mbuf 的分配操作将导致针对该 mbuf 的标记初始化操作,而 mbuf 的创建操作则被推迟到该 mbuf 真正与一个数据报相关联的时刻。
+ 通常,调用者将会提供创建事件的上下文,包括创建环境、创建过程中涉及的其他对象的标记等。例如,当一个套接字创建一个 mbuf 时,
+ 除了新创建的 mbuf 及其标记之外,作为创建者的套接字与其标记也被提交给策略检查。
+ 不提倡在创建对象时就为其分配内存的原因有两个:创建操作可能发生在对性能有严格要求的内核接口上;
+ 而且,因为创建调用不允许失败,所以无法报告内存分配失败。</para>
+
+ <para>对象特有的事件一般不会引发其他的标记事件,但是在对象上下文发生改变时,策略使用它们可以对相关标记进行修改或更新操作。
+ 例如,在<symbol>MAC_UPDATE_IPQ</symbol> 入口函数之内,某个 IP 分片重组队列的标记可能会因为队列中接收了新的 mbuf 而被更新。</para>
+
+ <para>访问控制事件将在后续章节中详细讨论。</para>
+
+ <para>策略通过执行标记销毁操作,释放为其分配的存储空间或维护的状态,之后内核才可以重用或者释放对象的内核数据结构。</para>
+
+ <para>除了与特定内核对象绑定的普通标记之外,还有一种额外的标记类型:临时标记。这些标记用于存放由用户进程提交的更新信息。
+ 它们的初始化和销毁操作与其他标记一样,只是创建事件,<symbol>MAC_INTERNALIZE</symbol>,略有不同:
+ 该函数接受用户提交的标记,负责将其转化为内核表示形式。 </para>
+
+ <sect3 id="mac-fs-label-event-ops">
+ <title>文件系统对象标记事件操作</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mp</parameter></entry>
+ <entry>Devfs 挂载点</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fslabel</parameter></entry>
+ <entry>Devfs 文件系统标记
+ (<varname>mp-&gt;mnt_fslabel</varname>)</entry>
+ </row>
+
+ <row>
+ <entry><parameter>de</parameter></entry>
+ <entry>Devfs 目录项</entry>
+ </row>
+
+ <row>
+ <entry><parameter>delabel</parameter></entry>
+ <entry>与 <parameter>de</parameter> 相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>与 <parameter>de</parameter> 相关联的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry>与 <parameter>vp</parameter> 相关联的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据参数 <parameter>de</parameter> 传入的 devfs 目录项及其标记信息,为一个新近创建的
+ devfs vnode 填充标记(<parameter>vlabel</parameter>)。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mp</parameter></entry>
+ <entry>文件系统挂载点</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fslabel</parameter></entry>
+ <entry>文件系统标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被标记的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry>与 <parameter>vp</parameter> 相关联的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>从文件系统扩展属性中读取 <parameter>vp</parameter> 的标记。成功,返回 <literal>0</literal>。
+ 不成功,则在 <varname>errno</varname> 指定的相应的错误编码。
+ 如果文件系统不支持扩展属性的读取操作,则可以考虑将 <parameter>fslabel</parameter> 拷贝至 <parameter>vlabel</parameter>。
+ </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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mp</parameter></entry>
+ <entry>文件系统挂载点</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fslabel</parameter></entry>
+ <entry>文件系统标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被标记的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry>与 <parameter>vp</parameter> 相关联的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>在非多重标记文件系统上,使用该入口函数,根据文件系统标记,<parameter>fslabel</parameter>,
+ 为 <parameter>vp</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>dev</parameter></entry>
+ <entry><parameter>devfs_dirent</parameter> 对应的设备</entry>
+ </row>
+
+ <row>
+ <entry><parameter>devfs_dirent</parameter></entry>
+ <entry>将被标记的 Devfs 目录项</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>将被填写的 <parameter>devfs_dirent</parameter> 标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为传入设备新建的 devfs_dirent 填写标记。该函数将在设备文件系统加载、重构或添加新设备时被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>dirname</parameter></entry>
+ <entry>新建目录的名字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>namelen</parameter></entry>
+ <entry>字符串 <parameter>dirname</parameter> 的长度</entry>
+ </row>
+
+ <row>
+ <entry><parameter>devfs_dirent</parameter></entry>
+ <entry>新建目录在 Devfs 中对应的目录项</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为传入目录参数的新建 devfs_dirent 填写标记。该函数将在加载、重构设备文件系统,或者添加一个需要指定目录结构的新设备时被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mp</parameter></entry>
+ <entry>devfs 挂载点</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dd</parameter></entry>
+ <entry>链接目标</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ddlabel</parameter></entry>
+ <entry>与 <parameter>dd</parameter> 相关联的标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>de</parameter></entry>
+ <entry>符号链接项</entry>
+ </row>
+
+ <row>
+ <entry><parameter>delabel</parameter></entry>
+ <entry>与 <parameter>de</parameter> 相关联的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为新近创建的 &man.devfs.5; 符号链接项填写标记(<parameter>delabel</parameter>)。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mount</parameter></entry>
+ <entry>文件系统挂载点</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>文件系统标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>父目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry>与 <parameter>dvp</parameter> 相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>新创建的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry>与 <parameter>vp</parameter> 相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry><parameter>vp</parameter>中的子域名字</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>将 <parameter>vp</parameter> 的标记写入文件扩展属性。成功,将标记填入 <parameter>vlabel</parameter>,
+ 并返回 <returnvalue>0</returnvalue>。否则,返回对应的错误编码。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mp</parameter></entry>
+ <entry>客体;将被挂载的文件系统</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mntlabel</parameter></entry>
+ <entry>将被填写的 <parameter>mp</parameter> 的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fslabel</parameter></entry>
+ <entry>将被挂载到 <parameter>mp</parameter> 的文件系统的策略标记。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为传入的主体信任状所创建的挂载点填写标记。该函数将在文件系统挂载时被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry namest="first" nameend="last">见 <xref
+ linkend="mac-mpo-create-mount">.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为传入的主体信任状所创建的挂载点填写标记。该函数将在挂载根文件系统时,&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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被重新标记的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vnodelabel</parameter></entry>
+ <entry><parameter>vp</parameter> 现有的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将取代<parameter>vnodelabel</parameter>的新(可能只是部分)标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的新标记和主体信任状,更新参数 vnode 的标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>写出标记所对应的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>intlabel</parameter></entry>
+ <entry>将被写入磁盘的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>将参数 <parameter>intlabel</parameter> 给出的标记信息写入指定 vnode 的扩展属性。
+ 该函数被 <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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>devfs_dirent</parameter></entry>
+ <entry>客体;devfs 目录项</entry>
+ </row>
+
+ <row>
+ <entry><parameter>direntlabel</parameter></entry>
+ <entry>将被更新的<parameter>devfs_dirent</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>父 vnode</entry>
+ <entry>已锁定</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vnodelabel</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据所传入的 devfs vnode 标记,对 <parameter>devfs_dirent</parameter> 的标记进行更新。
+ 重新标记一个 devfs vnode 的操作成功之后,将调用该函数来确认标记的改变,如此,即使相应的 vnode 数据结构被内核回收重用,
+ 也不会丢失标记的新状态。另外,在 devfs 中新建一个符号链接时,紧接着<function>mac_vnode_create_from_vnode</function>,
+ 也将调用该函数,对 vnode 标记进行初始化操作。</para>
+ </sect4>
+ </sect3>
+
+ <sect3 id="mac-ipc-label-ops">
+ <title>IPC 对象标记事件操作</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>socket</parameter></entry>
+ <entry>套接字</entry>
+ <entry>套接字锁定 WIP</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>socket</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>m</parameter></entry>
+ <entry>客体;mbuf</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry>将被填写的 <parameter>m</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的套接字标记为新创建的mbuf头部设置标记。
+ 每当套接字产生一个新的数据报或者消息,并将其存储在参数 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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的主体信任状参数,设置新建管道的标记。每当一个新管道被创建,该函数将被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>so</parameter></entry>
+ <entry>客体;将被标记的套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry>将被填写的 <parameter>so</parameter> 的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的主体信任状参数,设置新建套接字的标记。每当新建一个套接字,该函数将被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>oldsocket</parameter></entry>
+ <entry>监听套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldsocketlabel</parameter></entry>
+ <entry><parameter>oldsocket</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newsocket</parameter></entry>
+ <entry>新建套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newsocketlabel</parameter></entry>
+ <entry><parameter>newsocket</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据 &man.listen.2 套接字 <parameter>oldsocket</parameter>,
+ 为新建 &man.accept.2 的套接字 <parameter>newsocket</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldlabel</parameter></entry>
+ <entry><parameter>pipe</parameter> 的当前策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将为<parameter>pipe</parameter> 设置的新的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为<parameter>pipe</parameter>设置新标记<parameter>newlabel</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>so</parameter></entry>
+ <entry>客体;套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldlabel</parameter></entry>
+ <entry><parameter>so</parameter> 的当前标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将为<parameter>socket</parameter> 设置的新标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的标记参数,对套接字的当前标记进行更新。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>从套接字接收到的第一个数据报</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry><parameter>mbuf</parameter> 的标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldlabel</parameter></entry>
+ <entry>套接字的当前标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将为套接字填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的 mbuf 标记,设置某个 stream 套接字的对等标志。
+ 除Unix域的套接字之外,每当一个 stream 套接字接收到第一个数据报时,该函数将被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>oldsocket</parameter></entry>
+ <entry>本地套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldsocketlabel</parameter></entry>
+ <entry><parameter>oldsocket</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newsocket</parameter></entry>
+ <entry>对等套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newsocketpeerlabel</parameter></entry>
+ <entry>将为<parameter>newsocket</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <!-- XXX Passed _remote_ socket endpoint ? -->
+ <para>根据传入的远程套接字端点,为一个 stream UNIX 与套接字设置对等标记。
+ 每当相应的套接字对之间进行连接时,该函数将在两端分别被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>bpf_d</parameter></entry>
+ <entry>客体;bpf 描述子</entry>
+ </row>
+
+ <row>
+ <entry><parameter>bpf</parameter></entry>
+ <entry>将为<parameter>bpf_d</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的主体信任状参数,为新建的 BPF 描述子设置标记。
+ 当进程打开 BPF 设备节点时,该函数将被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry>将为<parameter>ifnet</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为新建的网络接口设置标记。该函数在以下情况下被调用:
+ 当一个新的物理接口变为可用时,或者当一个伪接口在引导时或由于某个用户操作而实例化时。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>fragment</parameter></entry>
+ <entry>第一个被接收的 IP 分片</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fragmentlabel</parameter></entry>
+ <entry><parameter>fragment</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipq</parameter></entry>
+ <entry>将被标记的 IP 重组队列</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipqlabel</parameter></entry>
+ <entry>将为<parameter>ipq</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据第一个接收到的分片的 mbuf 头部信息,为新建的 IP 分片重组队列设置标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>ipq</parameter></entry>
+ <entry>IP 重组队列</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipqlabel</parameter></entry>
+ <entry><parameter>ipq</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>datagram</parameter></entry>
+ <entry>将被标记的数据报</entry>
+ </row>
+
+ <row>
+ <entry><parameter>datagramlabel</parameter></entry>
+ <entry>将为<parameter>datagramlabel</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据 IP 分片重组队列,为刚刚重组完毕的 IP 数据报设置标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>datagram</parameter></entry>
+ <entry>数据报</entry>
+ </row>
+
+ <row>
+ <entry><parameter>datagramlabel</parameter></entry>
+ <entry><parameter>datagram</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>fragment</parameter></entry>
+ <entry>将被标记的分片</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fragmentlabel</parameter></entry>
+ <entry>将为<parameter>datagram</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据数据报所对应的 mbuf 头部信息,为其新建的分片的 mbuf 头部设置标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>oldmbuf</parameter></entry>
+ <entry>已有的(源)mbuf</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldmbuflabel</parameter></entry>
+ <entry><parameter>oldmbuf</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newmbuf</parameter></entry>
+ <entry>将被标记的新建 mbuf</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newmbuflabel</parameter></entry>
+ <entry>将为<parameter>newmbuf</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据某个现有数据报的 mbuf 头部信息,为新建数据报的 mbuf 头部设置标记。在许多条件下将会调用该函数,
+ 比如,由于对齐要求而重新分配某个 mbuf 时。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>新建数据报的 mbuf 头部</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry>将为<parameter>mbuf</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为在给定接口上由于某个链路层响应而新建的数据报的mbuf头部设置标记。
+ 该函数将在若干条件下被调用,比如当IPv4和IPv6协议栈在响应ARP或者ND6时。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>bpf_d</parameter></entry>
+ <entry>BPF 描述子</entry>
+ </row>
+
+ <row>
+ <entry><parameter>bpflabel</parameter></entry>
+ <entry><parameter>bpflabel</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>将被标记的新建 mbuf</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry>将为<parameter>mbuf</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为使用参数 BPF 描述子创建的新数据报的 mbuf 头部设置标记。
+ 当对参数 BPF 描述子所关联的 BPF 设备进行写操作时,该函数将被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnetlabel</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>新建数据报的 mbuf 头部</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry>将为<parameter>mbuf</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为从网络接口参数创建的数据报的 mbuf 头部设置标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>oldmbuf</parameter></entry>
+ <entry>现有数据报的 mbuf 头部</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldmbuflabel</parameter></entry>
+ <entry><parameter>oldmbuf</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newmbuf</parameter></entry>
+ <entry>将被标记的新建数据报 mbuf 头部</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newmbuflabel</parameter></entry>
+ <entry>将为<parameter>newmbuf</parameter>填写的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>当传入的已有数据报被给定多播封装接口(multicast encapsulation interface)处理时被调用,
+ 为新创建的数据报所在 mbuf 头部设置标记。
+ 每当使用该虚拟接口传递一个mbuf时,将调用该函数。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>oldmbuf</parameter></entry>
+ <entry>接收的数据报</entry>
+ </row>
+
+ <row>
+ <entry><parameter>oldmbuflabel</parameter></entry>
+ <entry><parameter>oldmbuf</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>newmbuf</parameter></entry>
+ <entry>新建数据报</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newmbuflabel</parameter></entry>
+ <entry><parameter>newmbuf</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为由 IP 堆栈因为响应接收数据报(<parameter>oldmbuf</parameter>)而新建的数据报设置其 mbuf 头部的标记。
+ 许多情况下需要调用该函数,比如,响应 ICMP 请求数据报时。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>fragment</parameter></entry>
+ <entry>IP 数据报分片</entry>
+ </row>
+
+ <row>
+ <entry><parameter>fragmentlabel</parameter></entry>
+ <entry><parameter>fragment</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipq</parameter></entry>
+ <entry>IP 分片重组队列</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipqlabel</parameter></entry>
+ <entry><parameter>ipq</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据所传入的 IP 分片重组队列(<parameter>ipq</parameter>)的标记,
+ 检查包含一个 IP 数据报(<parameter>fragment</parameter>)的 mbuf 的头部是否符合其要求。
+ 符合,则返回<returnvalue>1</returnvalue>。否则,返回<returnvalue>0</returnvalue>。
+ 每当 IP 堆栈尝试将一个刚刚接收到的分片放入某个已有的分片重组队列中时,将调用该函数进行安全检查;
+ 如果失败,将为分片重新实例化一个新的分片重组队列。
+ 策略可以利用该入口函数,根据标记或者其他信息阻止不期望的 IP 分片重组。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>客体;网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter> 的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将为<parameter>ifnet</parameter>设置的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据所传入的新标记,<parameter>newlabel</parameter>,以及主体信任状,
+ <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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>IP 分片</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry><parameter>mbuf</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipq</parameter></entry>
+ <entry>IP 分片重组队列</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ipqlabel</parameter></entry>
+ <entry>将被更新的<parameter>ipq</parameter>的当前策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据所传入的 IP 分片 mbuf 头部(<parameter>mbuf</parameter>)为接收
+ 它的 IP 分片重组队列(<parameter>ipq</parameter>)的标记进行更新。</para>
+ </sect4>
+ </sect3>
+
+ <sect3 id="mac-proc-labeling-event-ops">
+ <title>进程标记事件操作</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>parent_cred</parameter></entry>
+ <entry>父主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>child_cred</parameter></entry>
+ <entry>子主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据所传入的主体信任状,为新建的主体信任状设置标记。
+ 每当为一个新建的 <type>struct ucred</type>调用 &man.crcopy.9; 时,将调用此函数。
+ 该函数不应与进程复制(forking)或者创建事件混为一谈。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>old</parameter></entry>
+ <entry>已有的主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>new</parameter></entry>
+ <entry>将被标记的新主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被执行的文件</entry>
+ <entry>已被锁定</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vnodelabel</parameter></entry>
+ <entry><parameter>vp</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>一个拥有信任状<parameter>old</parameter>的主体由于执行(<parameter>vp</parameter>文件而导致标记转换时,
+ 该函数根据vnode标记为该主体重新标记为<parameter>new</parameter>。 每当一个进程请求执行vnode文件,而通过
+ 入口函数<function>mpo_execve_will_transition</function> 有成功返回的策略时,将调用该函数。
+ 策略模块可以通过传入两个主体信任状和简单地调用 <function>mpo_create_cred</function> 来实现该入口函数,
+ so as not to implement a
+ transitioning event. 一旦策略实现了<function>mpo_create_cred</function>函数,即使没有实现
+ <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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>old</parameter></entry>
+ <entry>在执行&man.execve.2;之前的主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被执行的文件</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vnodelabel</parameter></entry>
+ <entry><parameter>vp</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>由策略决定,当参数主体信任状执行参数 vnode 时,是否需要进行一个标记转换操作。如果需要,返回<returnvalue>1</returnvalue>;
+ 否则,返回<returnvalue>0</returnvalue>。即使一个策略返回<returnvalue>0</returnvalue>,它也必须为自己不期望的对
+ <function>mpo_execve_transition</function>的调用作好准备,因为只要有其他任何一个策略要求转换,就将执行此函数。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>将被填写的主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为进程0,所有内核进程的祖先,创建主体信任状。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>将被填写的主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>为进程1,所有用户进程的祖先,创建主体信任状。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将被应用到 <parameter>cred</parameter> 上的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据传入的新标记,对主体信任状上的标记进行更新。</para>
+ </sect4>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="mac-access-control-checks">
+ <title>访问控制检查</title>
+
+ <para>通过访问控制入口函数,策略模块能影响内核的访问控制决策。
+ 通常情况下,不是绝对,一个访问控制入口函数的参数有,一个或者若干个授权信任状,和相关操作涉及的其他任何对象的信息(其中可能包含标记)。
+ 访问控制入口函数返回0,表示允许该操作;否则,返回一个 &man.errno.2; 错误编码。调用该入口函数,将遍历所有系统注册的策略模块,逐一进行
+ 策略相关的检查和决策,之后按照下述方法组合不同策略的返回结果:只有当所有的模块均允许该操作时,才成功返回。
+ 否则,如果有一个或者若干模块失败返回,则整个检查不通过。如果有多个模块的检查出错返回,将由定义在<filename>kern_mac.c</filename> 中的
+ <function>error_select()</function> 函数从它们返回的错误编码中,选择一个合适的,返回给用户。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>最高优先级</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>最低优先级</entry>
+ <entry>EPERM</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>如果所有策略模块返回的错误编码均没有出现在上述优先级序列表中,则任意选择一个返回。
+ 选择错误编码的一般次序为:内核错误,无效的参数,对象不存在,访问被拒绝,和其他错误。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>bpf_d</parameter></entry>
+ <entry>主体;BPF 描述子</entry>
+ </row>
+
+ <row>
+ <entry><parameter>bpflabel</parameter></entry>
+ <entry><parameter>bpf_d</parameter> 的策略标记 </entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>客体;网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter> 的策略标记 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定 MAC 框架是否应该允许将由参数接口接收到的数据报传递给由 BPF 描述子所对应的缓冲区。成功,则返回<returnvalue>0</returnvalue>;
+ 否则,返回错误编码信息<varname>errno</varname>。建议使用的错误编码有:<errorcode>EACCES</errorcode>,用于标记不符的情况;
+ <errorcode>EPERM</errorcode>,用于缺少特权的情况。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否应该被允许查询内核环境状态(参考 &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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>name</parameter></entry>
+ <entry>内核的环境变量名字</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否可以查询内核中给定环境变量的状态。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>name</parameter></entry>
+ <entry>内核的环境变量名字</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权设置给定内核环境变量的值。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>name</parameter></entry>
+ <entry>内核的环境变量名字Kernel environment variable name</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权清除给定的内核环境变量的设置。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>内核模块的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权加载给定的模块文件。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权访问内核的加载模块文件链表以及相关的统计数据。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权卸载一个内核模块。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cmd</parameter></entry>
+ <entry>&man.ioctl.2; 命令</entry>
+ </row>
+
+ <row>
+ <entry><parameter>data</parameter></entry>
+ <entry>&man.ioctl.2; 数据</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权调用指定的 &man.ioctl.2; 系统调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定相关主体是否有权对管道<parameter>pipe</parameter>执行poll操作。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体是否有权读取<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter>的当前策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将为<parameter>pipelabel</parameter>设置的新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体是否有权为<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体是否有权查询与<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipe</parameter></entry>
+ <entry>管道</entry>
+ </row>
+
+ <row>
+ <entry><parameter>pipelabel</parameter></entry>
+ <entry><parameter>pipe</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体是否有权写<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socket</parameter></entry>
+ <entry>将被绑定的套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>socket</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>sockaddr</parameter></entry>
+ <entry><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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socket</parameter></entry>
+ <entry>将被连接的套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>socket</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>sockaddr</parameter></entry>
+ <entry><parameter>socket</parameter>的地址</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体(<parameter>cred</parameter>)是否有权将套接字(<parameter>socket</parameter>)绑定到地址
+ <parameter>sockaddr</parameter>。成功,返回<returnvalue>0</returnvalue>,否则返回一个错误编码<varname>errno</varname>。
+ 建议采用的错误编码有:<errorcode>EACCES</errorcode>,用于标记不符的情况;<errorcode>EPERM</errorcode>,用于特权不足的情况。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>so</parameter></entry>
+ <entry>套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>so</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体是否有权查询套接字<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>so</parameter></entry>
+ <entry>套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>so</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体是否有权通过套接字<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>u1</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>u2</parameter></entry>
+ <entry>对象信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定该主体信任状<parameter>u1</parameter>是否有权 <quote>see</quote> 具有信任状<parameter>u2</parameter> 的其他主体。
+ 成功,返回<returnvalue>0</returnvalue>;否则,返回错误编码<varname>errno</varname>。建议采用的错误编码有:
+ <errorcode>EACCES</errorcode>,用于标记不符的情况;<errorcode>EPERM</errorcode>,用于特权不足的情况;<errorcode>ESRCH</errorcode>,
+ 用来提供不可见性。该函数可在许多环境下使用,包括命令<command>ps</command>所使用的进程间的状态 sysctl,以及通过procfs 的状态查询操作。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socket</parameter></entry>
+ <entry>客体;套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>客体;网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter>现有的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将被应用到<parameter>ifnet</parameter>上的新的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体信任状是否有权使用传入的标记更新参数对给定的网络接口的标记进行重新设置。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socket</parameter></entry>
+ <entry>客体;套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>socket</parameter>现有的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将被应用到<parameter>socketlabel</parameter>上的更新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体信任状是否有权采用传入的标记对套接字参数的标记进行重新设置。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将被应用到<parameter>cred</parameter>上的更新标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体信任状是否有权将自己的标记重新设置为给定的更新标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ <entry>已被锁定</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vnodelabel</parameter></entry>
+ <entry><parameter>vp</parameter>现有的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlabel</parameter></entry>
+ <entry>将被应用到<parameter>vp</parameter>上的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>决定该主体信任状是否有权将参数 vnode 的标记重新设置为指定标记。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mp</parameter></entry>
+ <entry>客体;文件系统挂载</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mountlabel</parameter></entry>
+ <entry><parameter>mp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <!-- XXX Update ? -->
+ <para>确定相关主体信任状是否有权查看在给定文件系统上执行 statfs 的结果。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。
+ 该函数可能在下列情况下被调用:
+ 在 &man.statfs.2; 和其他相关调用期间,或者当需要从文件系统列表中选择排除哪个文件系统时,比如,
+ 调用 &man.getfsstat.2;时。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>proc</parameter></entry>
+ <entry>客体;进程</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权 debug 给定进程。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够;
+ <errorcode>ESRCH</errorcode>,用于隐瞒目标的存在。
+ &man.ptrace.2; 和 &man.ktrace.2; API,以及某些 procfs 操作将调用该函数。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>flags</parameter></entry>
+ <entry>&man.access.2; 标志</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据相关主体信任状决定其对给定 vnode 以给定访问标志执行的 &man.access.2;
+ 和其他相关调用的返回值。一般,应采用与<function>&mac.mpo;_check_vnode_open</function>
+ 相同的语义来实现该函数。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>客体;&man.chdir.2; 的目的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry><parameter>dvp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权将进程工作目录切换到给定 vnode。成功,则返回 <returnvalue>0</returnvalue>;
+ 否则,返回一个 <varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry>与<parameter>dvp</parameter>相关联的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权 &man.chroot.2; 到由
+ (<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry><parameter>dvp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry><parameter>dvp</parameter>中的成员名</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vap</parameter></entry>
+ <entry><parameter>vap</parameter>的 vnode 属性</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权在给定父目录,以给定的名字和属性,
+ 常见一个 vnode。成功,则返回 <returnvalue>0</returnvalue>;否则,
+ 返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。
+ 以<symbol>O_CREAT</symbol>为参数调用 &man.open.2;,或对 &man.mknod.2;,&man.mkfifo.2;
+ 等的调用将导致该函数被调用。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>父目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry><parameter>dvp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;将被删除的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry><parameter>vp</parameter>中的成员名</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权从给定的父目录中,删除给定名字的 vnode。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。
+ 使用 &man.unlink.2; 和 &man.rmdir.2;,将导致该函数被调用。
+ 提供该入口函数的策略还必须实现一个
+ <function>mpo_check_rename_to</function>,
+ 用来授权由于重命名操作导致的目标文件的删除。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ <entry>被锁定</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>type</parameter></entry>
+ <entry>ACL 类型</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权删除给定 vnode 的给定类型的 ACL。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;将被执行的 vnode </entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权执行给定 vnode。
+ 对于执行特权的决策与任何瞬时事件的决策是严格分开的。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>type</parameter></entry>
+ <entry>ACL 类型</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权查询给定 vnode 上的给定类型的 ACL。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>attrnamespace</parameter></entry>
+ <entry>扩展属性名字空间</entry>
+ </row>
+
+ <row>
+ <entry><parameter>name</parameter></entry>
+ <entry>扩展属性名</entry>
+ </row>
+
+ <row>
+ <entry><parameter>uio</parameter></entry>
+ <entry>I/O 结构指针;参见 &man.uio.9;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权查询给定 vnode 上给定名字空间和名字的扩展属性。
+ 使用扩展属性实现标记存储的策略模块可能会需要对这些扩展属性的操作进行特殊处理。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry>与<parameter>dvp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>链接目的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry>将被创建的链接对应的成员名</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权为参数<parameter>vp</parameter>给定的 vnode
+ 创建一个由参数<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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被映射的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>prot</parameter></entry>
+ <entry>mmap 保护 (参见 &man.mmap.2;)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权将给定 vnode <parameter>vp</parameter> 以
+ <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 frame="none" pgwide="1">
+ <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</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据主体和客体标记,降低 mmap protections。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>映射的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>prot</parameter></entry>
+ <entry>存储保护</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权将给定 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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>active_cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>file_cred</parameter></entry>
+ <entry>与<type>struct file</type>相关联的信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被执行 poll 操作的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权对给定 vnode <parameter>vp</parameter>执行 poll 操作。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry>与<parameter>dvp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>将被重命名的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry><parameter>vp</parameter>中的成员名</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权重命名给定vnode,<parameter>vp</parameter>。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry>与<parameter>dvp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>被覆盖的 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>samedir</parameter></entry>
+ <entry>布尔型变量;如果源和目的目录是相同的,则被置为<literal>1</literal></entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry>目标component名</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权重命名给定 vnode <parameter>vp</parameter>,至指定目录
+ <parameter>dvp</parameter>,或更名为<parameter>cnp</parameter>。如果无需覆盖已有文件,
+ 则<parameter>vp</parameter> 和
+ <parameter>label</parameter> 的值将为 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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socket</parameter></entry>
+ <entry>客体;套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>socket</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权监听给定套接字。
+ 成功,则返回<returnvalue>0</returnvalue>;否则,返回错误编码值<varname>errno</varname>。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry><parameter>dvp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>cnp</parameter></entry>
+ <entry>被检查的成员名</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权在给定的目录 vnode 中为查找给定名字执行lookup操作。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个 <varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>acc_mode</parameter></entry>
+ <entry>&man.open.2; 访问模式</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权在给定 vnode 上以给定的访问模式执行 open 操作。
+ 如果成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个错误编码。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dvp</parameter></entry>
+ <entry>客体;目录 vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>dlabel</parameter></entry>
+ <entry><parameter>dvp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权在给定的目录 vnode 上执行
+ <function>readdir</function> 操作。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个错误编码 <varname>errno</varname>。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权在给定符号链接 vnode 上执行
+ <function>readlink</function> 操作。成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够。
+ 该函数可能在若干环境下被调用,包括由用户进程显式执行的 <function>readlink</function> 调用,
+ 或者是在进程执行名字查询时隐式执行的 <function>readlink</function> 。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权撤销对给定 vnode 的访问。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>type</parameter></entry>
+ <entry>ACL 类型</entry>
+ </row>
+
+ <row>
+ <entry><parameter>acl</parameter></entry>
+ <entry>ACL</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权设置给定 vnode 的给定类型的 ACL。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>attrnamespace</parameter></entry>
+ <entry>扩展属性名字空间</entry>
+ </row>
+
+ <row>
+ <entry><parameter>name</parameter></entry>
+ <entry>扩展属性名</entry>
+ </row>
+
+ <row>
+ <entry><parameter>uio</parameter></entry>
+ <entry>I/O 结构指针;参见 &man.uio.9;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权设置给定 vnode 上给定名字空间中给定名字的扩展属性的值。
+ 使用扩展属性备份安全标记的策略模块可能需要对其使用的属性实施额外的保护。另外,
+ 由于在检查和实际操作时间可能存在的竞争,
+ 策略模块应该避免根据来自<parameter>uio</parameter>中的数据做出决策。
+ 如果正在执行一个删除操作,则参数 <parameter>uio</parameter> 的值也可能为 <literal>NULL</literal>。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>flags</parameter></entry>
+ <entry>文件标志;参见 &man.chflags.2;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权为给定的 vnode 设置给定的标志。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mode</parameter></entry>
+ <entry>文件模式;参见 &man.chmod.2;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权将给定 vnode 的模式设置为给定值。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>uid</parameter></entry>
+ <entry>用户ID</entry>
+ </row>
+
+ <row>
+ <entry><parameter>gid</parameter></entry>
+ <entry>组ID</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权将给定 vnode 的文件 uid 和文件 gid 设置为给定值。如果无需更新,
+ 相关参数值可能被设置为(<literal>-1</literal>)。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vp</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>atime</parameter></entry>
+ <entry>访问时间;参见 &man.utimes.2;</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mtime</parameter></entry>
+ <entry>修改时间;参见 &man.utimes.2;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权将给定 vnode 的访问时间标签设置为给定值。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>proc</parameter></entry>
+ <entry>客体;进程</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权改变给定进程的调度参数。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够;
+ <errorcode>ESRCH</errorcode>,用于提供不可见性质。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>proc</parameter></entry>
+ <entry>客体;进程</entry>
+ </row>
+
+ <row>
+ <entry><parameter>signal</parameter></entry>
+ <entry>信号;参见 &man.kill.2;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权向给定进程发送给定信号。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,
+ 用于标记不匹配;<errorcode>EPERM</errorcode>,用于权限不够;
+ <errorcode>ESRCH</errorcode>,用于提供不可见性质。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>客体;vnode</entry>
+ </row>
+
+ <row>
+ <entry><parameter>label</parameter></entry>
+ <entry><parameter>vp</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状是否有权在给定 vnode 上执行 <function>stat</function> 操作。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>客体;将被发送的 mbuf </entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry><parameter>mbuf</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关网络接口是否有权传送给定的 mbuf。成功,则返回 <returnvalue>0</returnvalue>;
+ 否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnet</parameter></entry>
+ <entry>网络接口</entry>
+ </row>
+
+ <row>
+ <entry><parameter>ifnetlabel</parameter></entry>
+ <entry><parameter>ifnet</parameter>的策略标记</entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuf</parameter></entry>
+ <entry>客体;将被传送的 mbuf </entry>
+ </row>
+
+ <row>
+ <entry><parameter>mbuflabel</parameter></entry>
+ <entry><parameter>mbuf</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关套接字是否有权从给定的 mbuf 中接收数据报。
+ 成功,则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ <entry>不可改变</entry>
+ </row>
+
+ <row>
+ <entry><parameter>so</parameter></entry>
+ <entry>客体;套接字</entry>
+ </row>
+
+ <row>
+ <entry><parameter>socketlabel</parameter></entry>
+ <entry><parameter>so</parameter>的策略标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体信任状cred 是否有权使用系统监控函数,比如,
+ 由&man.netstat.8; 和 &man.sockstat.1;使用的程序来观察
+ 给定的套接字(<parameter>socket</parameter>)。成功,
+ 则返回 <returnvalue>0</returnvalue>;否则,返回一个<varname>errno</varname>值。
+ 建议使用的错误编码:<errorcode>EACCES</errorcode>,用于标记不匹配;
+ <errorcode>EPERM</errorcode>,用于权限不够;
+ <errorcode>ESRCH</errorcode>,用于提供不可见性质。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>ucred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>审计文件;&man.acct.5;</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>根据主体标记和审计日志文件的标记,确定该主体是否有权启动审计。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权调用
+ &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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>howto</parameter></entry>
+ <entry>来自 &man.reboot.2;的<parameter>howto</parameter> 参数</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权以指定方式重启系统。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关用户是否有权设置系统时钟。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vp</parameter></entry>
+ <entry>swap设备</entry>
+ </row>
+
+ <row>
+ <entry><parameter>vlabel</parameter></entry>
+ <entry>与<parameter>vp</parameter>相关联的标记</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否有权增加一个作为swap设备的 <parameter>vp</parameter> 。</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 frame="none" pgwide="1">
+ <tgroup cols="3">
+ &mac.thead;
+
+ <tbody>
+ <row>
+ <entry><parameter>cred</parameter></entry>
+ <entry>主体信任状</entry>
+ </row>
+
+ <row>
+ <entry><parameter>name</parameter></entry>
+ <entry morerows="3">参见 &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>布尔型变量;如果从内核被调用,其值被置为<literal>1</literal></entry>
+ </row>
+
+ <row>
+ <entry><parameter>new</parameter></entry>
+ <entry morerows="1">参见 &man.sysctl.3;</entry>
+ </row>
+
+ <row>
+ <entry><parameter>newlen</parameter></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>确定相关主体是否应该被允许执行指定的 &man.sysctl.3; 事务。</para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="mac-label-management">
+ <title>标记管理调用</title>
+
+ <para>当用户进程请求对某个对象的标记进行修改时,将引发重新标记事件。对应的更新操作分两步进行:
+ 首先,进行访问控制检查,确认此次更新操作是有效且被允许的;然后,调用另一个独立的入口函数对标记进行修改。
+ 重新标记入口函数通常接收由请求进程提交的对象、对象标记指针和请求新标记,作为输入参数。
+ 对象重新标记操作的失败将由先期的标记检查报告,所以,不允许在接下来的标记修改过程中报告失败,故而不提倡在此过程中新分配内存。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mac-userland-arch">
+ <title>应用层体系结构</title>
+
+ <para>TrustedBSD MAC 框架包含了一组策略无关的组成元素,包括管理抽象标记的 MAC 接口库,
+ 对系统信任状管理体系的修改, 为用户分配 MAC 标记提供支持的 login 库函数,
+ 以及若干负责维护和更新内核对象(进程、文件和网络接口等)安全标记的工具。
+ 不久,将有更多关于应用层体系结构的详细信息被包含进来。</para>
+
+ <sect2 id="mac-userland-labels">
+ <title>策略无关的标记管理 API</title>
+
+ <para>TrustedBSD MAC 提供的大量库函数和系统调用,允许应用程序使用一种统一的、策略无关的接口来处理对象的 MAC 标记。
+ 如此,应用程序可以轻松管理各种策略的标记,无需为增加对某个特定策略的支持而重新编码。许多通用工具,比如
+ &man.ifconfig.8;,&man.ls.1; 和 &man.ps.1;,使用这些策略无关的接口查询网络结构、文件和进程的标记信息。
+ 这些 API 也被用于支持 MAC 管理工具,比如,&man.getfmac.8;,&man.getpmac.8;, &man.setfmac.8;, &man.setfsmac.8;,和 &man.setpmac.8;。
+ MAC API的设计细节可参考 &man.mac.3;.</para>
+
+ <para>应用程序处理的 MAC 标记有两种存在形式:内部形式,用来返回和设置进程和对象的标记(<literal>mac_t</literal>);
+ 基于 C 字符串的外部形式,作为标记在配置文件中的存放形式,用于向用户显示或者由用户输入。
+ 每一个 MAC 标记由一组标记元素组成,其中每个元素是一个形如(名字,值)的二元组。
+ 内核中的每个策略模块分别被指定一个特定的名字,由它们对标记中与该名字对应的值采用其策略特有的方式进行解析。
+ 采用外部形式表示的标记,其标记元素表示为名字 <literal>/</literal> 值,元素之间以逗号分隔。
+ 应用程序可以使用 MAC 框架提供的 API 将一个安全标记在内部形式和文本形式之间进行转换。
+ 每当向内核查询某个对象的安全标记时,内部形式的标记必须针对所需的元素集合作好内部标记存储准备。
+ 为此,通常采用下面两种方式之一:使用 &man.mac.prepare.3; 和一个包含所需标记元素的任意列表;或者,
+ 使用从&man.mac.conf.5; 配置文件中加载缺省元素集合的某个系统调用。在对象级别设置缺省标记,将允许应用程序在不确定
+ 系统是否采用相关策略的情况下,也能向用户返回与对象相关联的有意义的安全标记。</para>
+
+ <note><para>目前的 MAC 库不支持直接修改内部形式的标记元素,所有的修改必须按照下列的步骤进行:
+ 将内部形式的标记转换成文本字符串,对字符串进行编辑,最后将其转换成内部形式标记。如果应用程序的作者证明确实有需要,
+ 可以在将来的版本中加入对内部形式标记进行直接修改的接口。</para></note>
+ </sect2>
+
+ <sect2 id="mac-userland-credentials">
+ <title>为用户指定标记</title>
+
+ <para>用户上下文管理的标记接口,
+ &man.setusercontext.3;
+ ,的行为已经被修改为,从
+ &man.login.conf.5;
+ 中查询与某个用户登录类别相关联的 MAC 安全标记。
+ 当 <literal>LOGIN_SETALL</literal>
+ 被设置,或者当 <literal>LOGIN_SETMAC</literal>
+ 被明确指定时,这些安全标记将和其他用户上下文参数一起被设置。</para>
+
+ <note><para>可以预期,在今后的某个版本中,FreeBSD 将把 MAC 标记从
+ <filename>login.conf</filename> 的用户类别数据库中抽出,为其维护一个独立的数据库。
+ 不过在此前后,&man.setusercontext.3; API应该保持不变。</para></note>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mac-conclusion">
+ <title>小结</title>
+
+ <para>TrustedBSD MAC 框架使得内核模块能以一种集中的方式,完善系统的安全策略。
+ 它们既可利用现有的内核对象属性,又能使用由 MAC 框架协助维护的安全标记数据,来实施访问控制。
+ 框架提供的灵活性使得开发人员可以在其上实现各种策略,如利用 BSD 现有的信任状(credential)
+ 与文件保护机制的策略,以及信息流安全策略(如 MLS 和 Biba)。
+ 实现新安全服务的策略编程人员,可以参考本文档,以了解现有安全模块的信息。</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:
+-->
+
+