Description
/tmp is a separate filesystem mounted with:
nodev: device files on it are not usable;nosuid: setuid and setgid bits on it are ignored;noexec: programs on it cannot be executed directly.
On Debian the simplest way is the tmp.mount unit of systemd, which mounts a tmpfs (in memory,
emptied at each boot). Debian 13 enables it by default with nodev and nosuid; Debian 12 keeps
/tmp on the root filesystem and ships the unit as an example in /usr/share/systemd/.
The fix uses tmp.mount and a drop-in that adds noexec. On Debian 12, /tmp becomes a tmpfs at
the next reboot only: mounting it on a running system would hide files that programs are using.
Files left in the old on-disk /tmp are then hidden under the mount. When /tmp is a partition
declared in /etc/fstab, the fix stops and the options must be added by hand.
Rationale
/tmp is writable by every user and every service. Attackers drop their tools there and run
them, and a setuid file or device node placed there by a compromised account can be abused.
noexec, nosuid and nodev stop these uses. A separate filesystem also keeps a user or a
runaway process that fills /tmp from filling the root filesystem.
Impact
Scripts and binaries in /tmp cannot be run directly (./script); sh /tmp/script still works,
so noexec is a hurdle, not a barrier. A few installers and build tools that run helpers from
/tmp fail: point their TMPDIR elsewhere. A tmpfs /tmp uses memory (up to half of the RAM)
and loses its content at reboot.
Setting
| Location | /etc/systemd/system/tmp.mount.d/60-cirsec.conf, or /etc/fstab |
| Default | Debian 12: directory of the root filesystem. Debian 13: tmpfs with nodev,nosuid |
| Recommended | Separate filesystem (tmpfs) with nodev,nosuid,noexec |
Audit
Run findmnt -kn /tmp. It must print a line (separate filesystem) whose options contain
nodev, nosuid and noexec.
Automated: every check must pass. Scanners report each check by its id.
mount
/tmp is a mount point and its options include nodev, nosuid and noexec.
script: |
o=$(findmnt -kn -o SOURCE,FSTYPE,OPTIONS --mountpoint /tmp | tail -n 1)
[ -n "$o" ] || { echo "/tmp is not a separate filesystem"; exit 1; }
echo "/tmp $o"
rc=0
for opt in nodev nosuid noexec; do
case ,${o##* }, in *,$opt,*) ;; *) echo "missing $opt"; rc=1 ;; esac
done
exit $rc
Remediation
With a tmpfs (recommended):
- On Debian 12 only:
cp /usr/share/systemd/tmp.mount /etc/systemd/system/thensystemctl enable tmp.mount. - Create
/etc/systemd/system/tmp.mount.d/60-cirsec.conf:[Mount] Options=mode=1777,strictatime,nosuid,nodev,noexec,size=50%%,nr_inodes=1m - Run
systemctl daemon-reload. If/tmpis already a tmpfs, runmount -o remount,nodev,nosuid,noexec /tmp; otherwise reboot.
With a partition declared in /etc/fstab: add nodev,nosuid,noexec to the options of the
/tmp line, then run mount -o remount /tmp.
| Restart | system reboot |
| Disruption | low |
Rollback
Delete /etc/systemd/system/tmp.mount.d/60-cirsec.conf (and, on Debian 12, run
systemctl disable tmp.mount and delete /etc/systemd/system/tmp.mount), run
systemctl daemon-reload and reboot.
tmp-mount
# CB-DEB-FS-003: mount /tmp as a tmpfs with nodev, nosuid and noexec through systemd's tmp.mount.
if awk '$1 !~ /^#/ && $2 == "/tmp"' /etc/fstab | grep -q .; then
echo "/tmp is defined in /etc/fstab: add nodev,nosuid,noexec to its options by hand" >&2
exit 1
fi
if [ -L /tmp ]; then
echo "/tmp is a symbolic link, tmp.mount does not apply" >&2
exit 1
fi
# Debian 12 ships tmp.mount as an example in /usr/share/systemd, Debian 13 as an active unit.
if ! systemctl cat tmp.mount >/dev/null 2>&1; then
[ -f /usr/share/systemd/tmp.mount ] || { echo "no tmp.mount unit available" >&2; exit 1; }
cb_backup /etc/systemd/system/tmp.mount
cp /usr/share/systemd/tmp.mount /etc/systemd/system/tmp.mount
fi
f=/etc/systemd/system/tmp.mount.d/60-cirsec.conf
cb_backup "$f"
mkdir -p /etc/systemd/system/tmp.mount.d
printf '%s\n' '# Written by CIRSEC Baselines CB-DEB-FS-003' '[Mount]' \
'Options=mode=1777,strictatime,nosuid,nodev,noexec,size=50%%,nr_inodes=1m' >"$f"
chmod 644 "$f"
systemctl daemon-reload
[ "$(systemctl is-enabled tmp.mount 2>/dev/null)" = disabled ] && systemctl enable tmp.mount
# Mounting a new tmpfs over a live /tmp would hide files in use: only remount an existing tmpfs.
if [ "$(findmnt -kn -o FSTYPE --mountpoint /tmp | tail -n 1)" = tmpfs ]; then
mount -o remount,nodev,nosuid,noexec /tmp
else
echo "/tmp becomes a tmpfs at the next reboot"
fi
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
- systemd - Using /tmp/ and /var/tmp/ Safely systemd project, vendor-doc, accessed 2026-10-18
- systemd.mount(5), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- mount(8), Debian manual pages (filesystem-independent mount options) Debian, vendor-doc, accessed 2026-10-18
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R28) ANSSI, guide, accessed 2026-10-18
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R28 | partial | R28 covers the whole partitioning; this control covers /tmp. |
| NIST SP 800-53 Rev. 55.1.1 | CM-7 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
Related controls
- related
CB-DEB-FS-004Mount /dev/shm with nodev, nosuid and noexec - related
CB-DEB-FS-006Mount separate filesystems with nodev, nosuid and noexec where they are not needed
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM 922, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Fails on fresh install (/tmp on the root filesystem); fix copies tmp.mount, /tmp becomes a tmpfs at reboot; fix adds noexec through a tmp.mount drop-in; tmpfs with nodev,nosuid,noexec after reboot; apt-get still installs packages; running a script from /tmp is refused. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM 932, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Fails on fresh install (tmp.mount without noexec); fix remounts at once; fix adds noexec through a tmp.mount drop-in; tmpfs with nodev,nosuid,noexec after reboot; apt-get still installs packages; running a script from /tmp is refused. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |