Monday, April 9, 2012

Linux Security Modules Framework (LSM)

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
What is LSM Framework?

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?''

                                               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

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

No comments:

Post a Comment