Mauro Carvalho Chehab | 415008a | 2017-05-14 11:41:53 -0300 | [diff] [blame] | 1 | ======================================================== |
| 2 | Linux Security Modules: General Security Hooks for Linux |
| 3 | ======================================================== |
| 4 | |
| 5 | :Author: Stephen Smalley |
| 6 | :Author: Timothy Fraser |
| 7 | :Author: Chris Vance |
| 8 | |
| 9 | .. note:: |
| 10 | |
| 11 | The APIs described in this book are outdated. |
| 12 | |
| 13 | Introduction |
| 14 | ============ |
| 15 | |
| 16 | In March 2001, the National Security Agency (NSA) gave a presentation |
| 17 | about Security-Enhanced Linux (SELinux) at the 2.5 Linux Kernel Summit. |
| 18 | SELinux is an implementation of flexible and fine-grained |
| 19 | nondiscretionary access controls in the Linux kernel, originally |
| 20 | implemented as its own particular kernel patch. Several other security |
| 21 | projects (e.g. RSBAC, Medusa) have also developed flexible access |
| 22 | control architectures for the Linux kernel, and various projects have |
| 23 | developed particular access control models for Linux (e.g. LIDS, DTE, |
| 24 | SubDomain). Each project has developed and maintained its own kernel |
| 25 | patch to support its security needs. |
| 26 | |
| 27 | In response to the NSA presentation, Linus Torvalds made a set of |
| 28 | remarks that described a security framework he would be willing to |
| 29 | consider for inclusion in the mainstream Linux kernel. He described a |
| 30 | general framework that would provide a set of security hooks to control |
| 31 | operations on kernel objects and a set of opaque security fields in |
| 32 | kernel data structures for maintaining security attributes. This |
| 33 | framework could then be used by loadable kernel modules to implement any |
| 34 | desired model of security. Linus also suggested the possibility of |
| 35 | migrating the Linux capabilities code into such a module. |
| 36 | |
| 37 | The Linux Security Modules (LSM) project was started by WireX to develop |
| 38 | such a framework. LSM is a joint development effort by several security |
| 39 | projects, including Immunix, SELinux, SGI and Janus, and several |
| 40 | individuals, including Greg Kroah-Hartman and James Morris, to develop a |
| 41 | Linux kernel patch that implements this framework. The patch is |
| 42 | currently tracking the 2.4 series and is targeted for integration into |
| 43 | the 2.5 development series. This technical report provides an overview |
| 44 | of the framework and the example capabilities security module provided |
| 45 | by the LSM kernel patch. |
| 46 | |
| 47 | LSM Framework |
| 48 | ============= |
| 49 | |
| 50 | The LSM kernel patch provides a general kernel framework to support |
| 51 | security modules. In particular, the LSM framework is primarily focused |
| 52 | on supporting access control modules, although future development is |
| 53 | likely to address other security needs such as auditing. By itself, the |
| 54 | framework does not provide any additional security; it merely provides |
| 55 | the infrastructure to support security modules. The LSM kernel patch |
| 56 | also moves most of the capabilities logic into an optional security |
| 57 | module, with the system defaulting to the traditional superuser logic. |
| 58 | This capabilities module is discussed further in |
| 59 | `LSM Capabilities Module <#cap>`__. |
| 60 | |
| 61 | The LSM kernel patch adds security fields to kernel data structures and |
| 62 | inserts calls to hook functions at critical points in the kernel code to |
| 63 | manage the security fields and to perform access control. It also adds |
| 64 | functions for registering and unregistering security modules, and adds a |
| 65 | general :c:func:`security()` system call to support new system calls |
| 66 | for security-aware applications. |
| 67 | |
| 68 | The LSM security fields are simply ``void*`` pointers. For process and |
| 69 | program execution security information, security fields were added to |
| 70 | :c:type:`struct task_struct <task_struct>` and |
| 71 | :c:type:`struct linux_binprm <linux_binprm>`. For filesystem |
| 72 | security information, a security field was added to :c:type:`struct |
| 73 | super_block <super_block>`. For pipe, file, and socket security |
| 74 | information, security fields were added to :c:type:`struct inode |
| 75 | <inode>` and :c:type:`struct file <file>`. For packet and |
| 76 | network device security information, security fields were added to |
| 77 | :c:type:`struct sk_buff <sk_buff>` and :c:type:`struct |
| 78 | net_device <net_device>`. For System V IPC security information, |
| 79 | security fields were added to :c:type:`struct kern_ipc_perm |
| 80 | <kern_ipc_perm>` and :c:type:`struct msg_msg |
| 81 | <msg_msg>`; additionally, the definitions for :c:type:`struct |
| 82 | msg_msg <msg_msg>`, struct msg_queue, and struct shmid_kernel |
| 83 | were moved to header files (``include/linux/msg.h`` and |
| 84 | ``include/linux/shm.h`` as appropriate) to allow the security modules to |
| 85 | use these definitions. |
| 86 | |
| 87 | Each LSM hook is a function pointer in a global table, security_ops. |
| 88 | This table is a :c:type:`struct security_operations |
| 89 | <security_operations>` structure as defined by |
| 90 | ``include/linux/security.h``. Detailed documentation for each hook is |
| 91 | included in this header file. At present, this structure consists of a |
| 92 | collection of substructures that group related hooks based on the kernel |
| 93 | object (e.g. task, inode, file, sk_buff, etc) as well as some top-level |
| 94 | hook function pointers for system operations. This structure is likely |
| 95 | to be flattened in the future for performance. The placement of the hook |
| 96 | calls in the kernel code is described by the "called:" lines in the |
| 97 | per-hook documentation in the header file. The hook calls can also be |
| 98 | easily found in the kernel code by looking for the string |
| 99 | "security_ops->". |
| 100 | |
| 101 | Linus mentioned per-process security hooks in his original remarks as a |
| 102 | possible alternative to global security hooks. However, if LSM were to |
| 103 | start from the perspective of per-process hooks, then the base framework |
| 104 | would have to deal with how to handle operations that involve multiple |
| 105 | processes (e.g. kill), since each process might have its own hook for |
| 106 | controlling the operation. This would require a general mechanism for |
| 107 | composing hooks in the base framework. Additionally, LSM would still |
| 108 | need global hooks for operations that have no process context (e.g. |
| 109 | network input operations). Consequently, LSM provides global security |
| 110 | hooks, but a security module is free to implement per-process hooks |
| 111 | (where that makes sense) by storing a security_ops table in each |
| 112 | process' security field and then invoking these per-process hooks from |
| 113 | the global hooks. The problem of composition is thus deferred to the |
| 114 | module. |
| 115 | |
| 116 | The global security_ops table is initialized to a set of hook functions |
| 117 | provided by a dummy security module that provides traditional superuser |
| 118 | logic. A :c:func:`register_security()` function (in |
| 119 | ``security/security.c``) is provided to allow a security module to set |
| 120 | security_ops to refer to its own hook functions, and an |
| 121 | :c:func:`unregister_security()` function is provided to revert |
| 122 | security_ops to the dummy module hooks. This mechanism is used to set |
| 123 | the primary security module, which is responsible for making the final |
| 124 | decision for each hook. |
| 125 | |
| 126 | LSM also provides a simple mechanism for stacking additional security |
| 127 | modules with the primary security module. It defines |
| 128 | :c:func:`register_security()` and |
| 129 | :c:func:`unregister_security()` hooks in the :c:type:`struct |
| 130 | security_operations <security_operations>` structure and |
| 131 | provides :c:func:`mod_reg_security()` and |
| 132 | :c:func:`mod_unreg_security()` functions that invoke these hooks |
| 133 | after performing some sanity checking. A security module can call these |
| 134 | functions in order to stack with other modules. However, the actual |
| 135 | details of how this stacking is handled are deferred to the module, |
| 136 | which can implement these hooks in any way it wishes (including always |
| 137 | returning an error if it does not wish to support stacking). In this |
| 138 | manner, LSM again defers the problem of composition to the module. |
| 139 | |
| 140 | Although the LSM hooks are organized into substructures based on kernel |
| 141 | object, all of the hooks can be viewed as falling into two major |
| 142 | categories: hooks that are used to manage the security fields and hooks |
| 143 | that are used to perform access control. Examples of the first category |
| 144 | of hooks include the :c:func:`alloc_security()` and |
| 145 | :c:func:`free_security()` hooks defined for each kernel data |
| 146 | structure that has a security field. These hooks are used to allocate |
| 147 | and free security structures for kernel objects. The first category of |
| 148 | hooks also includes hooks that set information in the security field |
| 149 | after allocation, such as the :c:func:`post_lookup()` hook in |
| 150 | :c:type:`struct inode_security_ops <inode_security_ops>`. |
| 151 | This hook is used to set security information for inodes after |
| 152 | successful lookup operations. An example of the second category of hooks |
| 153 | is the :c:func:`permission()` hook in :c:type:`struct |
| 154 | inode_security_ops <inode_security_ops>`. This hook checks |
| 155 | permission when accessing an inode. |
| 156 | |
| 157 | LSM Capabilities Module |
| 158 | ======================= |
| 159 | |
| 160 | The LSM kernel patch moves most of the existing POSIX.1e capabilities |
| 161 | logic into an optional security module stored in the file |
| 162 | ``security/capability.c``. This change allows users who do not want to |
| 163 | use capabilities to omit this code entirely from their kernel, instead |
| 164 | using the dummy module for traditional superuser logic or any other |
| 165 | module that they desire. This change also allows the developers of the |
| 166 | capabilities logic to maintain and enhance their code more freely, |
| 167 | without needing to integrate patches back into the base kernel. |
| 168 | |
| 169 | In addition to moving the capabilities logic, the LSM kernel patch could |
| 170 | move the capability-related fields from the kernel data structures into |
| 171 | the new security fields managed by the security modules. However, at |
| 172 | present, the LSM kernel patch leaves the capability fields in the kernel |
| 173 | data structures. In his original remarks, Linus suggested that this |
| 174 | might be preferable so that other security modules can be easily stacked |
| 175 | with the capabilities module without needing to chain multiple security |
| 176 | structures on the security field. It also avoids imposing extra overhead |
| 177 | on the capabilities module to manage the security fields. However, the |
| 178 | LSM framework could certainly support such a move if it is determined to |
| 179 | be desirable, with only a few additional changes described below. |
| 180 | |
| 181 | At present, the capabilities logic for computing process capabilities on |
| 182 | :c:func:`execve()` and :c:func:`set\*uid()`, checking |
| 183 | capabilities for a particular process, saving and checking capabilities |
| 184 | for netlink messages, and handling the :c:func:`capget()` and |
| 185 | :c:func:`capset()` system calls have been moved into the |
| 186 | capabilities module. There are still a few locations in the base kernel |
| 187 | where capability-related fields are directly examined or modified, but |
| 188 | the current version of the LSM patch does allow a security module to |
| 189 | completely replace the assignment and testing of capabilities. These few |
| 190 | locations would need to be changed if the capability-related fields were |
| 191 | moved into the security field. The following is a list of known |
| 192 | locations that still perform such direct examination or modification of |
| 193 | capability-related fields: |
| 194 | |
| 195 | - ``fs/open.c``::c:func:`sys_access()` |
| 196 | |
| 197 | - ``fs/lockd/host.c``::c:func:`nlm_bind_host()` |
| 198 | |
| 199 | - ``fs/nfsd/auth.c``::c:func:`nfsd_setuser()` |
| 200 | |
| 201 | - ``fs/proc/array.c``::c:func:`task_cap()` |