The basic unix security model is discretionary access control (DAC) and capabilities.
The Linux Security Modules (LSM) is a
framework (set of hooks) that allow extending access control to
the linux kernel via a security module.
vfs patching vs. path permission hooks
vfs patching used the existing hooks and passed addition
information (vfsmnt, file *) that was available in the vfs down
into the LSM. The goal being that LSM should have all available
information when making its decision. Patching the vfs in this
way was controversial for several reason.
it passed information through vfs routines that did not need it, making them not as clean
it added an extra parameters that didn't have a valid value in some situations
it was a large and invasive patch set
path permissions hooks is the solution for path based mediation
that went upstream. It adds a new hooks that are called with the
to avoid patching the vfs the hooks are added at different locations than the older inode hooks
the new hooks means often two hooks are called to make a security decision for an object
there is no state passed between the hooks to determine if one has already been called
the path hooks do not provide as much coverage as the inode hooks
The LSM provides a set of hooks (upcalls) inserted throughout the
kernel to provide extended permission mediation.
General points to consider
The LSM is configured by choosing CONFIG_SECURITY=y
Security options ---> Enable different security modules
If no security module built in to kernel or registers DAC permissions are used
most DAC checks are hard coded into the kernel
Security modules source resides in the linux kernel under the security/ directory
Security modules can not be loaded, they are built into the kernel (as 2.6.28? TODO double check git commit #)
Multiple security modules can be built into the kernel
An LSM must register with the security framework using security_module_enable
If multiple security modules are builtin then the first to register wins
security=kernel parameter can be used to set which security module to use on boot.
AppArmor and SELinux support a parameter to turn them off at boot regardless of other settings
e.g. apparmor=0 or selinux=0
As of 2.6.33 the default security module can be set via config option (Ubuntu and SuSE have carried patches to due this for several revisions)
Tag module init fn with security_initcall if module needs to start during early boot.
AppArmor does this in more
There is no generic stacking of security modules. In practice this means that AppArmor and SELinux can not be used at the same time.
There can be module controlled stacking if the modules cooperaterecent versions Ubuntu 9.10 (Karmic Koala)
There is a securityfs file system for LSMs to build their own dir fs/dir layout under
Usually mounted at /sys/kernel/security/
apparmor shows up as /sys/kernel/security/apparmor/
In general DAC checks are applied before calling into the LSM
The security modules does not see failures caused by DAC so it can not log them. The audit frame work can be used for this.
some security_path_hook come before DAC checks
LSM hooks are setup in a vector (include/linux/security.h)
Discretionary access control (DAC) is the standard unix permission
model. An LSM module can not directly disable DAC security checks,
which means the LSM is not well suited to implementing some potential
Most DAC checks can be worked around or disabled via the LSMs control
Security Pointers & SIDs
Many kernel objects have a void *security field which is used
by LSM modules to store security context information. It is up to an
LSM to determine how and when to use them.
On some objects a security id (SID) instead of a void * security
pointer is used. This is a unique id that the LSM should be able to
map back to its policy and determine confinement.
AppArmor uses the security field in the tasks cred, files, and will
use the inode security field for none file objects.
AppArmor currently has minimal support for SIDs, and its main current
use is in identifying unique learning profiles.
The way the kernel handles a tasks security credentials was changed
in 2.6.29? (TODO get commit number). All task credentials got
coalesced into a single shared security structure. This necessitated
a significant change on how AppArmor did locking and managed profiles
associated with tasks.
The cred struct is ref counted
The task that the cred is assigned to can access the cred without any locking or RCU
The cred struct can only be updated by the task it is assigned to
The task must do the update RCU style. ie. no direct modification of any value with in the struct
If another task A wishes to access another tasks B cred it must do all access within
An RCU block
with a reference count to the struct held
the cred->security field points to the AppArmor task_context
the code for dealing with AppArmor interaction with creds is in security/apparmor/context.c
AppArmor task_context is NOT reference counted, it relies on the cred reference count
AppArmor does not get the cred reference count except where necessary (ie when task being examined is not current)
generally only the code in lsm.c deals with the cred, as AppArmor uses the profile as its unit of confinement
Path Based mediation
?? Path discussion
path being valid at that instance of lookup, doesn't matter if racing
as long as pathname generated is consitent and valid for instant
Basics - vfsmnt, dentry pair needed. Calls into d_path
reasons not to do forward lookup
The dfa is used to perform all path name matching. It does a linear
search transitioning through 1 state per character, when it is done
with the input string it returns the state it finished in. This state
can then be used to start another match or to lookup the permissions
associated with the state.
For matches that require pairs (link pairs) a null transition between
the two matches is used.