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