Private temporary directories

One more addition to pambase has been the mktemp USE flag. With that flag enabled, the default system-auth stack features pam_mktemp module, again from OpenWall.

All this module does is setting up a per-user private temporary directory inside /tmp, and set TMP and TMPDIR environment variables so that the programs (at least those respecting them) use the new private temporary directory rather than the globally-accessible one.

This is useful as a mitigation strategy for temporary file attacks (race issues and symlink attacks); while it does not magically fix them, and their seriousness is not to be ignored, it might make it more difficult to exploit them. You can think of it to something alike to PaX, hardened and SElinux.

There are, though, a few thing that need to be improved for it to be totally useful; and until those are completed, and the setup widely tested, it will not be enabled by default.

To begin with, not all applications make use of TMPDIR, I already blogged about sqlite ignoring TMPDIR entirely, but there are other cases like that, for instance, Emacs’s server support hardcodes /tmp as directory (I’ve mailed emacs-devel and they are now discussing about using TMPDIR as every other application), as well as gpg-agent and ssh-agent. I wonder how many applications will have broken designs in that regard; I know ESounD requires /tmp as path for its socket, so PulseAudio will not respect TMPDIR by default; Xorg also seems to use /tmp for locks (although I would have expected them to be in /var/lock), and PostgreSQL uses /tmp for its sockets (why not /var/run?).

Another issue is that pam_mktemp seems to handle in specific ways ext2/ext3, with its “appendable” flag, but the same does not hold true for other filesystems (I admit I don’t know how that works, and if other filesystems support them; I’m quite sure BSDs support that though – too bad they didn’t port pam_mktemp as well as pam_passwdqc). Some porting of this would probably be useful, I suppose OpenWall has a default setup where it does not make sense to check for more than ext3. SoC, anyone? 😉

Then there is the issue to make sure that setuid and setgid programs all work fine, it probably will require quite a bit of work though. I suppose this could get well along with file-based capabilities support, as that would limit a lot the amount of setgid and setuid programs, they’d just need capabilities to access the minimum privileges they need to.

But that’s a story for a different day…

A different way to achieve this is to use pam_namespace (provided by Linux-PAM), which allows to create per-user instances of any directory on the filesystem. This would then create a different /tmp directory without fiddling with TMPDIR. While this is quite interesting as it allows to workaround the broken applications hardcoding /tmp into their source, it would probably break Xorg, PostgreSQL and ESounD as they’ll get a different per-user directory too.

On the other hand, if we’re able to get all the software fixed in its design, so that global data (locks and sockets) goes to /var, then it might work fine in the future. It would also allow for a more graceful handling of FreeDesktop-defined cache directories (XDG_DATA_DIRS) as you could set the environment variable for all the users to, say, /var/cache/xdg and then instantiate a different version of that per-user.

Right now, though, I prefer the pam_mktemp solution, even if it will require more fixes around so that /tmp is not used.