Skip to content

Security Module Stacks That Don't Fall Over - Casey Schaufler, The Smack Project

Casey Schaufler

Blue TeamThe Linux Foundation33 minOpen on YouTube ↗

Details security Module Stacks That Dont Fall Over - Casey Schaufler, The Smack Project and evaluates key implications for security practitioners.

Summary

### Overview In this talk, Casey Schaufler discusses ongoing efforts to implement comprehensive Linux Security Module (LSM) stacking in the Linux kernel. Originally created so Linus Torvalds would not need to referee kernel security policy debates, the LSM framework uses a bail-on-fail model where modules are called in order, stopping at the first failure. While minor modules (such as Capabilities, Yama, and LoadPin) do not manage their own state and can run alongside one major module, stacking multiple major modules (such as SELinux, Smack, AppArmor, and Tomoyo) has historically been blocked by architectural constraints in kernel data structures, packet networking, and userspace interfaces.

### Key Topics - **Minor vs. Major Security Modules**: Minor modules rely on existing state, while major modules manage their own state and attach security data to kernel objects (inodes, tasks, credentials) or use networking mechanisms like NetLabel and Secmark. - **LSM Infrastructure-Managed Security Blobs**: Solving the single-pointer limitation where competing modules overwrite object security blob pointers. - **SecID Multiplexing and Secmark Constraints**: Addressing the hard 32-bit limit on security identifiers in IP packet processing when multiple modules need SecIDs. - **Mount Option Parsing**: Preventing kernels from failing file system mounts when an option is recognized by one LSM but rejected by another. - **Network Labeling Conflicts (NetLabel & CIPSO/CALIPSO)**: Managing disagreements over CIPSO packet tags, differing labeling granularities, and push vs. pull attribute models. - **Userspace Compatibility & Developer Guidelines**: Managing tools like `id -Z`, `ls -Z`, `/proc/self/attr/` directory disambiguation, and best practices for authoring new LSMs.

### Technical Details - **Blob Pointer Sharing**: Previously, kernel structures like `inode` and `cred` only had a single void pointer for security data. Stacking solves this by having the LSM infrastructure manage the allocated blob. Each module registers its required size at initialization, and the infrastructure assigns each module a specific offset into the shared blob. - **SecID Structures**: SecIDs are 32-bit integers used to reference security context data, notably within Secmark in IP networking. Because networking maintainers strictly limit Secmark to 32 bits, the infrastructure must replace individual 32-bit SecID references with a composite structure (or union when not stacking) mapping SecIDs across active modules. For user queries like `SO_PEERSEC`, a default (the first credential-supporting module) is returned unless explicitly selected using a `prctl` interface. - **Mount Options**: By default, unrecognized mount options cause mount failures. Stacking requires modules to ignore unrecognized options rather than immediately failing, with the caveat that wholly invalid options might pass undetected until broader mount API redesigns land. - **NetLabel and CIPSO**: The network stack permits only one CIPSO tag per packet. Because SELinux and Smack handle CIPSO differently—SELinux only labels MLS components while Smack places full labels by default—combining them without conflict is nearly impossible. The system must deny traffic unless modules agree, making concurrent network-heavy MAC modules generally impractical. - **Procfs Attributes**: Historically, `proc/self/attr/current` pointed directly to a single module's context. To support stacking without breaking userspace, subdirectories for each specific LSM (e.g., `proc/self/attr/<lsm>/current`) are introduced, while `sys/kernel/security/lsm` lists active modules.

### Takeaways - LSM infrastructure-managed blobs remove the primary barrier to stacking modules like AppArmor or Tomoyo alongside others, with full stacking becoming progressively feasible. - Developers creating new LSMs should make networking features optional, avoid claiming exclusive network control unless necessary, and carefully manage external allocated state because a failure in an earlier module prevents subsequent hooks from running. - Stacking redundant full mandatory access control (MAC) policies like SELinux and Smack together is unnecessary and creates severe networking conflicts; stacking is best utilized for combining different security paradigms (such as AppArmor with another module) and encouraging new access control models.

Related talks