Bugtraq mailing list archives

Re: Symlinks and Cryogenic Sleep


From: wietse () PORCUPINE ORG (Wietse Venema)
Date: Tue, 4 Jan 2000 14:37:17 -0500


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


Current thread: