Bugtraq mailing list archives

Re: [linux-security] Things NOT to put in root's crontab


From: S.Vickery () its gu edu au (Sean Vickery)
Date: Thu, 23 May 1996 13:47:23 +1000


On 22 May 1996, Philip Guenther wrote:
The race condition in find should be eliminatible by using fchdir()
and passing the '-exec'ed command a simple filename.  You have to keep
open one descriptor for each level descended which should max out at
MAXPATHLEN/2.  That should be within the bounds of modern UNIX systems.

Yes, the race condition in find can be eliminated, but your pseudocode
does not do it.

cur = open argv[1];
fchdir(cur);
do_dir(cur);

do_dir(int cur) {
    foreach file in "." {
        int fd = open file;
        do_stuff_from_command_line;
        if ISDIR(fstat fd) {
            fchdir(fd);
            do_dir(fd);
            fchdir(cur);
        }
    }
}

The problem is with

    int fd = open file;

How can you be sure that you're not opening a symlink?  When you fstat
it later it will certainly not be a symlink.

Here's a bit of perl I wrote earlier today which does eliminate the race
condition:

    #!/opt/bin/perl
    require 'sys/syscall.ph';
    require 'stat.pl';
    open(DIR, "<$ARGV[0]") || die "can't open $ARGV[0]: $!";
    ($dev1, $ino1) = (stat DIR)[$ST_DEV, $ST_INO];
    #sleep 20;
    ($dev2, $ino2) = (lstat $ARGV[0])[$ST_DEV, $ST_INO];
    if ($dev2 != $dev1 || $ino2 != $ino1) {
        print "lost race!\n";
    }
    elsif (-l _)
    {
        print "is a symlink\n";
    }
    else {
        syscall(&SYS_fchdir, fileno(DIR)) == 0 || die "can't fchdir: $!";
        print "chdir suceeded\n";
        system "/bin/pwd";
    }

The script opens a handle to the directory and notes its device and inode.
It then lstats the directory name, and checks that it hasn't been fooled
into opening a symlink.

The commented out `sleep 20;' line gave me enough time to replace a
directory with a symlink to /etc.

It would be nice if one could call fchdir(2) directly from perl, without
having to go through syscall().

Sean.
--
Sean Vickery <S.Vickery () its gu edu au>   Ph: +61 (0)7 3875 6410
Systems Programmer   Information Services   Griffith University



Current thread: