lsm.txt 11 KB

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