Guarding /tmp: How fs.protected_symlinks and fs.protected_regular Harden Your Kernel
Enable fs.protected_symlinks and fs.protected_regular to block symlink and hardlink races in /tmp. Learn how to verify, enable, test, and what side‑effects to watch for.
17 Oct 2025, 17:03 UTC

Problem: Symlink & Hardlink Races in World‑Writable Directories
On almost every Linux system, /tmp and /var/tmp are world‑writable and sticky. The sticky bit guarantees that only the file owner, the directory owner, or root can delete a file. However, it does not stop an attacker from creating a symlink or hardlink that points to a sensitive file owned by root or another user. If the kernel blindly follows those links, a privileged process that opens the file via the attacker‑controlled name can gain unintended access. This is the classic symlink race or hardlink race vulnerability.
Thesis: Enable fs.protected_symlinks and fs.protected_regular to Block These Races
Linux provides two sysctls that guard against these attacks:
fs.protected_symlinks– blocks following symlinks in sticky world‑writable directories when the symlink owner differs from the directory owner.fs.protected_regular– blocks opening regular files via hardlinks in the same scenario unless the caller owns the file or has theCAP_DAC_OVERRIDEcapability.
Both are enabled by default on many modern distributions, but they can be disabled in containers or custom kernels. This blog walks through how to verify, enable, and test these protections, and what side effects to watch for.
1. Understanding the Sysctls
fs.protected_symlinks and fs.protected_regular are read‑write values under /proc/sys/fs/. They accept 0 (disabled) or 1 (enabled). The kernel checks the sticky bit and ownership before following a symlink or opening a file via a hardlink. If the check fails, the kernel returns EPERM.
These sysctls do not replace mandatory access control (e.g., SELinux, AppArmor) or safe temporary‑file creation practices (e.g., O_TMPFILE, mkstemp). They are an additional layer that mitigates a specific class of race conditions.
2. Enabling and Verifying the Protection
Check Current Values
# sysctl fs.protected_symlinks
fs.protected_symlinks = 1
# sysctl fs.protected_regular
fs.protected_regular = 1
Alternatively, read the proc files directly:
# cat /proc/sys/fs/protected_symlinks
1
# cat /proc/sys/fs/protected_regular
1
If either value is 0, you can enable it with sysctl -w:
# sysctl -w fs.protected_symlinks=1
fs.protected_symlinks = 1
# sysctl -w fs.protected_regular=1
fs.protected_regular = 1
To make the change persistent, create a drop‑in file in /etc/sysctl.d/:
# cat /etc/sysctl.d/10-protect-tmp.conf
fs.protected_symlinks = 1
fs.protected_regular = 1
Reload the sysctl configuration:
# sysctl --system
Verify again with sysctl -a | grep fs.protected.
Test the Protection
We’ll simulate a symlink race by creating a symlink in /tmp that points to /etc/passwd and attempting to read it as root. The kernel should block the operation.
# su - root
# touch /tmp/testfile
# ln -s /etc/passwd /tmp/symlink_to_passwd
# cat /tmp/symlink_to_passwd
cat: /tmp/symlink_to_passwd: Permission denied
If you see the file contents instead, the protection is not active. Also test a hardlink race:
# ln /etc/passwd /tmp/hardlink_to_passwd
# cat /tmp/hardlink_to_passwd
cat: /tmp/hardlink_to_passwd: Permission denied
Both should return Permission denied when fs.protected_regular is enabled.
3. Real‑World Use Cases & Limitations
Many legitimate workloads create temporary files under /tmp for inter‑process communication, build artifacts, or container entrypoints. Some of these workflows rely on creating hardlinks across users, for example:
- Build systems that copy a shared library into a user’s
/tmpvia hardlink. - Container runtimes that mount a volume into
/tmpand create hardlinks to a pre‑downloaded image. - Setuid helpers that open a temporary file created by another user.
When fs.protected_regular is enabled, such operations will fail with Permission denied unless the process owns the file or has CAP_DAC_OVERRIDE. This can break automation scripts, CI pipelines, or container entrypoints that were written before these sysctls existed.
Similarly, fs.protected_symlinks can interfere with applications that legitimately use symlinks in /tmp, such as:
- Applications that download a file to
/tmpand then symlink it into a working directory. - Backup utilities that create symlinks to snapshot files in a shared temporary directory.
In such cases, the workaround is to move the operation to a directory without the sticky bit (e.g., /var/tmp if it is not sticky) or to use O_TMPFILE or mkstemp for safe temporary file creation.
4. Trade‑Offs and When to Disable
- Security vs Compatibility: Enabling the sysctls reduces the attack surface but may break scripts that assume unrestricted symlink/hardlink creation.
- Container Environments: Some container images deliberately disable these protections to allow the container runtime to manage temporary files. If you control the image, consider enabling them in the host and using
--tmpfsmounts with appropriate permissions. - Audit and Monitoring: If you rely on hardlinks for auditing or forensic purposes, you might need to adjust your workflow or use a dedicated directory with the sticky bit cleared.
5. Actionable Checklist
- Verify current values:
sysctl fs.protected_symlinks fs.protected_regular. - Enable both sysctls if not already set:
sysctl -w fs.protected_symlinks=1 fs.protected_regular=1. - Persist the changes: create
/etc/sysctl.d/10-protect-tmp.confwith the two lines. - Reload sysctl:
sysctl --system. - Run the test cases above to confirm denial of symlink/hardlink access in sticky directories.
- Audit your scripts and applications that use
/tmpor/var/tmpfor symlink/hardlink creation. Refactor to useO_TMPFILEor dedicated non‑sticky directories if necessary. - Document the change in your security policy and monitor for
EPERMerrors in logs that may indicate legitimate failures.
By enabling fs.protected_symlinks and fs.protected_regular, you add a robust defense against a class of privilege‑escalation attacks that target world‑writable temporary directories. The trade‑off is a small compatibility cost that can be mitigated with careful refactoring. The payoff is a kernel that refuses to follow malicious links, keeping your root‑owned files safe from unintended exposure.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.