Description
fs.protected_fifos and fs.protected_regular restrict O_CREAT opens of FIFOs and regular
files that already exist in a sticky directory and that the process does not own:
1: refused in world-writable sticky directories (such as/tmp) when the file is owned neither by the process nor by the owner of the directory;2: the same rule also applies to group-writable sticky directories.
Ubuntu ships fs.protected_fifos = 1 and fs.protected_regular = 2 (99-protect-links.conf
from procps, or 50-default.conf from systemd on 26.04), so core profiles pass on a fresh
install and hardened profiles raise fs.protected_fifos to 2.
Rationale
A program that "creates" a file in /tmp with a predictable name, without O_EXCL, opens the
file an attacker put there first instead. With a FIFO, the attacker reads what the program
writes or feeds it data; with a regular file, they control or read its content. These settings
block the attack in the kernel, whatever the quality of the program.
Impact
1 has no known impact and is the Ubuntu default. With 2, programs that share files or
FIFOs between users of a group through a group-writable sticky directory must open them
without O_CREAT or run as their owner.
Setting
| Location | sysctl `fs.protected_fifos` and `fs.protected_regular`, persisted in `/etc/sysctl.d/` |
| Default | fs.protected_fifos = 1, fs.protected_regular = 2 |
| Recommended | Both at least {{ protection_level }} |
Parameters
| Parameter | Core | Server | Server hardened | Desktop | Desktop hardened | Bounds |
|---|---|---|---|---|---|---|
protection_levelinteger. Minimum value of fs.protected_fifos and fs.protected_regular. 1 covers world-writable sticky directories, 2 adds group-writable ones. | 1 | 1 | 2 | 1 | 2 | 1 to 2 |
The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.
Audit
Run sysctl fs.protected_fifos fs.protected_regular. Both values must be at least
{{ protection_level }}. Then check that no sysctl configuration file sets a lower value.
Automated: every check must pass. Scanners report each check by its id.
fifos
Running value of fs.protected_fifos.
key: fs.protected_fifos
operator: '>='
value: '{{ protection_level }}'
regular
Running value of fs.protected_regular.
key: fs.protected_regular
operator: '>='
value: '{{ protection_level }}'
Remediation
For each key below {{ protection_level }}, add <key> = {{ protection_level }} to
/etc/sysctl.d/zz-cirsec.conf, then run sysctl --system. The file must sort after
/usr/lib/sysctl.d/99-protect-links.conf (protect-links.conf, without a number, on 20.04),
which sets both keys: a file named 60-*.conf or 99-*.conf would be overridden at the next
boot.
| Restart | none |
| Disruption | low |
Rollback
Remove the lines from /etc/sysctl.d/zz-cirsec.conf and run sysctl --system.
raise
# CB-UBU-BOOT-017: raise fs.protected_fifos / fs.protected_regular to CB_PROTECTION_LEVEL.
# Ubuntu sets both keys in /usr/lib/sysctl.d/99-protect-links.conf (protect-links.conf on 20.04),
# which sort after 60-cirsec.conf: the value goes in a file that sorts after both. Never lowers a value.
f=/etc/sysctl.d/zz-cirsec.conf
for k in fs.protected_fifos fs.protected_regular; do
cur=$(sysctl -n "$k") || exit 1
[ "$cur" -ge "$CB_PROTECTION_LEVEL" ] && continue
cb_backup "$f"
touch "$f"
sed -i "/^[[:space:]]*$(printf '%s' "$k" | sed 's/\./\\./g')[[:space:]]*=/d" "$f"
printf '%s = %s\n' "$k" "$CB_PROTECTION_LEVEL" >>"$f"
sysctl -q -w "$k=$CB_PROTECTION_LEVEL" || exit 1
done
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- Linux kernel documentation - Documentation for /proc/sys/fs/ (protected_fifos, protected_regular) The Linux Kernel Organization, vendor-doc, accessed 2026-10-19
- Ubuntu Security documentation - File handling (FIFO and regular file restrictions) Canonical, vendor-doc, accessed 2026-10-19
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R14) ANSSI, guide, accessed 2026-10-19
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R14 | partial | R14 asks for 2 on both keys among other filesystem settings; core profiles accept 1, hardened profiles require 2. |
| NIST SP 800-53 Rev. 55.1.1 | AC-6 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
Related controls
- related
CB-UBU-BOOT-006Protect symbolic links in world-writable sticky directories - related
CB-UBU-BOOT-007Protect hard links to files the user does not own
People and lifecycle
| Authors |
|
| Verified | 2026-10-19 by Sn0wAlice on 20.04, Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic, BIOS boot. Core passes on a fresh install (fifos 1, regular 2); server-hardened fails, fix writes fs.protected_fifos = 2 to zz-cirsec.conf; kept after reboot; fix idempotent. |
| Verified | 2026-10-19 by Sn0wAlice on 22.04, Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic, BIOS boot. Core passes on a fresh install (fifos 1, regular 2); server-hardened fails, fix writes fs.protected_fifos = 2 to zz-cirsec.conf; kept after reboot; fix idempotent. |
| Verified | 2026-10-19 by Sn0wAlice on 24.04, Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic, BIOS boot. Core passes on a fresh install (fifos 1, regular 2); server-hardened fails, fix writes fs.protected_fifos = 2 to zz-cirsec.conf; kept after reboot; fix idempotent. |
| Verified | 2026-10-19 by Sn0wAlice on 26.04, Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic, BIOS boot. Core passes on a fresh install (fifos 1, regular 2); server-hardened fails, fix writes fs.protected_fifos = 2 to zz-cirsec.conf; kept after reboot; fix idempotent. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-19, 2026-10-19 |
| Translations | fr |