On Thu, Apr 25, 2013 at 11:57:24PM -0500, Derek Martin wrote: > The whole point of > this subthread is that choosing not to rely on the system-provided > library routines is folly. You can't provide anything better > portably--your system libraries will already use the best source of > randomness available to them.
I'm reading this discussion with interest, more for my own academic curiosity than anything practical. As I understand it (and would welcome corrections if I'm wrong)... - Mutt uses mktemp to help compute a unique filename, then opens the file with O_CREAT|O_EXCL. - The alternative is to use mktemps to open a file with whatever guarantees the OS gives you, then use link to give the file a name that has the desired suffix. The attacks that mktemp has to defend against are: - content attacks, where the attacker wants you to open a file that they've created; - symlink attacks, where the attacker wants you to follow a symlink and thus open a file in an unsafe location, and - DOS attacks, where the attacker wants to prevent you from opening a tempfile by creating it before you do. Opening the file with O_CREAT|O_EXCL is a solid defense against the first two attacks in almost all common cases except when the temp filesystem is mounted over NFSv2. Using sufficient randomness with a large address space defends against the third attack, and can mitigate the other attacks in cases where O_EXCL is not guaranteed to be safe. The open questions as far as I'm concerned are: - what does the OS's mkstemp guarantee about randomness; - what does it guarantee about race conditions on NFSv2, and - is mkstemp followed by link any safer than mktemp followed by O_EXCL? The manual page for open(2) on GNU/Linux systems mentions that O_EXCL is not guaranteed race-free on an NFSv2 system. However, the man page for mkstemp does not discuss NFSv2 at all, and doesn't promise to be cryptographically random. So I've looked at the source code of glibc. First thing to notice is that mktemp, mkstemp, mkdtemp, etc are all implemented by the same function. Consequently, mkstemp is exactly equivalent to calling mktemp and then opening the file with O_EXCL. This means that mkstemp is not guaranteed race-free on an NFSv2 system, and thus mkstemp+link is no safer than the current way of doing it. Second thing is that the sources of randomness are as follows: - the pseudorandom value arrived at in the previous (if any) call to mk*temp - the system clock at microsecond precision - the system's high precision clock, if it has one (on x86 systems this maps to the assembly instruction "rdtsc") - the current pid And that's all. Moreover, if the first attempt to open a file fails then the subsequent attempts are entirely predictable (value+=7777). I therefore conclude that there is a large class of systems on which mktemp et al do not use the best source of randomness available to them unless you think the CPU's time stamp counter is difficult enough to predict. imc