In computer security the term access control is mainly used to refer to the process of controlling the access of a subject or initiator (Process) or generally perform some sort of operation on an object or target (Data).
The Linux
Security Modules (LSM) project has developed a lightweight,
general purpose, access control framework for the mainstream Linux
kernel that enables many different access control models to be
implemented as loadable kernel modules. A number of existing enhanced
access control implementations, including Linux capabilities,
Security-Enhanced Linux (SELinux), and Domain and Type Enforcement
(DTE), have already been adapted to use the LSM framework.
By checking the kernel source code i found that there are two systems that have already adopted to use the LSM framework, Tomoyo and Smack.
Agenda
- What is LSM Framework?
- LSM Design
- LSM Implementation
- LSM Hooks
- References
Linux Security Modules (LSM) is a framework that allows the Linux kernel to support a variety of computer security models while avoiding favoritism toward any single security implementation. The framework is licensed under the terms of the GNU General Public License and is standard part of the Linux kernel since Linux 2.6. Apparmor, SELinux, Smack and TOMOYO Linux are the currently accepted modules in the official kernel.
LSM Framework Design
The basic abstraction of the LSM interface is to mediate access to internal kernel objects. LSM seeks to allow modules to answer the question ``May a subject S perform a kernel operation OP on an internal kernel object OBJ?''
The LSM framework is initialized during the kernel's boot sequence
with a set of dummy hook functions that enforce traditional UNIX superuser
semantics. When a security module is loaded, it must register itself
with the LSM framework by calling the register_security
function. This function sets the global security_ops table to
refer to the module's hook function pointers, causing the kernel to
call into the security module for access control decisions. The register_security function will not overwrite a previously loaded
module. Once a security module is loaded, it becomes a policy
decision whether it will allow itself to be unloaded.
If a security module is unloaded, it must unregister with the framework using unregister_security. This simply replaces the hook functions with the defaults so the system will still have some basic means for security. The default hook functions do not use the opaque security fields, so the system's security should not be compromised if the module does a poor job of resetting the opaque fields.
LSM Hooks
Task Hooks
LSM provides a set of task hooks that enable security modules to manage process security information and to control process operations. Modules can maintain process security information using the security field of the task_struct structure. Task hooks provide control over inter-process operations, such as kill, as well as control over privileged operations on the current process, such as setuid. The task hooks also provide fine-grained control over resource management operations such as setrlimit and nice.
Program Loading Hooks
Many security modules, including Linux capabilities, DTE, SELinux, and SubDomain require the ability to perform changes in privilege when a new program is executed. Consequently, LSM provides a set of program-loading hooks that are called at critical points during the processing of an execve operation. The security field of the linux_binprm structure permits modules to maintain security information during program loading. One hook is provided to permit security modules to initialize this security information and to perform access control prior to loading the program, and a second hook is provided to permit modules to update the task security information after the new program has been successfully loaded. These hooks can also be used to control inheritance of state across program executions, for example, revalidating open file descriptors.
IPC Hooks
Security modules can manage security information and perform access control for System V IPC using the LSM IPC hooks.
File System Hooks
For file operations, three sets of hooks were defined: filesystem hooks, inode hooks, and file hooks. LSM adds a security field to each of the associated kernel data structures: super_block, inode, and file. The filesystem hooks enable security modules to control operations such as mounting and statfs. LSM leverages the existing permission function by inserting an inode hook into it, but LSM also defines a number of other inode hooks to provide finer-grained control over individual inode operations. Some of the file hooks allow security modules to perform additional checking on file operations such as read and write, for example, to revalidate permissions on use to support privilege bracketing or dynamic policy changes. A hook is also provided to allow security modules to control receipt of open file descriptors via socket IPC. Other file hooks provide finer-grained control over operations such as fcntl and ioctl.
Network Hooks
Application layer access to networking is mediated using a set of socket hooks. These hooks, which include the interposition of all socket system calls, provide coarse mediation coverage of all socket-based protocols. Since active user sockets have an associated inode structure, a separate security field was not added to the socket structure or to the lower-level sock structure. As the socket hooks allow general mediation of network traffic in relation to processes, LSM significantly expands the kernel's network access control framework. For example, the sock_rcv_skb hook allows an inbound packet to be mediated in terms of its destination application, prior to being queued at the associated userspace socket.
Other Hooks
LSM provides two additional sets of hooks: module hooks and a set of top-level system hooks. Module hooks can be used to control the kernel operations that create, initialize, and delete kernel modules. System hooks can be used to control system operations, such as setting the system hostname, accessing I/O ports, and configuring process accounting. The existing Linux kernel provides some control over many of these operations using the capability checks, but those checks only provide coarse-grained distinctions among different operations and do not provide any argument information.
References
The basic abstraction of the LSM interface is to mediate access to internal kernel objects. LSM seeks to allow modules to answer the question ``May a subject S perform a kernel operation OP on an internal kernel object OBJ?''
Figure1: LSM Hook Architecture
LSM allows modules to mediate access to kernel objects by placing hooks in the kernel code just ahead of the access, as shown in
Figure 1. Just before the kernel would have
accessed an internal object, a hook makes a call to a function that the
LSM module must provide. The module can either let the access occur, or
deny access, forcing an error code return.
Many security models require binding security attributes to kernel
objects. To facilitate this, LSM provides for opaque security
fields that are attached to various internal kernel objects. However, the module is completely
responsible for managing these fields, including allocation,
de-allocation, and concurrency control.
LSM Implementation
The LSM kernel patch modifies the kernel in five primary ways. First,
it adds opaque security fields to certain kernel data structures. Second, the patch inserts
calls to security hook functions at various points within the kernel
code. Third, the patch adds a
generic security system call.
Fourth, the patch provides functions to allow kernel modules to
register and unregister themselves as security modules. Finally, the patch moves most of
the capabilities logic into an optional security module.
Opaque Security Fields
The opaque security fields are void* pointers, which enable
security modules to associate security information with
kernel objects. Table 1 shows the kernel
data structures that are modified by the LSM kernel patch and the
corresponding abstract object.
The setting of these security fields and the management of the
associated security data is handled by the security modules. LSM
merely provides the fields and a set of calls to security hooks that
can be implemented by the module to manage the security fields as
desired. For most kinds of objects, an alloc_security hook and
a free_security hook are defined that permit the security module
to allocate and free security data when the corresponding kernel data
structure is allocated and freed. Other hooks are provided to permit
the security module to update the security data as necessary, e.g. a
post_lookup hook that can be used to set security data for an
inode after a successful lookup operation. It is important to
note that LSM does not provide any locking for the security fields;
such locking must be performed by the security module.
Since some objects will exist prior to the initialization of a
security module, even if the module is built into the kernel, a
security module must handle pre-existing objects. Several approaches
are possible. The simplest approach is to ignore such objects,
treating them as being outside of the control of the module. These
objects would then only be controlled by the base Linux access control
logic. A second approach is to traverse the kernel data structures
during module initialization, setting the security fields for all
pre-existing objects at this time. This approach would require great
care to ensure that all objects are updated (e.g. an open file might
be on a UNIX domain socket awaiting receipt by a process) and to
ensure that appropriate locking is performed. A third approach is to
test for pre-existing objects on each use and to then set the security
field for pre-existing objects when needed.
Calls to Security Hook Functions
Figure:
The vfs_mkdir kernel function with one security hook call
to mediate access and one security hook call to manage
the security field.
The security hooks are marked by<->.
As discussed in the previous subsection, LSM provides a set of calls
to security hooks to manage the security fields of kernel objects.
It also provides a set of calls to security hooks to mediate access to
these objects. Both sets of hook functions are called via function
pointers in a global security_ops table. This structure
consists of a collection of substructures that group related hooks
based on kernel object or subsystem, as well as some top-level hooks
for system operations. Each hook is defined in terms of kernel
objects and parameters, and care has been taken to avoid userspace
pointers.
Figure 2 shows the vfs_mkdir kernel function
after the LSM kernel patch has been applied. This kernel function is
used to create new directories. Two calls to security hook functions
have been inserted into this function. The first hook call,
security_ops->inode_ops->mkdir, can be used to control the ability
to create new directories. If the hook returns an error status, then
the new directory will not be created and the error status will be
propagated to the caller. The second hook call,
security_ops->inode_ops->post_mkdir, can be used to set the
security field for the new directory's inode structure. This hook can
only update the security module's state; it cannot affect the return
status.
Registering Security Modules
If a security module is unloaded, it must unregister with the framework using unregister_security. This simply replaces the hook functions with the defaults so the system will still have some basic means for security. The default hook functions do not use the opaque security fields, so the system's security should not be compromised if the module does a poor job of resetting the opaque fields.
LSM Hooks
Task Hooks
LSM provides a set of task hooks that enable security modules to manage process security information and to control process operations. Modules can maintain process security information using the security field of the task_struct structure. Task hooks provide control over inter-process operations, such as kill, as well as control over privileged operations on the current process, such as setuid. The task hooks also provide fine-grained control over resource management operations such as setrlimit and nice.
Program Loading Hooks
Many security modules, including Linux capabilities, DTE, SELinux, and SubDomain require the ability to perform changes in privilege when a new program is executed. Consequently, LSM provides a set of program-loading hooks that are called at critical points during the processing of an execve operation. The security field of the linux_binprm structure permits modules to maintain security information during program loading. One hook is provided to permit security modules to initialize this security information and to perform access control prior to loading the program, and a second hook is provided to permit modules to update the task security information after the new program has been successfully loaded. These hooks can also be used to control inheritance of state across program executions, for example, revalidating open file descriptors.
IPC Hooks
Security modules can manage security information and perform access control for System V IPC using the LSM IPC hooks.
File System Hooks
For file operations, three sets of hooks were defined: filesystem hooks, inode hooks, and file hooks. LSM adds a security field to each of the associated kernel data structures: super_block, inode, and file. The filesystem hooks enable security modules to control operations such as mounting and statfs. LSM leverages the existing permission function by inserting an inode hook into it, but LSM also defines a number of other inode hooks to provide finer-grained control over individual inode operations. Some of the file hooks allow security modules to perform additional checking on file operations such as read and write, for example, to revalidate permissions on use to support privilege bracketing or dynamic policy changes. A hook is also provided to allow security modules to control receipt of open file descriptors via socket IPC. Other file hooks provide finer-grained control over operations such as fcntl and ioctl.
Network Hooks
Application layer access to networking is mediated using a set of socket hooks. These hooks, which include the interposition of all socket system calls, provide coarse mediation coverage of all socket-based protocols. Since active user sockets have an associated inode structure, a separate security field was not added to the socket structure or to the lower-level sock structure. As the socket hooks allow general mediation of network traffic in relation to processes, LSM significantly expands the kernel's network access control framework. For example, the sock_rcv_skb hook allows an inbound packet to be mediated in terms of its destination application, prior to being queued at the associated userspace socket.
Other Hooks
LSM provides two additional sets of hooks: module hooks and a set of top-level system hooks. Module hooks can be used to control the kernel operations that create, initialize, and delete kernel modules. System hooks can be used to control system operations, such as setting the system hostname, accessing I/O ports, and configuring process accounting. The existing Linux kernel provides some control over many of these operations using the capability checks, but those checks only provide coarse-grained distinctions among different operations and do not provide any argument information.
References
- Linux Security Modules Paper
- Mandatory Access Control Wiki
- Smack Security Module Wiki (LSM security project)
- Linux Security Modules Wiki
- Kernel Security Documentation
No comments:
Post a Comment