| ======================================================== | 
 | Linux Security Modules: General Security Hooks for Linux | 
 | ======================================================== | 
 |  | 
 | :Author: Stephen Smalley | 
 | :Author: Timothy Fraser | 
 | :Author: Chris Vance | 
 |  | 
 | .. note:: | 
 |  | 
 |    The APIs described in this book are outdated. | 
 |  | 
 | Introduction | 
 | ============ | 
 |  | 
 | In March 2001, the National Security Agency (NSA) gave a presentation | 
 | about Security-Enhanced Linux (SELinux) at the 2.5 Linux Kernel Summit. | 
 | SELinux is an implementation of flexible and fine-grained | 
 | nondiscretionary access controls in the Linux kernel, originally | 
 | implemented as its own particular kernel patch. Several other security | 
 | projects (e.g. RSBAC, Medusa) have also developed flexible access | 
 | control architectures for the Linux kernel, and various projects have | 
 | developed particular access control models for Linux (e.g. LIDS, DTE, | 
 | SubDomain). Each project has developed and maintained its own kernel | 
 | patch to support its security needs. | 
 |  | 
 | In response to the NSA presentation, Linus Torvalds made a set of | 
 | remarks that described a security framework he would be willing to | 
 | consider for inclusion in the mainstream Linux kernel. He described a | 
 | general framework that would provide a set of security hooks to control | 
 | operations on kernel objects and a set of opaque security fields in | 
 | kernel data structures for maintaining security attributes. This | 
 | framework could then be used by loadable kernel modules to implement any | 
 | desired model of security. Linus also suggested the possibility of | 
 | migrating the Linux capabilities code into such a module. | 
 |  | 
 | The Linux Security Modules (LSM) project was started by WireX to develop | 
 | such a framework. LSM is a joint development effort by several security | 
 | projects, including Immunix, SELinux, SGI and Janus, and several | 
 | individuals, including Greg Kroah-Hartman and James Morris, to develop a | 
 | Linux kernel patch that implements this framework. The patch is | 
 | currently tracking the 2.4 series and is targeted for integration into | 
 | the 2.5 development series. This technical report provides an overview | 
 | of the framework and the example capabilities security module provided | 
 | by the LSM kernel patch. | 
 |  | 
 | LSM Framework | 
 | ============= | 
 |  | 
 | The LSM kernel patch provides a general kernel framework to support | 
 | security modules. In particular, the LSM framework is primarily focused | 
 | on supporting access control modules, although future development is | 
 | likely to address other security needs such as auditing. By itself, the | 
 | framework does not provide any additional security; it merely provides | 
 | the infrastructure to support security modules. The LSM kernel patch | 
 | also moves most of the capabilities logic into an optional security | 
 | module, with the system defaulting to the traditional superuser logic. | 
 | This capabilities module is discussed further in | 
 | `LSM Capabilities Module <#cap>`__. | 
 |  | 
 | The LSM kernel patch adds security fields to kernel data structures and | 
 | inserts calls to hook functions at critical points in the kernel code to | 
 | manage the security fields and to perform access control. It also adds | 
 | functions for registering and unregistering security modules, and adds a | 
 | general :c:func:`security()` system call to support new system calls | 
 | for security-aware applications. | 
 |  | 
 | The LSM security fields are simply ``void*`` pointers. For process and | 
 | program execution security information, security fields were added to | 
 | :c:type:`struct task_struct <task_struct>` and | 
 | :c:type:`struct linux_binprm <linux_binprm>`. For filesystem | 
 | security information, a security field was added to :c:type:`struct | 
 | super_block <super_block>`. For pipe, file, and socket security | 
 | information, security fields were added to :c:type:`struct inode | 
 | <inode>` and :c:type:`struct file <file>`. For packet and | 
 | network device security information, security fields were added to | 
 | :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 | 
 | <kern_ipc_perm>` and :c:type:`struct msg_msg | 
 | <msg_msg>`; additionally, the definitions for :c:type:`struct | 
 | msg_msg <msg_msg>`, struct msg_queue, and struct shmid_kernel | 
 | were moved to header files (``include/linux/msg.h`` and | 
 | ``include/linux/shm.h`` as appropriate) to allow the security modules to | 
 | use these definitions. | 
 |  | 
 | Each LSM hook is a function pointer in a global table, security_ops. | 
 | This table is a :c:type:`struct security_operations | 
 | <security_operations>` structure as defined by | 
 | ``include/linux/security.h``. Detailed documentation for each hook is | 
 | included in this header file. At present, this structure consists of a | 
 | collection of substructures that group related hooks based on the kernel | 
 | object (e.g. task, inode, file, sk_buff, etc) as well as some top-level | 
 | 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 | 
 | possible alternative to global security hooks. However, if LSM were to | 
 | start from the perspective of per-process hooks, then the base framework | 
 | would have to deal with how to handle operations that involve multiple | 
 | 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 | 
 | provided by a dummy security module that provides traditional superuser | 
 | logic. A :c:func:`register_security()` function (in | 
 | ``security/security.c``) is provided to allow a security module to set | 
 | security_ops to refer to its own hook functions, and an | 
 | :c:func:`unregister_security()` function is provided to revert | 
 | security_ops to the dummy module hooks. This mechanism is used to set | 
 | the primary security module, which is responsible for making the final | 
 | decision for each hook. | 
 |  | 
 | LSM also provides a simple mechanism for stacking additional security | 
 | 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 | 
 | that are used to perform access control. Examples of the first category | 
 | of hooks include the :c:func:`alloc_security()` and | 
 | :c:func:`free_security()` hooks defined for each kernel data | 
 | structure that has a security field. These hooks are used to allocate | 
 | and free security structures for kernel objects. The first category of | 
 | hooks also includes hooks that set information in the security field | 
 | after allocation, such as the :c:func:`post_lookup()` hook in | 
 | :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 | 
 | ======================= | 
 |  | 
 | The LSM kernel patch moves most of the existing POSIX.1e capabilities | 
 | logic into an optional security module stored in the file | 
 | ``security/capability.c``. This change allows users who do not want to | 
 | use capabilities to omit this code entirely from their kernel, instead | 
 | using the dummy module for traditional superuser logic or any other | 
 | module that they desire. This change also allows the developers of the | 
 | capabilities logic to maintain and enhance their code more freely, | 
 | 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()` |