Last week, I wrote about my experimentation with pam_namespace to replace pam_mktemp (that breaks samba and does not cover all software). Unfortunately, a couple of days after starting this I gave up on it entirely, I did write down a quick comment about that, and promised to write down what the issue is exactly.
But since I know that people like to have some context on why I’m doing something and why that’s important for users, I’ll first post some summary on what the problem is with insecure temporary files and why it’s useful to mitigate them. And while I’m at it, I’ll explain the drawbacks of my original approach that is currently available through pambase.
Software often have security problems with temporary files, that might lead to information disclosure, or worse . This is caused both by manually-created temporary files, and by old, broken functions like
tmpnam() which are deemed insecure. For this reason there are two main movements trying to work on this: from one side, Debian security team has developed a script that can identify a large amount of insecure temporary files creation (tracker from Gentoo); on the other hand, OpenWall developed pam_mktemp (do not confuse it with the pam_mktemp from the Debian-Athena distribution, that used the same name with a different version and with a totally different interface — not a very good choice there), which creates per-user directories, properly set up so that insecure temporary files from an user cannot be exploited from another… that is if the software supports
Yes because the pam_mktemp module does not rely on anything particular, either from the kernel or from the PAM implementation: it works fine with Linux-PAM and OpenPAM, on Linux and FreeBSD and most likely on any operating system and PAM implementation. What it mostly does is setting up the directory structure, and then sets the
TMPDIR environment variable to the new one. All the software knowing about this variable (knowing about it is part of the GNU coding standards), or are using the proper commands and functions to create the temporary files, will be using the user-private temporary directory and this reduces the impact of insecure temporary file creation.
Unfortunately, this does not work as flawlessly as I hoped: first problem is that Samba, for instance, has some problems with the idea of having per-user temporary directories: indeed, after it starts (with user nobody) it moves to the temporary directory as CWD (Current Work Directory) and tries to stay there after changing user to the one you’re authenticating with. Since the directory for nobody is not accessible by the rest of the users, Samba stops working there.
The second problem is more insidious, because while the previous one can be deemed an incompatibility and thus would simply require users to change their setup slightly, this one moots the main reason why we want to use pam_mktemp: vulnerability mitigation. We want to reduce the chance that insecure temporary file creation might be exploited for information disclosure or worse, but if the code is unable to create properly secured temporary files, it’s very likely that it will not respect the
TMPDIR setting either.
At the end, what pam_mktemp is actually able to prevent is insecure temporary file creation by mistake in code that is otherwise sound. While this happens, and thus the module is not totally useless, this is quite rare; most of the code that would have this kind of problems would also have to be modified to accept
TMPDIR too. And you have to add to this the software that insists on not supporting that setting: GnuPG for instance, where upstream has claimed multiple mirror-climbing reasons for not abiding to the coding standards it should abide to, being a GNU project (just to qualify this statement, one of the reasons I was given is that if they abided to
TMPDIR, the user could set that to his home directory, which could be stored on NFS, and that would open a security risk as it would expose the agent to other machines – if you got any idea how local unix sockets work, you know this is not the case since the socket is local to the kernel, and at the same time, such misconfiguration is likely to be a problem for other reasons and something that exists between keyboard and chair).
An alternative to all this is the pam_namespace module, but that also has its share of problems, but those, will be posted tomorrow. (For once, I already have the post written so it will happen! I just wanted to give this drop by drop since people keep saying I write too much).