Olaf Kirch: > Hi all, > > when you're dealing with files in /tmp that are supposed to be re-opened > (rather than opened once and then discarded) there's an established > way to do it which goes like this: > > if (lstat(fname, &stb1) >= 0 && S_ISREG(stb1.st_mode)) { > fd = open(fname, O_RDWR); > if (fd < 0 || fstat(fd, &stb2) < 0 > || ino_or_dev_mismatch(&stb1, &stb2)) > raise_big_stink() > } else { > /* do the O_EXCL thing */ > } > > Accepted wisdom has it that this protects you from symlink attacks. Olaf explains that this test compares inode information not files - if the process is setuid, the open() can, at least in theory, be delayed until the inode found with lstat() has been re-used for something interesting. > All of this doesn't make it a practical attack yet, but it surely > demonstrates that the supposedly secure code shown above is far from > secure. > > Comments? Suggestions? Three comments. First of all, this demonstrates how problematic it can be to do privileged work in a process that runs under control by a user. For daemon processes that don't run under user control, the above test can be improved a bit by comparing more attributes than just device/inode numbers. I'll update a comment to that effect in the Postfix safe_open() routine, now that I understand my code better. Thanks for pointing out an interesting flaw in the common assumptions made about race conditions, namely, that the race is being run at high speed. Wietse
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:26:26 PDT