Making /tmp non-executable

Many simple exploits that are used against machines, (via vulnerable PHP applications or local users, etc), rely upon being able to execute commands in /tmp. If this is a seperate partition or file system you can gain some protection by marking it non-executable. The common problem with this is that apt-get fails to work with such a setup.

When you mount a partition there are many flags that can be used, two interesting ones are:


(A full list can be read as part of man mount).

The two flags are explained fully in the man page for mount, but briefly:

  • noexec
    • Do not allow execution of any binaries on the mounted file system.
  • nosuid
    • Do not allow set-user-identifier or set-group-identifier bits to take effect.

Mounting filesystems with these flags set raises the bar a little, but it doesn’t stop files from being executed. The Linux linker and loader will permit binaries to be run:

# Make /tmp non-executable
root@earth:~# mount -o remount,noexec /tmp

# Copy an executable into it
root@earth:~# cp /bin/ls /tmp
root@earth:~# chmod 755 /tmp/ls

# Test it - the execution should fail.
root@earth:~# /tmp/ls
bash: /tmp/ls: Permission denied

# But .. what's this?  It still runs?
root@earth:~# /lib/ /tmp/ls
Mail  public_html  

# cleanup
root@earth:~# rm /tmp/ls
root@earth:~# mount -o remount,exec /tmp

With that in mind you might wonder what the point is? Well it foils any simplistic attack that relies upon putting a script in /tmp and running it. If they’ve got shell access they can probably figure it out, but an automated tool would be foiled – for the moment.

To make your system have a non-executable /tmp partition you must edit the way that it is mounted in the file /etc/fstab. Find the line that contains /tmp and change the defaults to read nosuid,noexec instead.

For example this is my updated /etc/fstab file:

/dev/sda3       /tmp              ext3  noexec,nosuid           0       2

This will take effect the next time you mount the filesystem, you can do this now with:

mount -o remount /tmp

Very if it by running:

root@earth:/tmp# mount |grep /tmp
/dev/sda3 on /tmp type ext3 (rw,noexec,nosuid)

The output line should contain the two words ‘noexec,nosuid’ in it. If this is in place then you’re covered.

The only problem now is that when apt-get upgrades your system it will sometimes place scripts inside the temp directory which will now not be executable.

The fix for this is to temporarily make the temporary directory executable before running apt-get and then remove the execution bits afterwards. This would be a troublesome thing to remember doing ourselves – but thankfully we can set it up to be automatic.

Add the following to the file /etc/apt/apt.conf:

DPkg::Pre-Install-Pkgs {"mount -o remount,exec /tmp";};
DPkg::Post-Invoke {"mount -o remount /tmp";};

In Debian Etch (4.0) the file is named /etc/apt/apt.conf.d/70debconf

This contains two lines, one running before any packing installation and one afterwards. They merely execute the commands required to add and remove the execute permissions on the /tmp