Add more to the MAC Framework Kernel Architecture:

- Add Management Interfaces (sysctls, tunables, et al).
- Add Concurrency and Synchronization (busy count handling to synchronize
  policy loading).
- Add Policy Registration (management of active poliy lists).
- Flesh out Labeling Support to talk about label initialization and
  life cycles, allocation semantics.
- Add System Calls.

Obtained from:	TrustedBSD Project
Sponsored by:	DARPA, Network Associates Laboratories
This commit is contained in:
Robert Watson 2003-04-20 21:00:56 +00:00
parent 8c1173c2f6
commit fa27b75e0f
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=16634
2 changed files with 268 additions and 4 deletions
en_US.ISO8859-1/books
arch-handbook/mac
developers-handbook/mac

View file

@ -188,9 +188,9 @@
<itemizedlist>
<listitem><para>Framework management interfaces</para></listitem>
<listitem><para>Concurrency and synchronization management
<listitem><para>Concurrency and synchronization
primitives.</para></listitem>
<listitem><para>Policy registration and management</para></listitem>
<listitem><para>Policy registration</para></listitem>
<listitem><para>Extensible security label for kernel
objects</para></listitem>
<listitem><para>Policy entry point composition
@ -211,6 +211,76 @@
</itemizedlist>
</sect2>
<sect2 id="mac-framework-kernel-arch-management">
<title>Management Interfaces</title>
<para>The TrustedBSD MAC Framework may be directly managed using
sysctls, loader tunables, and system calls.</para>
<para>In most cases, sysctls and loader tunables modify the same
parameters, and control behavior such as enforcement of
protections relating to various kernel subsystems. In addition,
if MAC debugging support is compiled into the kernel, a variety
of counters will be maintained tracking label allocation. In
most cases, it is advised that per-subsystem enforcement
controls not be used to control policy behavior in production
environments, as they broadly impact the operation of all
active policies. Instead, per-policy controls should be
preferred to ensure proper policy operation.</para>
<para>Loading and unloading of policy modules is performed
using the system module management system calls and other
system interfaces, including loader variables.</para>
</sect2>
<sect2 id="mac-framework-kernel-arch-synchronization">
<title>Concurrency and Synchronization</title>
<para>As the set of active policies may change at run-time,
and the invocation of entry points is non-atomic,
synchronization is required to prevent unloading or
loading of new policies while an entry point invocation
is progress, freezing the list of policies for the
duration. This is accomplished by means of a Framework
busy count. Whenever an entry point is entered, the
busy count is incremented; whenever it is exited, the
busy count is decremented. While the busy count is
elevated, policy list changes are not permitted, and
threads attempting to modify the policy list will sleep
until the list is not busy. The busy count is protected
by a mutex, and a condition variable is used to wake up
sleepers waiting on policy list modifications.</para>
<para>Various optimizations are used to reduce the overhead
of the busy count, including avoiding the full cost of
incrementing and decrementing if the list is empty or
contains only static entries (policies that are loaded
before the system starts, and cannot be unloaded).</para>
</sect2>
<sect2 id="mac-framework-kernel-arch-registration">
<title>Policy Registration</title>
<para>The MAC Framework maintains two lists of active
policies: a static list, and a dynamic list. The lists
differ only with regards to their locking semantics: an
elevated reference count is not required to make use of
the static list. When kernel modules containing MAC
Framework policies are loaded, the policy module will
use <literal>SYSINIT</literal> to invoke a registration
function; when a policy module is unloaded,
<literal>SYSINIT</literal> will likewise invoke a
de-registration function. Registration may fail if a
policy module is loaded more than once, if insufficient
resources are available for the registration (for
example, the policy might require labeling and
insufficient labeling state might be available), or
other policy prerequisites might not be met (some
policies may only be loaded prior to boot). Likewise,
de-registration may fail if a policy refuses an
unload.</para>
</sect2>
<sect2 id="mac-framework-kernel-arch-entrypoints">
<title>Entry Points</title>
@ -260,11 +330,73 @@
of string-based labels provides by user applications, and can
expose multiple label elements to applications if desired.</para>
<para>In-memory labels are stored in <structname>struct
label</structname>, which consists of a fixed-length array
of unions, each holding a <literal>void *</literal> pointer
and a <literal>long</literal>. Policies registering for
label storage will be assigned a "slot" identifier, which
may be used to dereference the label storage. The semantics
of the storage are left entirely up to the policy module:
modules are provided with a variety of entry points
associated with the kernel object life cycle, including
initialization, association/creation, and destruction. Using
these interfaces, it is possible to implement reference
counting and other storage mechanisms. Direct access to
the kernel object is generally not required by policy
modules to retrieve a label, as the MAC Framework generally
passes both a pointer to the object and a direct pointer
to the object's label into entry points.</para>
<para>Initialization entry points frequently include a blocking
disposition flag indicating whether or not an initialization
is permitted to block; if blocking is not permitted, a failure
may be returned to cancel allocation of the label. This may
occur, for example, in the network stack during interrupt
handling, where blocking is not permitted. Due to the
performance cost of maintaining labels on in-flight network
packets (Mbufs), policies must specifically declare a
requirement that Mbuf labels be allocated. Dynamically
loaded policies making use of labels must be able to handle
the case where their init function has not been called on
an object, as objects may already exist when the policy is
loaded.</para>
<para>In the case of file system labels, special support is
provided for the persistent storage of security labels in
extended attributes. Where available, EA transactions
are used to permit consistent compound updates of
security labels on vnodes.</para>
<note><para>Currently, if a labeled policy permits dynamic
unloading, its state slot cannot be reclaimed.</para></note>
</sect2>
<sect2 id="mac-framework-kernel-arch-syscalls">
<title>System Calls</title>
<para>The MAC Framework implements a number of system calls:
most of these calls support the policy-agnostic label
retrieval and manipulation APIs exposed to user
applications.</para>
<para>The label management calls accept a label description
structure, <structname>struct mac</structname>, which
contains a series of MAC label elements. Each element
contains a character string name, and character string
value. Each policy will be given the chance to claim a
particular element name, permitting policies to expose
multiple independent elements if desired. Policy modules
perform the internalization and externalization between
kernel labels and user-provided labels via entry points,
permitting a variety of semantics. Label management system
calls are generally wrapped by user library functions to
perform memory allocation and error handling.</para>
<para>In addition, <function>mac_syscall()</function>
permits policy modules to create new system calls without
allocating system calls. <function>mac_execve()</function>
permits an atomic process credential label change when
executing a new image.</para>
</sect2>
</sect1>

