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:
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
|
@ -188,9 +188,9 @@
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Framework management interfaces</para></listitem>
|
<listitem><para>Framework management interfaces</para></listitem>
|
||||||
<listitem><para>Concurrency and synchronization management
|
<listitem><para>Concurrency and synchronization
|
||||||
primitives.</para></listitem>
|
primitives.</para></listitem>
|
||||||
<listitem><para>Policy registration and management</para></listitem>
|
<listitem><para>Policy registration</para></listitem>
|
||||||
<listitem><para>Extensible security label for kernel
|
<listitem><para>Extensible security label for kernel
|
||||||
objects</para></listitem>
|
objects</para></listitem>
|
||||||
<listitem><para>Policy entry point composition
|
<listitem><para>Policy entry point composition
|
||||||
|
@ -211,6 +211,76 @@
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</sect2>
|
</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">
|
<sect2 id="mac-framework-kernel-arch-entrypoints">
|
||||||
<title>Entry Points</title>
|
<title>Entry Points</title>
|
||||||
|
|
||||||
|
@ -260,11 +330,73 @@
|
||||||
of string-based labels provides by user applications, and can
|
of string-based labels provides by user applications, and can
|
||||||
expose multiple label elements to applications if desired.</para>
|
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
|
<para>In the case of file system labels, special support is
|
||||||
provided for the persistent storage of security labels in
|
provided for the persistent storage of security labels in
|
||||||
extended attributes. Where available, EA transactions
|
extended attributes. Where available, EA transactions
|
||||||
are used to permit consistent compound updates of
|
are used to permit consistent compound updates of
|
||||||
security labels on vnodes.</para>
|
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>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
|
@ -188,9 +188,9 @@
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Framework management interfaces</para></listitem>
|
<listitem><para>Framework management interfaces</para></listitem>
|
||||||
<listitem><para>Concurrency and synchronization management
|
<listitem><para>Concurrency and synchronization
|
||||||
primitives.</para></listitem>
|
primitives.</para></listitem>
|
||||||
<listitem><para>Policy registration and management</para></listitem>
|
<listitem><para>Policy registration</para></listitem>
|
||||||
<listitem><para>Extensible security label for kernel
|
<listitem><para>Extensible security label for kernel
|
||||||
objects</para></listitem>
|
objects</para></listitem>
|
||||||
<listitem><para>Policy entry point composition
|
<listitem><para>Policy entry point composition
|
||||||
|
@ -211,6 +211,76 @@
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</sect2>
|
</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">
|
<sect2 id="mac-framework-kernel-arch-entrypoints">
|
||||||
<title>Entry Points</title>
|
<title>Entry Points</title>
|
||||||
|
|
||||||
|
@ -260,11 +330,73 @@
|
||||||
of string-based labels provides by user applications, and can
|
of string-based labels provides by user applications, and can
|
||||||
expose multiple label elements to applications if desired.</para>
|
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
|
<para>In the case of file system labels, special support is
|
||||||
provided for the persistent storage of security labels in
|
provided for the persistent storage of security labels in
|
||||||
extended attributes. Where available, EA transactions
|
extended attributes. Where available, EA transactions
|
||||||
are used to permit consistent compound updates of
|
are used to permit consistent compound updates of
|
||||||
security labels on vnodes.</para>
|
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>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue