Denying write access on /tmp: a quick fix to stop local privilege escalation

Why /tmp is a problem

/tmp is the classic “dump‑ground” for most Linux programs.
Because it’s world‑writable, a non‑root user can drop a rogue binary, swap out a shared library, or trick a set‑uid helper into loading code from there.
In 2025 a handful of local privilege‑elevation bugs (e.g., CVE‑2025‑1234) took advantage of that writable surface to inject payloads into privileged processes.
The fix? Make /tmp read‑only for everyone but root.

Quick fix: mount‑options for a read‑only /tmp

The most reliable way to enforce this is to remount /tmp with ro and the usual safety flags:

# /etc/fstab entry
tmpfs   /tmp   tmpfs   defaults,noexec,nosuid,nodev,ro   0   0

noexec stops binaries from running, nosuid ignores set‑uid bits, nodev blocks device nodes, and ro prevents any writes. After editing /etc/fstab, reboot or remount:

sudo mount -o remount,ro /tmp

Systemd‑based remount

If you prefer a systemd unit that runs at boot, create /etc/systemd/system/tmp.mount:

[Unit]
Description=Temporary Directory
Documentation=man:tmpfs(5)
DefaultDependencies=no
Before=local-fs.target

[Mount]
What=tmpfs
Where=/tmp
Type=tmpfs
Options=defaults,noexec,nosuid,nodev,ro

[Install]
WantedBy=local-fs.target

Enable it:

sudo systemctl daemon-reload
sudo systemctl enable --now tmp.mount

Trade‑offs and application compatibility

A read‑only /tmp breaks programs that expect to write there. The most common offenders are:

  • Package managers (apt, yum, dnf) that unpack archives into /tmp during installation.
  • Build tools (make, gcc) that create temporary object files.
  • Web servers that store session data or temporary uploads.
  • Desktop applications that use /tmp for IPC sockets.

If you hit a failure, you have a few options:

  1. Move the offending directory: Many services already support a custom temp directory. For example, systemd can be told to use /var/tmp for its runtime data via RuntimeDirectory= in unit files.

  2. Use systemd-tmpfiles: Create a rule that creates a writable subdirectory inside /tmp for a specific service, e.g.:

    /tmp/myapp 1777 root root -
    

    This gives the app its own sandboxed writable space while the rest of /tmp stays read‑only.

  3. Temporarily remount: For short‑lived tasks that need write access, remount /tmp as writable, run the task, then remount read‑only again.

Example: allowing apt to write

apt writes to /var/cache/apt/archives by default, but some older scripts may still use /tmp. The safest fix is to patch those scripts or set APT::Cache-Dir to a writable directory. If you must keep /tmp writable for apt, create a dedicated writable subdirectory:

sudo mkdir /tmp/apt
sudo chmod 1777 /tmp/apt

Then set APT::Cache-Dir to /tmp/apt in /etc/apt/apt.conf.d/99tmpcache.

Using tmpfs with nodev and noexec only

If you need /tmp to stay writable but want to mitigate the most common attack vectors, mount it as tmpfs with nodev and noexec only:

tmpfs   /tmp   tmpfs   defaults,noexec,nodev   0   0

This keeps the directory writable but blocks execution of binaries and device nodes. It is a middle ground that protects against many local exploits while preserving compatibility.

Monitoring and troubleshooting

After remounting, verify the mount options:

mount | grep ' /tmp '

You should see ro or noexec as appropriate. If a service fails, check its logs:

journalctl -u <service>

Common errors:

  • Permission denied: The service tried to write to /tmp. Create a dedicated writable subdirectory or adjust the service configuration.
  • Exec format error: A binary was executed from /tmp and noexec prevented it. Move the binary to a writable, executable directory like /usr/local/bin.

If you need to revert the change temporarily, remount with rw:

sudo mount -o remount,rw /tmp

Long‑term hardening

A read‑only /tmp is a good first step, but consider the following additional measures:

  • Set the sticky bit (chmod 1777 /tmp) to prevent users from deleting others’ files. This is already the default on most systems.

  • Use systemd-tmpfiles to clean /tmp automatically at boot or on a schedule, reducing the attack surface.

  • Audit /tmp with auditd to detect unexpected writes:

    auditctl -w /tmp -p w -k tmp-writes
    
  • Keep the kernel up to date. The kernel’s tmpfs implementation receives regular security patches; see the kernel changelog for updates.

Bottom line

Making /tmp read‑only for unprivileged users is a quick, effective mitigation against local privilege escalation that relies on writable temporary space. The trade‑off is reduced compatibility with legacy applications, but most modern services can be reconfigured or given isolated writable subdirectories. Use systemd units or fstab to enforce the mount options, monitor for failures, and adjust as needed. Combine this with sticky bits, tmpfiles.d cleanup, and kernel updates for a robust hardening strategy.


See also