[2588] in bugtraq
Re: [linux-security] Things NOT to put in root's crontab
daemon@ATHENA.MIT.EDU (Sean Vickery)
Thu May 23 04:40:43 1996
Date: Thu, 23 May 1996 13:47:23 +1000
Reply-To: Bugtraq List <BUGTRAQ@NETSPACE.ORG>
From: Sean Vickery <S.Vickery@its.gu.edu.au>
X-To: Philip Guenther <guenther@gac.edu>
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@NETSPACE.ORG>
In-Reply-To: Your message of "Wed, 22 May 1996 19:10:05 EST."
<199605230010.TAA27660@solen.gac.edu>
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