Log in

No account? Create an account

Previous Entry Share Next Entry
Fedora 17 New Security Feature part II - PrivateTmp
One of the reasons I am really excited about Fedora 17 is amount of new Security Features we have added, and not all of them involve SELinux ...

As  I blogged a few weeks ago, we have stopped the ability for one process to look at another processes memory even if they have same UID, with the deny_ptrace feature.


But today I want to talk about PrivateTmp.    One of my goals over the years has been to stop system services from using /tmp. 

I blogged about this back in 2007.    Any time I have found out a daemon was using /tmp, I tried to convince the packager to move the content to /run directory if it was temporary or /var/lib if it was permanent. 

Over the years there have been several vulnerabilities  (CVEs) about this.  For example:
CVE-2011-2722, which covered a case where hplib actually included code like.

fp = fopen ("/tmp/hpcupsfax.out", "w"); // <- VULN
system ("chmod 666 /tmp/hpcupsfax.out"); // <- "

Meaning if you setup a machine running cups daemon, a bad user or a application that a user ran could attack your system.

I have convinced a lot of packages to stop using /tmp, but I can't get them all and in some cases services like Apache,  need to use /tmp.   Apache runs lots of other packages that might store content in /tmp.

Well systemd has added lots of new security features (more on these later).  

PrivateTmp, which showed up in Fedora 16,  is an option in systemd unit configuration files. 

      > man system.unit
       A unit configuration file encodes information about a service, a socket, a device, a mount point, an automount point, a   
     swap file or partition, a start-up target, a file system path or a timer controlled and supervised by systemd(1).

     > man systemd.exec
       systemd.exec - systemd execution environment configuration
       systemd.service, systemd.socket, systemd.mount, systemd.swap
       Unit configuration files for services, sockets, mount points and swap devices share a subset of configuration 
       options which define the execution environment of spawned processes.
           Takes a boolean argument. If true sets up a new file system namespace for the executed processes and mounts a 
           private /tmp directory inside it, that is not shared by processes outside of the namespace. This is useful to secure 
           access to temporary files of the process, but makes sharing between processes via /tmp impossible. 
           Defaults to false.
PrivateTmp causes systemd to do the following any time it starts a service with this option turned on:

   Allocate a private "tmp" directory
   Create a new file system namespace 
   Bind mount this private "tmp" directory within the namespace over /tmp
   Start the service.  

This means that processes running with this flag would see a different and unique /tmp from the one users and other daemons sees or can access.

Note:  We have found bugs using PrivateTmp in Fedora 16, so make sure you test this well before turning it on in Production.

For Fedora 17, I opened a feature page that requested all daemons that were using systemd unit files and /tmp to turn this feature on by default.

Apache and Cups now have PrivateTmp turned on by default in Fedora 17, along will several other daemons.

Giving three options as a Developer of System Service, I still believe that you should not use /tmp, you should use /run or /var/lib.  But if you have to use /tmp and do not communicate with other users then use PrivateTmp.  If you need to communicate with users be careful...

  • 1
(Deleted comment)

Re: Gnome forks and security

I don't see why not. I will look at all security issues raised by SELinux.

How to learn the PrivateTmp directory of a service?

How can I learn which of the gazillion private "tmp" directories created by systemd under /tmp belongs to a given running service? Motivating use case: profiling PHP applications server-side with XDebug. Need to know where the profiler output files end up!

Re: How to learn the PrivateTmp directory of a service?

So far I am aware of the only way - list mounts of given process:

grep tmp /proc/$PID/mountinfo

Mount options for the privatetmp mounts?

We're running EL7 with PrivateTmp on several services. It appears the tmpfs mounts are created with the options nosuid and nodev, but we'd like to further tighten security by setting noexec on the mount.

Is this possible?

Re: Mount options for the privatetmp mounts?

Not that I know of. Tried to google it, but found no answer.

You could put something into the service startup script to remount the tmpfs with no exec.

Hey, Dan,

thank you for all of your work.
Is the PrivateTmp stuff specific to systemd units or are there other use-cases where that private namespace is/can be used.
I'm seeing some interesting effects on gentoo with selinux + systemd, where the "eix-remote update" command tries to write to "/tmp/.private/" and gets denied. That command is executed by the root user in the terminal; hence, no systemd units. The "/tmp/.private/" directory is only there if SELinux is enabled. So, I assume that namespace separation is a security feature that could be used outside of systemd units.

PrivateTmp is just taking advantage of the Mount Namespace.

In Linux a process can create a new mount namespace and then mount partitions that its parent process does not see. So it could bind mount a directory on top of /tmp and have a different /tmp then the rest of the system.

Tools like containers use this functionality all the time.

You can experiment with this by using the unshare command. If you want to play with containers i would suggest podman or docker.

  • 1