diff options
Diffstat (limited to 'Documentation/security/lsm.rst')
-rw-r--r-- | Documentation/security/lsm.rst | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/Documentation/security/lsm.rst b/Documentation/security/lsm.rst new file mode 100644 index 000000000000..ad4dfd020e0d --- /dev/null +++ b/Documentation/security/lsm.rst | |||
@@ -0,0 +1,201 @@ | |||
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()` | ||