Hacking Linux Exposed

About
Authors
Contents
Reviews
Foreword
Purchase

Articles
Books
Sourcecode
Tools
Errata

Home

 


(view this code in a separate window)

#!/usr/bin/perl
#
# runForward
#
# This is no longer vulnerable to a race condition.
# Uses sysopen to avoid symlink open attack,
# and fchown system call to avoid symlink race
# between create and chown.
#
# No chmod needed (handled in the open call.)

# POSIX needed for fchown call.
use POSIX; require "syscall.ph";

# Get username and id info.
($username,$email) = @ARGV;
($uid,$gid,$home) = (getpwnam($username))[2,3,7] || die

$FILE = "$home/.forward";

# No need to check unlink's exit status.  If it fails
# then sysopen will complain and we'll bail out.
# Besides, relying on the exit status would lead to a
# a new race condition.
unlink $FILE;

# Open the file securely - O_EXCL makes sure that
# it can't be a symlink, dangling or no.
sysopen( FORWARD, $FILE, O_RDWR|O_CREAT|O_EXCL, 0600) || die;

# Note we're using fchown, which operates on the open
# file descriptor, thus no chown race condition.
syscall(&SYS_fchown, fileno(FORWARD), $uid, $gid)==0 || die;

print FORWARD "$email\n";
close FORWARD;