This site is now 100% read-only, and retired.

Making /tmp non-executable

Posted by Steve on Wed 15 Dec 2004 at 13:08

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-Invoke{"mount -o remount,exec /tmp";};
DPkg::Post-Invoke {"mount -o remount /tmp";};

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



Verifying mount options with 'mount'
Posted by docelic (213.202.xx.xx) on Mon 3 Jan 2005 at 18:34
You might do cat /proc/mounts instead of using mount (which reads file /etc/mtab) to avoid any confusion. If you remount the root partition read-only (or cause some similar trouble for the system), /etc/mtab will not be updated and it will stop representing an actual situation.

[ Parent ]

Problems with apt
Posted by chris (80.203.xx.xx) on Tue 4 Jan 2005 at 15:54
[ View Weblogs ]
The article suggests adding two lines to /etc/apt/apt.conf This didn't work for me - I had no /etc/apt/apt.conf so I created one - and it still complained that packages couldn't run files from /tmp duing an upgrade (preconfigure). I do have a /etc/apt/apt.conf.d directory with 70debconf in it. This file sets DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt || true";}; From man apt.conf I think it means that apt.conf.d files are run before apt.conf itself. So I moved the suggested lines from this article from apt.conf to /etc/apt/apt.conf.d/50tmp - so they should trigger before 70debconf's lines instead of after. It appears to have worked - but since this is stable with some backports the number of packages I've had are very low - will comment again if I find it's still not working.

[ Parent ]

What about /usr read-only?
Posted by Anonymous (216.220.xx.xx) on Wed 2 Mar 2005 at 18:09
Is it advisable to mount /usr read-only and use the same technique to remount it read-write during upgrades?

[ Parent ]

Re: What about /usr read-only?
Posted by Steve (82.41.xx.xx) on Wed 2 Mar 2005 at 18:34
[ View Weblogs ]

It doesn't really gain you very much as normal users cannot write to this directory - unlike /tmp.


[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (69.205.xx.xx) on Sun 1 May 2005 at 22:41
Another possible side effect of mounting /tmp noexec is that logrotate may fail when rotating apache2 and cupsd logs. I don't have a suggestion for a work around yet, but I imagine something could be put in the script in /etc/logrotate.d/apache2 to correct this.

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (69.205.xx.xx) on Tue 24 May 2005 at 02:18
OK, talking to myself, but I'll add this here for completeness. If you run into the problem I described above with logrotate failing on apache2 and cupsd logs, you can solve it by placing "TMPDIR=/var/tmp; export TMPDIR" in a logical place in /etc/cron.daily/logrotate. There is a debian bug for this, but I'm not sure what its status is. The fix is not well documented. It should be added to a debian readme for the logrotate package.

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (71.164.xx.xx) on Mon 2 Apr 2007 at 08:31
Is the problem with logrotate resolved yet, or is TMPDIR still necessary?

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (195.150.xx.xx) on Tue 20 Sep 2005 at 12:31
I had to use Pre-Invoke instad of Pre-Install-Pkgs, because otherwise I still was getting errors.

[ Parent ]

Re: Making /tmp non-executable
Posted by gonad (60.234.xx.xx) on Fri 11 Nov 2005 at 02:20
APT::ExtractTemplates::TempDir "/var/tmp";

Or another suitable directory, probably better than remounting.

[ Parent ]

Re: Making /tmp non-executable
Posted by spiney (128.131.xx.xx) on Fri 11 Nov 2005 at 11:57

I suppose it's just a matter of time until the typical exploit tries /var/tmp as well, if they don't do that already. So either remount, or use some completely other directory.

Of course if you're afraid of an script hitting /tmp while you install packages, you might use a combination of both. Even setting up a semi-random tmpfs mount at install time would do, but I guess that's a level of paranoia that I don't want to think about. ;) --
Debian GNU/Linux on an IBM Thinkpad T43p

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (82.181.xx.xx) on Thu 31 Jan 2013 at 11:41
Why then /var/tmp that maybe should indeed be noexec too, why not any other root-only-writable directory? In general setting a sane apt temp(late) dir is so much cleaner than remounting anything, that to me it looks almost like the entire article should be rewritten according to the parent comment (maybe with instructions for making a root-only temp dir). Perhaps even default layout should be changed so that package scripts won't break if /tmp is read-only - the fact that it does smells of being defective by design.

Ubuntu 12.04 x64 GNU/Linux on EeePC 1201N - still gathering the strength for documenting the install experience

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (123.2.xx.xx) on Tue 17 Nov 2015 at 03:06
That didn't work for me. I put the below into a new file called "/etc/apt/apt-conf.d/40tmp". This method prevents the dir from being used for malicious purposes simply by creating it and then deleting it when finished.

DPkg::Pre-Invoke{"mount -t tmpfs -o size=512m tmpfs /apt-tmp";};
DPkg::Post-Invoke{"umount /apt-tmp";};
TempDir "/apt-tmp";

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (67.85.xx.xx) on Tue 14 Feb 2006 at 02:09
The above line about running apt-get with /tmp noexec will not work...
you would need to change the following:


should be


otherwise it is too late in the process for pre-configuring packages (using Perl for example)

#man apt.conf

for more info.

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (153.94.xx.xx) on Mon 20 Feb 2006 at 11:09
The hack to use the dynamic elf loader to start a non exec file was fixed a while ago:

mrvn@storage:~% ls -lh /tmp/sh
-rwxr-xr-x 1 mrvn mrvn 713K Feb 20 12:05 /tmp/sh*
mrvn@storage:~% /lib/ /tmp/sh
/tmp/sh: error while loading shared libraries: /tmp/sh: failed to map segment from shared object: Operation not permitted


[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (190.169.xx.xx) on Mon 21 Jan 2008 at 16:14
My tmp is a directory not a different partition, what could be done ,if any, in that situation?

[ Parent ]

Re: Making /tmp non-executable
Posted by Steve (80.68.xx.xx) on Mon 21 Jan 2008 at 16:17
[ View Weblogs ]



[ Parent ]

Re: Making /tmp non-executable
Posted by xurizaemon (60.234.xx.xx) on Sun 9 Mar 2008 at 10:24
I disagree, it's quite simple to create a file-based partition and then apply this tactic. Please see my reply to parent comment (below).

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (174.240.xx.xx) on Fri 20 Feb 2015 at 05:40
or my mount only option... below also

[ Parent ]

Re: Making /tmp non-executable
Posted by xurizaemon (60.234.xx.xx) on Sun 9 Mar 2008 at 10:22

Make a file-based partition. Mount that as noexec /tmp. Done. All the below needs to be done as root, or with magic word ("sudo", not "please") in the right place.

  1. Make 100MB /tmp file-based partition
    dd if=/dev/zero of=/TMPFILE bs=1024 count=100000
    mkfs.ext3 /TMPFILE
  2. Add to /etc/fstab
    /TMPFILE /tmp ext3 loop,noexec,nosuid,rw 0 0
  3. Mount /tmp (you may need to restart services which keep socket files in /tmp after this!)
    mount /tmp
  4. If the final command fails, you may need to create your /dev/loop# entries. (Check if /dev/loop0 exists, for example.) If so, then:
    for ii in 0 1 2 3 4 5 6 7 8 ; do mknod -m660 /dev/loop$ii b 7 $ii ; done

[ Parent ]

Re: Making /tmp non-executable
Posted by Anonymous (174.240.xx.xx) on Fri 20 Feb 2015 at 05:33
or just:

mount -o bind /tmp /tmp;
mount -o remount,noexec,nosuid /tmp;

[ Parent ]

Re: Making /tmp non-executable
Posted by joeyo (24.211.xx.xx) on Sun 18 May 2008 at 02:11
If you have the memory for it, you could try mounting /tmp using tmpfs. Basically, this puts it on a ramdisk and should speed up access to files in /tmp as well. Put this line in your /etc/fstab:

/dev/shm /tmp tmpfs rw,bind,nosuid,noexec 0 0

Note that this will limit the size of /tmp to one half of your available RAM (by default) and that it will be cleared on reboot (usually the case anyway).

[ Parent ]