Hardening Linux with Linux Security Module Framework and Yama
- WHAT?
The Linux Security Module (LSM) provides a mandatory access control layer in the Linux kernel. It works alongside traditional Discretionary Access Control (DAC) by intercepting system calls after DAC permission checks and applying additional security policies.
- WHY?
Use LSMs like Yama to harden system security by intercepting sensitive system calls after standard DAC checks, and understand how configuring them strengthens system security beyond basic user-level permissions.
- EFFORT
The average reading time of this article is approximately 40 minutes.
- REQUIREMENTS
Linux fundamentals: Understanding basic Linux commands, file permissions, directory structures and use of the command line.
1 About the Linux Security Module Framework #
The LSM (Linux Security Module) framework is a modular architecture within the Linux kernel that allows for the implementation of various security models, primarily MAC (Mandatory Access Control).
Rather than hard-coding security policies, the Linux kernel provides hook points at critical system calls—such as opening files or starting processes—that the LSM framework defines and manages. These managed hooks allow external modules such as SELinux or Yama to dynamically verify system actions. When a process attempts a sensitive operation, the kernel triggers these hooks to ask the loaded security module for permission; if the module's specific policy denies the request, the action is blocked even if the user has root privileges. This framework ensures that Linux remains flexible, allowing users to choose or stack different security layers based on their specific needs for system hardening.
The Linux security module framework includes the following modules:
Lockdown: The Lockdown module is an LSM designed to strengthen the boundary between user-space processes and the kernel by restricting access to features that could allow even a root user to modify the running kernel image. It operates in two primary modes:
integrity: blocks features that allow user space to modify the kernel, such as unsigned module loading or direct memory access via
/dev/mem.confidentiality: extends these restrictions to prevent users from extracting sensitive information from kernel memory, such as RSA private keys.
Landlock: The Landlock module empowers unprivileged processes to restrict their own access rights, effectively creating a tailored sandbox without requiring administrative or root privileges. Unlike traditional security modules that enforce system-wide policies, Landlock allows an application developer to define a safe subset of the file system that the program is permitted to access, blocking any unauthorized file reads, writes, or executions outside of that scope.
Capability: breaks down the traditionally all-or-nothing power of the root user into distinct and granular privileges. Instead of granting a process full administrative control, Linux assigns specific capabilities, such as
CAP_NET_BIND_SERVICE, to open low-numbered ports.SELinux: is a robust LSM module that implements a MAC (Mandatory Access Control) architecture, moving beyond the traditional user-owner permission model. It works by assigning security labels (contexts) to every process, file, and network port on the system. Then it enforces a central policy that dictates exactly how these entities can interact.
1.1 How LSM works #
Whenever a process attempts to access an object, like opening a file, sending a network packet, or creating a directory, the kernel first performs its standard DAC (Discretionary Access Control). This is the basic root versus user or read/write/execute permission check.
If DAC allows it, the LSM framework then steps in:
The kernel calls a hook, which is a redirection point.
The security module such as SELinux, checks its own specific policy.
The security module then returns a decision:
AllowedorDenied.
You can check which security modules are currently initialized on your Linux system:
cat /sys/kernel/security/lsm lockdown,capability,landlock,yama,selinux,bpf,ima,evm
1.2 Why is LSM necessary for system hardening? #
Before LSM was introduced, users who wanted to add a new security feature to Linux had to hack the kernel code directly. LSM solved this by:
Standardization: It created a stable interface so security developers did not have to rewrite their code every time the kernel updated.
Modularity: It allows users to choose the security model that best fits their needs, such as SELinux for high-security environments.
Stacking: Modern kernels allow you to stack multiple modules, so you can run something like Yama to protect against
ptraceattacks alongside AppArmor.
2 How does the Yama security module protect the Linux kernel? #
Yama is a Linux security module designed to enhance system-wide security by implementing DAC (Discretionary Access Control) for certain kernel functionalities.
It focuses on restricting the use of the ptrace system call, which is commonly used for debugging but can also be exploited for malicious purposes.
ptrace is a short form of process call, which is a powerful system call that allows one process to observe, control, and manipulate another process.
The Yama module is vital because it addresses a fundamental weakness in the traditional Linux process model, where any process could freely peek and poke into the memory of any other process owned by the same user.
By introducing configurable scopes, most notably the restriction that a process can only trace its own descendants, Yama prevents lateral movement by attackers. This means a compromised low-privilege application, like a Web browser or a chat client, cannot easily reach out to steal sensitive data from an SSH agent or a password manager running in the same session.
You can implement Yama, which is selectable at build time with CONFIG_SECURITY_YAMA and can be controlled at runtime through sysctls in /proc/sys/kernel/yama.
sysctl is a powerful interface used to examine and modify kernel parameters at runtime. However, because these settings can fundamentally change how the OS behaves, they are guarded by specific permissions.
When a setting is writable only with CAP_SYS_PTRACE, it means the kernel requires the process attempting the change to possess a specific capability.
The sysctl settings writable only with CAP_SYS_PTRACE are:
| Level | Name | Description |
|---|---|---|
| 0 | Classic | Regular Linux ptrace permissions (owner can attach). |
| 1 | Restricted | Only a parent process can ptrace its descendants. |
| 2 | Admin-only | Only processes with CAP_SYS_PTRACE can ptrace (usually root). |
| 3 | No-attach | Ptrace is disabled globally. Cannot be changed until reboot. |
3 How do I enable and configure Yama? #
Yama is built into most modern kernels, so you don't run it like a program. Instead, you configure its ptrace_scope .
Verify that your kernel was compiled with Yama support. Check for the existence of the Yama configuration file:
ls /proc/sys/kernel/yama/ptrace_scope
If this file exists, Yama is active. If you get a
No such file or directoryerror, Yama is likely not compiled into your kernel or not enabled as a security module at boot.To see which mode your system is currently using, read the value of the
ptrace_scopefile:cat /proc/sys/kernel/yama/ptrace_scope
0: Classic permissions (Least secure).
1: Restricted (Default on most systems; can only trace children).
2: Admin-only (Requires root).
3: Disabled (Highest security; cannot be changed without reboot).
You can change the security level temporarily to see how it affects your tools, for example,
strace:>sudosh -c 'echo 2 /proc/sys/kernel/yama/ptrace_scope'If the level is already set to 3, you cannot lower it using this method. Level 3 is a lockdown mode that persists until the next system reboot.
sleep 100 &
Note the PID.
Open a separate terminal and try to attach to it:
strace -p PID_NO. If Yama level 1 is active, you will see:attach: ptrace: Operation not permitted.Edit the sysctl configuration to make the Yama level permanent:
>sudovi /etc/sysctl.d/10-ptrace.confIf the file does not exist, you can create it or edit
/etc/sysctl.conf.Add the following line and apply the change:
kernel.yama.ptrace_scope = 1
>sudosysctl -p /etc/sysctl.d/10-ptrace.confOptional: If you want to ensure Yama is at level 3 (disabled) from the moment the system turns on, add
yama.ptrace_scope=3to your GRUB kernel boot parameters.
ptrace scope restrictionsThe kernel.yama.ptrace_scope setting is a security feature that restricts which processes can use ptrace.
When set to 1, a process only attaches to its own direct children.
You can choose either workarounds:
Permanent, persistent system-wide disable
(Preferred) Install the pre-configured package to handle the sysctl setup for you:
>sudozypper install aaa_base-yama-enable-ptraceCreate a configuration file and add the following line:
/etc/sysctl.d/90-disable-yama.conf
kernel.yama.ptrace_scope = 0Assign the
CAP_SYS_PTRACEcapability to the debugger via thesetcaputility from the libcap-progs package:>sudosetcap cap_sys_ptrace+ep /usr/bin/gdb
Temporary disablement of Yama
During runtime, set sysctl to
0:sysctl -w kernel.yama.ptrace_scope=0
Run the respective debugger as
root.
Disabling the ptrace restriction allows any program you run to control and spy on your other running applications, easing software debugging but creating a significant security risk.
To disable Yama ptrace restrictions temporarily, run the command sysctl -w kernel.yama.ptrace_scope=0 in your terminal to instantly allow debugging until the next reboot.
For a permanent change that survives system restarts, add the line kernel.yama.ptrace_scope = 0 to /etc/sysctl.d/99-ptrace.conf and apply it using the command sysctl --system.
For more information, refer to man 2 ptrace.
4 Troubleshooting Yama #
Troubleshooting Yama is essential because an overly restrictive ptrace_scope can silently break critical system operations, such as debugging with GDB or generating crash reports, directly impacting a developer's ability to diagnose software failures.
Common troubleshooting scenarios include:
- Debuggers (GDB) cannot attach to processes
This is the most common issue. You try to debug a running process with GDB or strace, and you get an
Operation not permittederror, even if you own the process. To resolve issues where a restrictive Yamaptrace_scope(typically levels 1 or 2) prevents a debugger from attaching to a process, lower the kernel's security constraints.First, check the current status of the scope:
cat /proc/sys/kernel/yama/ptrace_scope
Subsequently, update the value to
0to temporarily grant permissions for a user to debug their own non-privileged processes:>sudoecho 0 | sudo tee /proc/sys/kernel/yama/ptrace_scopeThis adjustment effectively relaxes the system's
ptracerestrictions, enabling standard debugging tools to function without being blocked by the Linux security module.- Permissions reverting after reboot
You manually set
ptrace_scopeto 0 to allow development work, but every time the machine reboots, it switches back to 1, breaking your workflow. Because the/procfile system is volatile, any manual changes to the YAMAptrace_scopeare lost upon reboot, as security-oriented distributions reset this value via default configuration files.To make a permanent adjustment, modify the persistent configuration located at
/etc/sysctl.d/10-ptrace.confor a similar path by changing the value ofkernel.yama.ptrace_scopefrom 1 to 0.Save the file and apply the changes with
sudo sysctl -p. This ensures that the relaxed debugging permissions remain active across system restarts.- Admin only debugging (scope 2)
You are a developer with
sudoaccess, but you still cannot attach to a process you started, even after trying to usesudo gdb. When the YAMAptrace_scopeis set to level 2 (Admin-only attach), the system enforces a strict security policy that prevents users and sometimes even root users from attaching to a process that is already running unless they possess specific capabilities likeCAP_SYS_PTRACE. To bypass this restriction without lowering the system's global security level, initiate the process directly through the debugger rather than attempting to hook into a pre-existing PID.>sudogdb --args ./my_programWith this method, the debugger acts as the parent process, establishing a legitimate relationship that permits full debugging control even under restrictive Yama settings.
5 For more information #
To learn more about the Linux security module usage: https://docs.kernel.org/admin-guide/LSM/index.html.
6 Legal Notice #
Copyright© 2006– 2026 SUSE LLC and contributors. All rights reserved.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or (at your option) version 1.3; with the Invariant Section being this copyright notice and license. A copy of the license version 1.2 is included in the section entitled “GNU Free Documentation License”.
For SUSE trademarks, see https://www.suse.com/company/legal/. All other third-party trademarks are the property of their respective owners. Trademark symbols (®, ™ etc.) denote trademarks of SUSE and its affiliates. Asterisks (*) denote third-party trademarks.
All information found in this book has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither SUSE LLC, its affiliates, the authors, nor the translators shall be held liable for possible errors or the consequences thereof.