Commit | Line | Data |
---|---|---|
415008af MCC |
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()` |