[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Symlinks and Cryogenic Sleep



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