Sie sind auf Seite 1von 5

Linux Security Modules (LSM)

Thursday, October 18, 2018 2:57 PM

Overview
The Linux Security Modules (LSM) framework is a generic framework for security modules in the Linux kernel. In essence,
a security module is a collection of callbacks to security hooks in key points of the kernel operation. The LSM allows
multiple modules to register themselves as security modules by registering to a sub-set of a pre-defined list of supported
security hooks, which are grouped into logical sets based on the kernel object (e.g. task, inode, file, sock, etc)
as well as some miscellaneous hooks for system operations (e.g. for binder.)

Introduction
From the Linux documentation [1]:
"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."

Implementation Details
The Evolution of LSM Throughout History
Historically, the LSM defined a global array of function hooks that were registered by a primary security module, and
supplied an interface to register additional modules, but the implementation details of module -stacking was defered to
the primary module [2]:
"Each LSM hook is a function pointer in a global table, security_ops [ ] 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 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 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 [ ] provides mod_reg_security and 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 defers the
problem of composition to the module."

This implementation was changed in version 4.2. In that same major refactor, the Linux capabilities were re-
implemented as a security module (and therefore there is always at least one security module in the system.)

Linux Page 1
I will only cover the new implementation details.

Security Hooks
The LSM defines a global structure of security hooks, security_hook_heads {1}. This structure is essentially an
array of linked-lists of callbacks, each list represents all callbacks to a specific security hook. The following is a small
snippet of that structure:

The list element is of type security_hook_list:

The pre-defined list of security hooks can be seen at {1}:

Comprehensive documentation for each hook can be seen in the (infinitely-long) comment before this union. For
example, here is the documentation for the binder_set_context_mgr() hook:

Linux Page 2
Security Module Initialization
The callback list of each security hook the LSM exposes are defined in the security_hook_heads global. It is
initialized to an array of empty linked-lists using the LIST_HEAD_INIT macro:

Each security module defines an array of callbacks to the security hooks it supports using the LSM_HOOK_INIT macro:

For example, this is how SELinux uses it to define selinux_hooks[]:

Which is later sent to security_add_hooks() to add it to the global hook lists.

security_add_hooks() is defined at {1}:

Hook Dispatchment
Each hook supported by the LSM begins by a voluntary call to the LSM from the hooked function. This is the non -generic
part of the LSM which introduces code modification to each function that is hooked for security purposes.

As an example, we will take a look at the security hook for file renaming. For the complete flow of this security hook
under SELinux, please refer to the SELinux access check flow paragraph.

vfs_rename() performs the voluntary call to the LSM in order to make sure all security modules audit and allow this
operation:

Linux Page 3
operation:

security_inode_rename() is one of the many security_xxx() functions implemented in {2}. Most of these
functions wrap around one of the two: call_int_hook() or call_void_hook(). These functions traversal the
list of callback defined for the specified security hook and call each one in order. The difference between them, is that
call_int_hook() is used to check if the operation is allowed, and therefore assures that no callback disallow the
operation (and quits on the first one that does, if such an event occurs.) call_void_hook() does not return a value
and therefore cannot disallow an operation; thus, it will most-likely be used for auditing purposes. The definitions of
these macros follow (taken from {2}):

Source Code References

Linux Page 4
Source Code References
1. include/linux/lsm_hooks.h
○ security_hook_heads
○ security_hook_list
○ LSM_HOOK_INIT
○ security_add_hooks()
2. security/security.c
○ security_hook_heads
○ security_inode_rename()
○ call_void_hook()
○ call_int_hook()

External References
1. Linux Documentation, Documentation/DocBook/lsm.tmpl (in sources)
2. Implementing SELinux as a Linux Security Module, NSA.
https://www.nsa.gov/resources/everyone/digital-media-center/publications/research-
papers/assets/files/implementing-selinux-as-linux-security-module-report.pdf

Linux Page 5

Das könnte Ihnen auch gefallen