LSM and Access Control

On this page

Unix permissions allow, yet services may still be denied by policy; possessing a capability does not imply that all related operations will pass. Access control requires interpreting the subject, object, operation, and policy combination together.

DAC includes owner/group/other and ACLs, typically allowing the object owner to arrange access; mandatory policies can further constrain the service domain.

Target to consultLocation to read
LSM and labels/profilesSections 1–3
Capabilities and BPF policiesSections 4–5
Keyrings, integrity, and runtime stateSections 6–7

1. LSM provides check points; modules provide policies

A file access must satisfy multiple independent conditions Call and path checks Is the object and operation valid? Basic permission checks DAC / ACL / capability Enabled LSM checks Labels, profiles, and other policies Execute file operation I/O errors may still occur The diagram illustrates constraint relationships; actual kernel checks are distributed across multiple paths. Allowance at one layer does not automatically bypass others; LSM does not only run at syscall entry points.

LSM hooks are located in the operation paths of kernel objects such as files, credentials, processes, and networks; a single system call may trigger multiple checks, and internal kernel operations may also pass through these points. Hooks include functions that return decisions, as well as notifications for allocating, releasing, or updating security state. It is incorrect to uniformly state that "all hooks returning an error result in denial."

For example, security_file_open() uses a file_open hook with a return value; it is invalid to write it as call_void_hook() and then claim to check for errors. Reading the target version's security/security.c and include/linux/lsm_hook_defs.h is more reliable than copying old hook list structures.

For common denial-type permission hooks, enabled modules participate in checks according to defined combination rules; a denial by one module cannot be overridden by an allowance from another. It is incorrect to draw SELinux and AppArmor as running in fixed parallel on all systems: the actual combination and order of enabling depend on the kernel version, configuration, and boot parameters. When securityfs is visible, /sys/kernel/security/lsm lists the currently active modules.

The name "LSM" does not imply they are ordinary modules that can be freely insmod/rmmod. Framework concepts are described in the LSM documentation, where historical structure explanations should be read in conjunction with current source code.

2. SELinux: Subject domains and object types

SELinux security contexts typically contain user, role, type, and level/range. For example, httpd_sys_content_t in a file label is an object type; service processes run in a specific domain.

When reading a type enforcement denial record, align the following four items:

FieldQuestion to confirm
source contextWhich subject domain initiated the access?
target contextWhat type is the object actually?
object classIs it a file, directory, or other object?
permissionWhich operation was denied: read, search, etc.?

Looking only at the path can lead to missing labels, domain transitions, or directory search permissions. Rules express the permission for a source domain to perform operations on a specific type of target object.

The AVC cache stores access decisions to reduce query costs. Label sources include filesystem extended attributes and labels generated by the policy for specific objects; the labeling methods for procfs, tmpfs, etc., cannot be uniformly stated as all generated by genfscon.

Enforcing mode denies access according to policy; permissive mode typically logs accesses that would have been denied without enforcing the SELinux denial. Other DAC, LSM, and system errors can still cause operations to fail, so permissive does not mean all operations will succeed. Auditing is also affected by policy and log configuration, so it is incorrect to assume a new log entry is generated for every decision.

3. AppArmor and Smack: Different policy expressions

AppArmor centers on program profiles; file access rules are often expressed by path and can restrict capabilities, network operations, etc. Different programs under the same Unix user can thus be subject to different constraints.

Path-based policies require understanding the process's mount view, aliases, renaming, and linking rules, but one cannot directly conclude that "creating a hardlink or bind mount will bypass AppArmor." Links and mounts are also subject to checks; the profile, policy namespace, and specific rules determine the outcome. The following are merely fragments of rule syntax, not a complete, deployable service profile:

