Blame view

Documentation/lsm.txt 10.5 KB
415008af3   Mauro Carvalho Chehab   docs-rst: convert...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  ========================================================
  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()`