Documentation: LSM: Correct the basic LSM description
This is a first pass at updating the basic documentation on Linux Security Modules (LSM), which is frighteningly out of date. Remove untrue statements about the LSM framework. Replace them with true statements where it is convenient to do so. This is the beginnig of a larger effort to bring the LSM documentation up to date. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Link: https://lore.kernel.org/r/4c053d72-2d58-612f-6d6b-f04226d0181e@schaufler-ca.com Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
cea0fad0f8
commit
e2d467de34
@ -35,47 +35,50 @@ desired model of security. Linus also suggested the possibility of
|
|||||||
migrating the Linux capabilities code into such a module.
|
migrating the Linux capabilities code into such a module.
|
||||||
|
|
||||||
The Linux Security Modules (LSM) project was started by WireX to develop
|
The Linux Security Modules (LSM) project was started by WireX to develop
|
||||||
such a framework. LSM is a joint development effort by several security
|
such a framework. LSM was a joint development effort by several security
|
||||||
projects, including Immunix, SELinux, SGI and Janus, and several
|
projects, including Immunix, SELinux, SGI and Janus, and several
|
||||||
individuals, including Greg Kroah-Hartman and James Morris, to develop a
|
individuals, including Greg Kroah-Hartman and James Morris, to develop a
|
||||||
Linux kernel patch that implements this framework. The patch is
|
Linux kernel patch that implements this framework. The work was
|
||||||
currently tracking the 2.4 series and is targeted for integration into
|
incorporated in the mainstream in December of 2003. This technical
|
||||||
the 2.5 development series. This technical report provides an overview
|
report provides an overview of the framework and the capabilities
|
||||||
of the framework and the example capabilities security module provided
|
security module.
|
||||||
by the LSM kernel patch.
|
|
||||||
|
|
||||||
LSM Framework
|
LSM Framework
|
||||||
=============
|
=============
|
||||||
|
|
||||||
The LSM kernel patch provides a general kernel framework to support
|
The LSM framework provides a general kernel framework to support
|
||||||
security modules. In particular, the LSM framework is primarily focused
|
security modules. In particular, the LSM framework is primarily focused
|
||||||
on supporting access control modules, although future development is
|
on supporting access control modules, although future development is
|
||||||
likely to address other security needs such as auditing. By itself, the
|
likely to address other security needs such as sandboxing. By itself, the
|
||||||
framework does not provide any additional security; it merely provides
|
framework does not provide any additional security; it merely provides
|
||||||
the infrastructure to support security modules. The LSM kernel patch
|
the infrastructure to support security modules. The LSM framework is
|
||||||
also moves most of the capabilities logic into an optional security
|
optional, requiring `CONFIG_SECURITY` to be enabled. The capabilities
|
||||||
module, with the system defaulting to the traditional superuser logic.
|
logic is implemented as a security module.
|
||||||
This capabilities module is discussed further in
|
This capabilities module is discussed further in
|
||||||
`LSM Capabilities Module`_.
|
`LSM Capabilities Module`_.
|
||||||
|
|
||||||
The LSM kernel patch adds security fields to kernel data structures and
|
The LSM framework includes security fields in kernel data structures and
|
||||||
inserts calls to hook functions at critical points in the kernel code to
|
calls to hook functions at critical points in the kernel code to
|
||||||
manage the security fields and to perform access control. It also adds
|
manage the security fields and to perform access control.
|
||||||
functions for registering and unregistering security modules, and adds a
|
It also adds functions for registering security modules.
|
||||||
general :c:func:`security()` system call to support new system calls
|
An interface `/sys/kernel/security/lsm` reports a comma separated list
|
||||||
for security-aware applications.
|
of security modules that are active on the system.
|
||||||
|
|
||||||
The LSM security fields are simply ``void*`` pointers. For process and
|
The LSM security fields are simply ``void*`` pointers.
|
||||||
program execution security information, security fields were added to
|
The data is referred to as a blob, which may be managed by
|
||||||
|
the framework or by the individual security modules that use it.
|
||||||
|
Security blobs that are used by more than one security module are
|
||||||
|
typically managed by the framework.
|
||||||
|
For process and
|
||||||
|
program execution security information, security fields are included in
|
||||||
:c:type:`struct task_struct <task_struct>` and
|
:c:type:`struct task_struct <task_struct>` and
|
||||||
:c:type:`struct linux_binprm <linux_binprm>`. For filesystem
|
:c:type:`struct cred <cred>`.
|
||||||
security information, a security field was added to :c:type:`struct
|
For filesystem
|
||||||
|
security information, a security field is included in :c:type:`struct
|
||||||
super_block <super_block>`. For pipe, file, and socket security
|
super_block <super_block>`. For pipe, file, and socket security
|
||||||
information, security fields were added to :c:type:`struct inode
|
information, security fields are included in :c:type:`struct inode
|
||||||
<inode>` and :c:type:`struct file <file>`. For packet and
|
<inode>` and :c:type:`struct file <file>`.
|
||||||
network device security information, security fields were added to
|
For System V IPC security information,
|
||||||
:c:type:`struct sk_buff <sk_buff>` and :c:type:`struct
|
|
||||||
net_device <net_device>`. For System V IPC security information,
|
|
||||||
security fields were added to :c:type:`struct kern_ipc_perm
|
security fields were added to :c:type:`struct kern_ipc_perm
|
||||||
<kern_ipc_perm>` and :c:type:`struct msg_msg
|
<kern_ipc_perm>` and :c:type:`struct msg_msg
|
||||||
<msg_msg>`; additionally, the definitions for :c:type:`struct
|
<msg_msg>`; additionally, the definitions for :c:type:`struct
|
||||||
@ -84,118 +87,45 @@ were moved to header files (``include/linux/msg.h`` and
|
|||||||
``include/linux/shm.h`` as appropriate) to allow the security modules to
|
``include/linux/shm.h`` as appropriate) to allow the security modules to
|
||||||
use these definitions.
|
use these definitions.
|
||||||
|
|
||||||
Each LSM hook is a function pointer in a global table, security_ops.
|
For packet and
|
||||||
This table is a :c:type:`struct security_operations
|
network device security information, security fields were added to
|
||||||
<security_operations>` structure as defined by
|
:c:type:`struct sk_buff <sk_buff>` and
|
||||||
``include/linux/security.h``. Detailed documentation for each hook is
|
:c:type:`struct scm_cookie <scm_cookie>`.
|
||||||
included in this header file. At present, this structure consists of a
|
Unlike the other security module data, the data used here is a
|
||||||
collection of substructures that group related hooks based on the kernel
|
32-bit integer. The security modules are required to map or otherwise
|
||||||
object (e.g. task, inode, file, sk_buff, etc) as well as some top-level
|
associate these values with real security attributes.
|
||||||
hook function pointers for system operations. This structure is likely
|
|
||||||
to be flattened in the future for performance. The placement of the hook
|
|
||||||
calls in the kernel code is described by the "called:" lines in the
|
|
||||||
per-hook documentation in the header file. The hook calls can also be
|
|
||||||
easily found in the kernel code by looking for the string
|
|
||||||
"security_ops->".
|
|
||||||
|
|
||||||
Linus mentioned per-process security hooks in his original remarks as a
|
LSM hooks are maintained in lists. A list is maintained for each
|
||||||
possible alternative to global security hooks. However, if LSM were to
|
hook, and the hooks are called in the order specified by CONFIG_LSM.
|
||||||
start from the perspective of per-process hooks, then the base framework
|
Detailed documentation for each hook is
|
||||||
would have to deal with how to handle operations that involve multiple
|
included in the `include/linux/lsm_hooks.h` header file.
|
||||||
processes (e.g. kill), since each process might have its own hook for
|
|
||||||
controlling the operation. This would require a general mechanism for
|
|
||||||
composing hooks in the base framework. Additionally, LSM would still
|
|
||||||
need global hooks for operations that have no process context (e.g.
|
|
||||||
network input operations). Consequently, LSM provides global security
|
|
||||||
hooks, but a security module is free to implement per-process hooks
|
|
||||||
(where that makes sense) by storing a security_ops table in each
|
|
||||||
process' security field and then invoking these per-process hooks from
|
|
||||||
the global hooks. The problem of composition is thus deferred to the
|
|
||||||
module.
|
|
||||||
|
|
||||||
The global security_ops table is initialized to a set of hook functions
|
The LSM framework provides for a close approximation of
|
||||||
provided by a dummy security module that provides traditional superuser
|
general security module stacking. It defines
|
||||||
logic. A :c:func:`register_security()` function (in
|
security_add_hooks() to which each security module passes a
|
||||||
``security/security.c``) is provided to allow a security module to set
|
:c:type:`struct security_hooks_list <security_hooks_list>`,
|
||||||
security_ops to refer to its own hook functions, and an
|
which are added to the lists.
|
||||||
:c:func:`unregister_security()` function is provided to revert
|
The LSM framework does not provide a mechanism for removing hooks that
|
||||||
security_ops to the dummy module hooks. This mechanism is used to set
|
have been registered. The SELinux security module has implemented
|
||||||
the primary security module, which is responsible for making the final
|
a way to remove itself, however the feature has been deprecated.
|
||||||
decision for each hook.
|
|
||||||
|
|
||||||
LSM also provides a simple mechanism for stacking additional security
|
The hooks can be viewed as falling into two major
|
||||||
modules with the primary security module. It defines
|
|
||||||
:c:func:`register_security()` and
|
|
||||||
:c:func:`unregister_security()` hooks in the :c:type:`struct
|
|
||||||
security_operations <security_operations>` structure and
|
|
||||||
provides :c:func:`mod_reg_security()` and
|
|
||||||
:c:func:`mod_unreg_security()` functions that invoke these hooks
|
|
||||||
after performing some sanity checking. A security module can call these
|
|
||||||
functions in order to stack with other modules. However, the actual
|
|
||||||
details of how this stacking is handled are deferred to the module,
|
|
||||||
which can implement these hooks in any way it wishes (including always
|
|
||||||
returning an error if it does not wish to support stacking). In this
|
|
||||||
manner, LSM again defers the problem of composition to the module.
|
|
||||||
|
|
||||||
Although the LSM hooks are organized into substructures based on kernel
|
|
||||||
object, all of the hooks can be viewed as falling into two major
|
|
||||||
categories: hooks that are used to manage the security fields and hooks
|
categories: hooks that are used to manage the security fields and hooks
|
||||||
that are used to perform access control. Examples of the first category
|
that are used to perform access control. Examples of the first category
|
||||||
of hooks include the :c:func:`alloc_security()` and
|
of hooks include the security_inode_alloc() and security_inode_free()
|
||||||
:c:func:`free_security()` hooks defined for each kernel data
|
These hooks are used to allocate
|
||||||
structure that has a security field. These hooks are used to allocate
|
and free security structures for inode objects.
|
||||||
and free security structures for kernel objects. The first category of
|
An example of the second category of hooks
|
||||||
hooks also includes hooks that set information in the security field
|
is the security_inode_permission() hook.
|
||||||
after allocation, such as the :c:func:`post_lookup()` hook in
|
This hook checks permission when accessing an inode.
|
||||||
:c:type:`struct inode_security_ops <inode_security_ops>`.
|
|
||||||
This hook is used to set security information for inodes after
|
|
||||||
successful lookup operations. An example of the second category of hooks
|
|
||||||
is the :c:func:`permission()` hook in :c:type:`struct
|
|
||||||
inode_security_ops <inode_security_ops>`. This hook checks
|
|
||||||
permission when accessing an inode.
|
|
||||||
|
|
||||||
LSM Capabilities Module
|
LSM Capabilities Module
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
The LSM kernel patch moves most of the existing POSIX.1e capabilities
|
The POSIX.1e capabilities logic is maintained as a security module
|
||||||
logic into an optional security module stored in the file
|
stored in the file ``security/commoncap.c``. The capabilities
|
||||||
``security/capability.c``. This change allows users who do not want to
|
module uses the order field of the :c:type:`lsm_info` description
|
||||||
use capabilities to omit this code entirely from their kernel, instead
|
to identify it as the first security module to be registered.
|
||||||
using the dummy module for traditional superuser logic or any other
|
The capabilities security module does not use the general security
|
||||||
module that they desire. This change also allows the developers of the
|
blobs, unlike other modules. The reasons are historical and are
|
||||||
capabilities logic to maintain and enhance their code more freely,
|
based on overhead, complexity and performance concerns.
|
||||||
without needing to integrate patches back into the base kernel.
|
|
||||||
|
|
||||||
In addition to moving the capabilities logic, the LSM kernel patch could
|
|
||||||
move the capability-related fields from the kernel data structures into
|
|
||||||
the new security fields managed by the security modules. However, at
|
|
||||||
present, the LSM kernel patch leaves the capability fields in the kernel
|
|
||||||
data structures. In his original remarks, Linus suggested that this
|
|
||||||
might be preferable so that other security modules can be easily stacked
|
|
||||||
with the capabilities module without needing to chain multiple security
|
|
||||||
structures on the security field. It also avoids imposing extra overhead
|
|
||||||
on the capabilities module to manage the security fields. However, the
|
|
||||||
LSM framework could certainly support such a move if it is determined to
|
|
||||||
be desirable, with only a few additional changes described below.
|
|
||||||
|
|
||||||
At present, the capabilities logic for computing process capabilities on
|
|
||||||
:c:func:`execve()` and :c:func:`set\*uid()`, checking
|
|
||||||
capabilities for a particular process, saving and checking capabilities
|
|
||||||
for netlink messages, and handling the :c:func:`capget()` and
|
|
||||||
:c:func:`capset()` system calls have been moved into the
|
|
||||||
capabilities module. There are still a few locations in the base kernel
|
|
||||||
where capability-related fields are directly examined or modified, but
|
|
||||||
the current version of the LSM patch does allow a security module to
|
|
||||||
completely replace the assignment and testing of capabilities. These few
|
|
||||||
locations would need to be changed if the capability-related fields were
|
|
||||||
moved into the security field. The following is a list of known
|
|
||||||
locations that still perform such direct examination or modification of
|
|
||||||
capability-related fields:
|
|
||||||
|
|
||||||
- ``fs/open.c``::c:func:`sys_access()`
|
|
||||||
|
|
||||||
- ``fs/lockd/host.c``::c:func:`nlm_bind_host()`
|
|
||||||
|
|
||||||
- ``fs/nfsd/auth.c``::c:func:`nfsd_setuser()`
|
|
||||||
|
|
||||||
- ``fs/proc/array.c``::c:func:`task_cap()`
|
|
||||||
|
Loading…
Reference in New Issue
Block a user