View file

@ -188,9 +188,9 @@
<itemizedlist>
<listitem><para>Framework management interfaces</para></listitem>
<listitem><para>Concurrency and synchronization management
<listitem><para>Concurrency and synchronization
primitives.</para></listitem>
<listitem><para>Policy registration and management</para></listitem>
<listitem><para>Policy registration</para></listitem>
<listitem><para>Extensible security label for kernel
objects</para></listitem>
<listitem><para>Policy entry point composition
@ -211,6 +211,76 @@
</itemizedlist>
</sect2>
<sect2 id="mac-framework-kernel-arch-management">
<title>Management Interfaces</title>
<para>The TrustedBSD MAC Framework may be directly managed using
sysctls, loader tunables, and system calls.</para>
<para>In most cases, sysctls and loader tunables modify the same
parameters, and control behavior such as enforcement of
protections relating to various kernel subsystems. In addition,
if MAC debugging support is compiled into the kernel, a variety
of counters will be maintained tracking label allocation. In
most cases, it is advised that per-subsystem enforcement
controls not be used to control policy behavior in production
environments, as they broadly impact the operation of all
active policies. Instead, per-policy controls should be
preferred to ensure proper policy operation.</para>
<para>Loading and unloading of policy modules is performed
using the system module management system calls and other
system interfaces, including loader variables.</para>
</sect2>
<sect2 id="mac-framework-kernel-arch-synchronization">
<title>Concurrency and Synchronization</title>
<para>As the set of active policies may change at run-time,
and the invocation of entry points is non-atomic,
synchronization is required to prevent unloading or
loading of new policies while an entry point invocation
is progress, freezing the list of policies for the
duration. This is accomplished by means of a Framework
busy count. Whenever an entry point is entered, the
busy count is incremented; whenever it is exited, the
busy count is decremented. While the busy count is
elevated, policy list changes are not permitted, and
threads attempting to modify the policy list will sleep
until the list is not busy. The busy count is protected
by a mutex, and a condition variable is used to wake up
sleepers waiting on policy list modifications.</para>
<para>Various optimizations are used to reduce the overhead
of the busy count, including avoiding the full cost of
incrementing and decrementing if the list is empty or
contains only static entries (policies that are loaded
before the system starts, and cannot be unloaded).</para>
</sect2>
<sect2 id="mac-framework-kernel-arch-registration">
<title>Policy Registration</title>
<para>The MAC Framework maintains two lists of active
policies: a static list, and a dynamic list. The lists
differ only with regards to their locking semantics: an
elevated reference count is not required to make use of
the static list. When kernel modules containing MAC
Framework policies are loaded, the policy module will
use <literal>SYSINIT</literal> to invoke a registration
function; when a policy module is unloaded,
<literal>SYSINIT</literal> will likewise invoke a
de-registration function. Registration may fail if a
policy module is loaded more than once, if insufficient
resources are available for the registration (for
example, the policy might require labeling and
insufficient labeling state might be available), or
other policy prerequisites might not be met (some
policies may only be loaded prior to boot). Likewise,
de-registration may fail if a policy refuses an
unload.</para>
</sect2>
<sect2 id="mac-framework-kernel-arch-entrypoints">
<title>Entry Points</title>
@ -260,11 +330,73 @@
of string-based labels provides by user applications, and can
expose multiple label elements to applications if desired.</para>
<para>In-memory labels are stored in <structname>struct
label</structname>, which consists of a fixed-length array
of unions, each holding a <literal>void *</literal> pointer
and a <literal>long</literal>. Policies registering for
label storage will be assigned a "slot" identifier, which
may be used to dereference the label storage. The semantics
of the storage are left entirely up to the policy module:
modules are provided with a variety of entry points
associated with the kernel object life cycle, including
initialization, association/creation, and destruction. Using
these interfaces, it is possible to implement reference
counting and other storage mechanisms. Direct access to
the kernel object is generally not required by policy
modules to retrieve a label, as the MAC Framework generally
passes both a pointer to the object and a direct pointer
to the object's label into entry points.</para>
<para>Initialization entry points frequently include a blocking
disposition flag indicating whether or not an initialization
is permitted to block; if blocking is not permitted, a failure
may be returned to cancel allocation of the label. This may
occur, for example, in the network stack during interrupt
handling, where blocking is not permitted. Due to the
performance cost of maintaining labels on in-flight network
packets (Mbufs), policies must specifically declare a
requirement that Mbuf labels be allocated. Dynamically
loaded policies making use of labels must be able to handle
the case where their init function has not been called on
an object, as objects may already exist when the policy is
loaded.</para>
<para>In the case of file system labels, special support is
provided for the persistent storage of security labels in
extended attributes. Where available, EA transactions
are used to permit consistent compound updates of
security labels on vnodes.</para>
<note><para>Currently, if a labeled policy permits dynamic
unloading, its state slot cannot be reclaimed.</para></note>
</sect2>
<sect2 id="mac-framework-kernel-arch-syscalls">
<title>System Calls</title>
<para>The MAC Framework implements a number of system calls:
most of these calls support the policy-agnostic label
retrieval and manipulation APIs exposed to user
applications.</para>
<para>The label management calls accept a label description
structure, <structname>struct mac</structname>, which
contains a series of MAC label elements. Each element
contains a character string name, and character string
value. Each policy will be given the chance to claim a
particular element name, permitting policies to expose
multiple independent elements if desired. Policy modules
perform the internalization and externalization between
kernel labels and user-provided labels via entry points,
permitting a variety of semantics. Label management system
calls are generally wrapped by user library functions to
perform memory allocation and error handling.</para>
<para>In addition, <function>mac_syscall()</function>
permits policy modules to create new system calls without
allocating system calls. <function>mac_execve()</function>
permits an atomic process credential label change when
executing a new image.</para>
</sect2>
</sect1>