[Fusionforge-commits] r8459 - in branches/Branch_4_5/gforge: cronjobs/cvs-cron deb-specific
Roland Mas
lolando at libremir.placard.fr.eu.org
Thu Dec 3 14:20:53 CET 2009
Author: lolando
Date: 2009-12-03 14:20:52 +0100 (Thu, 03 Dec 2009)
New Revision: 8459
Modified:
branches/Branch_4_5/gforge/cronjobs/cvs-cron/ssh_create.php
branches/Branch_4_5/gforge/deb-specific/ssh_dump_update.pl
Log:
Backported fix for CVE-2009-3304
Modified: branches/Branch_4_5/gforge/cronjobs/cvs-cron/ssh_create.php
===================================================================
--- branches/Branch_4_5/gforge/cronjobs/cvs-cron/ssh_create.php 2009-12-02 13:30:04 UTC (rev 8458)
+++ branches/Branch_4_5/gforge/cronjobs/cvs-cron/ssh_create.php 2009-12-03 13:20:52 UTC (rev 8459)
@@ -4,6 +4,7 @@
* GForge Cron Job
*
* The rest Copyright 2002-2005 (c) GForge Team
+ * Copyright (C) 2009 Sylvain Beucler
* http://gforge.org/
*
* @version $Id$
@@ -53,10 +54,16 @@
mkdir ($ssh_dir, 0755);
}
+ # Set the effective uid/gid to this user, so as to avoid symlink attacks
+ $userinfo = posix_getpwnam($username);
+ posix_setegid($userinfo['gid']);
+ posix_seteuid($userinfo['uid']);
$h8 = fopen("$ssh_dir/authorized_keys","w");
fwrite($h8,'# This file is automatically generated from your account settings.'."\n");
fwrite($h8,$ssh_key);
fclose($h8);
+ posix_seteuid(0);
+ posix_setegid(0);
system("chown $username:users $homedir_prefix/$username");
system("chown $username:users $ssh_dir");
Modified: branches/Branch_4_5/gforge/deb-specific/ssh_dump_update.pl
===================================================================
--- branches/Branch_4_5/gforge/deb-specific/ssh_dump_update.pl 2009-12-02 13:30:04 UTC (rev 8458)
+++ branches/Branch_4_5/gforge/deb-specific/ssh_dump_update.pl 2009-12-03 13:20:52 UTC (rev 8459)
@@ -4,8 +4,65 @@
#
# ssh_dump.pl - Script to suck data outta the database to be processed by ssh_create.pl
#
+# Symlink attack fix Copyright (C) 2009 Sylvain Beucler / GPLv2+ / no warranty
use DBI;
+use English;
+## Become this effective user (EUID/EGID) and perform this action.
+##
+## This protects against symlink attacks; they are inevitable when
+## working in a directory owned by a local user. We could naively
+## check for the presence of symlinks, but then we'd still be
+## vulnerable to a symlink race attack.
+##
+## We'll use set_e_uid/set_e_gid for efficiency and simplicity
+## (e.g. we can get the return value directly), which is enough for
+## opening files and similar basic operations. When calling external
+## programs, you should use fork&exec&setuid/setgid.
+##
+# arg1: username
+# arg2: a Perl sub{}
+sub SudoEffectiveUser {
+ my $user = $_[0];
+ my $sub_unprivileged = $_[1];
+
+ my ($uid,$gid) = GetUserUidGid($user);
+ if ($uid eq "" or $gid eq "") {
+ print "Unknown user: $user";
+ return;
+ }
+
+ my $old_GID = $GID; # save additional groups
+ $! = '';
+ $EGID = "$gid $gid"; # set egid and additional groups
+ if ($! ne '') {
+ warn "Cannot setegid($gid $gid): $!";
+ return;
+ }
+ $EUID = $uid;
+ if ($! ne '') {
+ warn "Cannot seteuid($uid): $!";
+ return;
+ }
+
+ # Perform the action under this effective user:
+ my $ret = &$sub_unprivileged();
+
+ # Back to root
+ undef($EUID); # restore euid==uid
+ $EGID = $old_GID; # restore egid==gid + additional groups
+
+ return $ret;
+}
+
+## Get system uid/gid
+sub GetUserUidGid {
+ my $user = $_[0];
+ my ($name,$passwd,$uid,$gid,
+ $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
+ return ($uid,$gid);
+}
+
# Run as gforge
my($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwnam("gforge");
$> = $uid;
@@ -56,10 +113,12 @@
if($verbose){print("Writing authorized_keys for $username: ")};
- if (write_array_file("$ssh_dir/authorized_keys", @user_authorized_keys)) {
+ SudoEffectiveUser($username, sub {
+ if (write_array_file("$ssh_dir/authorized_keys", @user_authorized_keys)) {
warn "Problem writing authorized_keys for $username\n";
next;
- }
+ }
+ });
chown $uid, $uid, ("$homedir_prefix/$username", $ssh_dir, "$ssh_dir/authorized_keys");
chmod 0644, "$ssh_dir/authorized_keys";
@@ -97,8 +156,12 @@
if (-d $ssh_dir) {
if($verbose){print("Resetting authorized_keys for $username: ")};
-
- unlink("$ssh_dir/authorized_keys");
+
+ if (-l "$ssh_dir") {
+ warn("$ssh_dir is a symlink, possible symlink attack!");
+ } else {
+ unlink("$ssh_dir/authorized_keys");
+ }
system("chown $uid:$uid $homedir_prefix/$username");
system("chown $uid:$uid $ssh_dir");
More information about the Fusionforge-commits
mailing list