[13257] in bugtraq

home help back first fref pref prev next nref lref last post

Re: Symlinks and Cryogenic Sleep

daemon@ATHENA.MIT.EDU (Marc Heuse)
Wed Jan 5 17:17:43 2000

Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Message-Id:  <20000104192007.88DED67A5@Galois.suse.de>
Date:         Tue, 4 Jan 2000 20:20:07 +0100
Reply-To: Marc Heuse <marc@SUSE.DE>
From: Marc Heuse <marc@SUSE.DE>
X-To:         bugtraq@securityfocus.com
To: BUGTRAQ@SECURITYFOCUS.COM

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

home help back first fref pref prev next nref lref last post