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 Ubuntu the simplest way is the tmp.mount unit of systemd, which mounts a tmpfs (in memory,
emptied at each boot). Ubuntu 26.04 enables it by default with nodev and nosuid; Ubuntu 20.04,
22.04 and 24.04 keep /tmp on the root filesystem and ship the unit as an example in
/usr/share/systemd/.
The fix uses tmp.mount and a drop-in that adds noexec. On Ubuntu 20.04 to 24.04, /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. On 26.04 the
drop-in replaces the options of the shipped unit, which drops its optional per-user quota
(usrquota); add it back in the drop-in if user quotas on /tmp are wanted.
Snaps get their own private /tmp inside the host /tmp, so they follow the same options.
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 | 20.04 to 24.04: directory of the root filesystem. 26.04: 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 Ubuntu 20.04 to 24.04 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 Ubuntu 20.04 to 24.04, run
systemctl disable tmp.mount and delete /etc/systemd/system/tmp.mount), run
systemctl daemon-reload and reboot.
tmp-mount
# CB-UBU-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
# Ubuntu 20.04 to 24.04 ship tmp.mount as an example in /usr/share/systemd, 26.04 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-UBU-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-19
- systemd.mount(5), Ubuntu manual pages Canonical, vendor-doc, accessed 2026-10-19
- mount(8), Ubuntu manual pages (filesystem-independent mount options) Canonical, vendor-doc, accessed 2026-10-19
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R28) ANSSI, guide, accessed 2026-10-19
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-UBU-FS-004Mount /dev/shm with nodev, nosuid and noexec - related
CB-UBU-FS-006Mount separate filesystems with nodev, nosuid and noexec where they are not needed
People and lifecycle
| Authors |
|
| Verified | 2026-10-19 by Sn0wAlice on 20.04, Proxmox VM 2520, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic. Fails on fresh install (/tmp on the root filesystem); fix copies tmp.mount, /tmp becomes a tmpfs at reboot with nodev,nosuid,noexec; apt-get still installs packages, snaps still run; running a script from /tmp is refused. |
| Verified | 2026-10-19 by Sn0wAlice on 22.04, Proxmox VM 2522, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic. Fails on fresh install (/tmp on the root filesystem); fix copies tmp.mount, /tmp becomes a tmpfs at reboot with nodev,nosuid,noexec; apt-get still installs packages, snaps still run; running a script from /tmp is refused. |
| Verified | 2026-10-19 by Sn0wAlice on 24.04, Proxmox VM 2524, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic. Fails on fresh install (/tmp on the root filesystem); fix copies tmp.mount, /tmp becomes a tmpfs at reboot with nodev,nosuid,noexec; apt-get still installs packages, snaps still run; running a script from /tmp is refused. |
| Verified | 2026-10-19 by Sn0wAlice on 26.04, Proxmox VM 2526, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic. Fails on fresh install (tmp.mount without noexec); fix adds noexec through a drop-in and remounts at once; kept after reboot; apt-get still installs packages, snaps still run; running a script from /tmp is refused. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-19, 2026-10-19 |
| Translations | fr |