123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- ========================================================
- 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()`
|