/var/www/** r,
/var/log/example/*.log w,
capability net_bind_service,

It lacks program loading, dynamic libraries, directory access, and complete runtime dependencies. Theoretically understanding a rule is a different task from having an available and sufficiently convergent policy. See the AppArmor documentation.

Smack also uses subject/object labels and access rules, but has its own rules and special label semantics. It is not a version of "SELinux with a fixed percentage of features removed"; the choice mechanism should compare actual expressive power and deployment environments. See the Smack documentation.

4. Capabilities: Splitting privileges, not generating a complete sandbox

Kernel capability semantics are based on thread credentials, including permitted, effective, and inheritable sets, as well as bounding and ambient sets. Conventional permission checks care about the relevant capabilities in the effective set; how they are recalculated during exec depends on conditions such as file capabilities, set-ID bits, and securebits.

  • CAP_NET_RAW involves permissions for raw/packet sockets, etc.
  • CAP_SYS_PTRACE can participate in bypassing some ptrace credential restrictions, but other checks still apply.
  • CAP_NET_BIND_SERVICE involves protected low ports; port threshold settings in network namespaces also affect whether it is needed.
  • CAP_SYS_ADMIN covers a wide range; it is inappropriate to interpret the name as a narrow operation.

Capabilities within a user namespace are only valid within the applicable namespace and object relationships; root inside a container does not automatically possess all the capabilities of the host root. Conversely, removing capabilities does not eliminate all interfaces that a regular user could otherwise use. See capabilities(7).

Separate the scopes of DAC and capabilities, LSM, and read-only filesystem conditions. The following presents the combination of these constraints, rather than disguising them as a single function call order that all systems fixedly follow.

Preparing the visual
Can one allowance override another denial?

An applicable capability can satisfy specific DAC bypass conditions, but it cannot change an LSM denial or a read-only filesystem into an allowance. Root within a user namespace is also not a pass for all host objects.

5. BPF LSM: Verified programs may still write incorrect policies

BPF LSM allows extending supported hooks via permission-controlled BPF programs. libbpf can handle loading and linking, while CO-RE/BTF helps adapt to kernel types.

For system-wide MAC hooks, when multiple BPF programs are chained, programs should preserve previous denial results according to the interface specification; it is incorrect to unconditionally change a non-zero ret passed in to 0. Different attach types have different return semantics, so one cannot directly apply the return value rules from one example to all BPF LSM programs.

The verifier checks acceptable memory access, control flow, and other conditions, reducing the risk of the program damaging the kernel; it does not prove the correctness of business authorization logic, nor does it promise that the kernel/verifier is forever bug-free. Deploying incorrect policies can still block normal work. See the BPF LSM documentation.

6. Keyrings, IMA, and EVM

The kernel keyring manages key objects with types, permissions, and lifetimes, and supports linking keys to keyrings. It is not a global dictionary allowing all users to read all keys, nor does it guarantee that every key payload is protected by hardware; trusted, encrypted, and other key types have their own encapsulation and root trust mechanisms.

Measurement records and denial upon use are different goals

IMA measurement measures objects such as files according to policy, retains measurement logs, and can extend TPM PCRs. It does not recompute the entire file for every byte read, nor does it store the hash of every file separately in the TPM. Remote verification requires understanding the log, PCRs, trusted attestation, and expected state simultaneously.

IMA appraisal, on the other hand, verifies file integrity/authenticity according to policy and decides whether to deny use. EVM protects the integrity of selected security extended attributes and related metadata, using HMAC or signatures. Measurement, denial of execution, and disk content encryption are three different goals; having only measurement logs does not automatically prevent tampered programs from running.

7. Read-only observation of the current environment

from pathlib import Path

for name in ('/sys/kernel/security/lsm', '/sys/fs/selinux/enforce',
             '/proc/self/attr/current'):
    try:
        print(name, Path(name).read_text().strip())
    except OSError as exc:
        print(name, type(exc).__name__)
for line in Path('/proc/self/status').read_text().splitlines():
    if line.startswith(('Cap', 'NoNewPrivs:', 'Seccomp:')):
        print(line)

File invisibility may stem from securityfs not being mounted, configuration, permissions, or container views; one cannot assert that the system has no access control solely based on read failures. Actual authorization issues should be analyzed in conjunction with the service process's credentials, namespaces, labels/profiles, and denial logs, rather than only checking the current shell.

References: Kernel key management, Integrity mechanisms source code.