Bugtraq mailing list archives
Re: Symlinks and Cryogenic Sleep
From: marc () SUSE DE (Marc Heuse)
Date: Tue, 4 Jan 2000 20:20:07 +0100
Hi,
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.
yes, but not from hardlink attacks
When trying to explain this to someone, I noticed that this is not quite what it does. It protects your application against symlinks to files that exist *before the call to lstat*. This sounds like I'm nitpicking, and my first reaction also was to try to find some convincing handwaving argument to dispel my concerns.
no, thats right, there is still a small race condition. Thats the reason why O_NOFOLLOW was added to the kernel (bsd and linux >= 2.1.126)
- All symlink attacks can be improved by running them on an NFS mounted directory (easy for applications that heed the TMPDIR environment variable). In terms of file system race conditions, NFS acts as a kind of slo-mo glue.
however, who is mounting /tmp via NFS? rare (can be found sometimes, yes) And it's always a good idea to make /tmp a partition of it's own. (and Theo de Raadt even goes that far to set quotas on /tmp ... ;-)
- It's not that hard to detect whether the targetted application is in the critical section of code. On Linux, it's very easy because /proc/$pid/stat will give you the instruction pointer. On other OSes
wasn't that fixed? Thomas (thomas () suse de) found that vulnerability and reported it. As far as I know it's fixed (hmm, but I'm not sure).
Comments? Suggestions?
hmm, I'd propose the following function to protect against the hard/symlink attacks (add syslog/warnings wherever you want to). Comments welcome. #ifndef O_NOFOLLOW # define O_NOFOLLOW 0 // was introduced in kernel 2.1.126, needs glibc > 2.0.100 #endif int safe_reopen (char *file, int modes) { struct stat st; struct stat st2; int fd; if (lstat(TMPFILE, &st) < 0) { // does not exit -> safe creation if ((fd=open(TMPFILE, modes | O_EXCL | O_CREAT, 0600)) < 0) return -1; } else { // it exists - allow only regular file which are not hardlinked if ((! S_ISREG(st.st_mode)) || st.st_nlink != 1) return -1; // OK, lets open if ((fd=open(TMPFILE, modes | O_NOFOLLOW)) < 0) return -1; fstat(fd, &st2); // recheck that it's the same file ... if (st2.st_ino != st.st_ino || st2.st_uid != st.st_uid || st2.st_nlink != 1) { close(fd); return -1; } } return fd; } Greets, Marc -- Marc Heuse, SuSE GmbH, Schanzaeckerstr. 10, 90443 Nuernberg E@mail: marc () suse de Function: Security Support & Auditing "lynx -source http://www.suse.de/~marc/marc.pgp | pgp -fka" Key fingerprint = B5 07 B6 4E 9C EF 27 EE 16 D9 70 D4 87 B5 63 6C
Current thread:
- Re: Symlinks and Cryogenic Sleep, (continued)
- Re: Symlinks and Cryogenic Sleep Christos Zoulas (Jan 04)
- Re: Symlinks and Cryogenic Sleep Mikael Olsson (Jan 05)
- Re: Symlinks and Cryogenic Sleep Marc Heuse (Jan 05)
- Re: Symlinks and Cryogenic Sleep Wietse Venema (Jan 04)
- Re: Symlinks and Cryogenic Sleep Pavel Machek (Jan 04)
- Security problem with Solstice Backup/Legato Networker recover command Chris Siebenmann (Jan 04)
- Local / Remote D.o.S Attack in IMail IMONITOR Server for WinNT Version 5.08 Ussr Labs (Jan 05)
- Re: Symlinks and Cryogenic Sleep Pavel Kankovsky (Jan 05)
- [RHSA-2000:002] New lpr packages available Bill Nottingham (Jan 07)
- Re: Symlinks and Cryogenic Sleep der Mouse (Jan 03)
- Re: Symlinks and Cryogenic Sleep Marc Heuse (Jan 04)
- Re: Symlinks and Cryogenic Sleep John Cochran (Jan 04)
- Re: Symlinks and Cryogenic Sleep Antonomasia (Jan 04)
- Re: Symlinks and Cryogenic Sleep Antonomasia (Jan 05)