From: Joey Hess Date: Thu, 17 May 2012 03:57:56 +0000 (-0400) Subject: Revert "ikiwiki-mass-rebuild: Fix tty hijacking vulnerability by using su. X-Git-Tag: 3.20100815.9^0 X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/commitdiff_plain/0255c1bdbe528c1ad5d51aaa8f19efcdc963bdaa Revert "ikiwiki-mass-rebuild: Fix tty hijacking vulnerability by using su. su's related bug #628843 has still not been fixed in stable, and the .8 release of ikiwiki never happened. This reverts commit 851cc6ca0d241e9167b8188102199190d5baed3c. --- diff --git a/debian/changelog b/debian/changelog index fbcd6fac1..f4cbc9812 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,17 +2,9 @@ ikiwiki (3.20100815.9) stable-security; urgency=high * meta: Security fix; add missing sanitization of author and authorurl. CVE-2012-0220 Thanks, Raúl Benencia - - -- Joey Hess Wed, 16 May 2012 19:51:27 -0400 - -ikiwiki (3.20100815.8) stable-security; urgency=low - - * ikiwiki-mass-rebuild: Fix tty hijacking vulnerability by using su. - (Once su's related bug #628843 is fixed.) Thanks, Ludwig Nussel. - (CVE-2011-1408) * po: Make po4a warn, not error on a malformed document. (intrigeri) - -- Joey Hess Wed, 08 Jun 2011 17:34:56 -0400 + -- Joey Hess Wed, 16 May 2012 19:51:27 -0400 ikiwiki (3.20100815.7) stable-security; urgency=high diff --git a/doc/index.mdwn b/doc/index.mdwn index 19f0a217a..06acc9cec 100644 --- a/doc/index.mdwn +++ b/doc/index.mdwn @@ -10,7 +10,7 @@ There are many other [[features]], including support for [[Setup]] has a tutorial for setting up ikiwiki, or you can read the [[man_page|usage]]. There are some [[examples]] of things you can do -with ikiwiki, and some [[tips]]. Use the [[forum]] for discussions. +with ikiwiki, and some [[tips]]. All wikis are supposed to have a [[SandBox]], so this one does too. @@ -20,6 +20,7 @@ ikiwiki [[!version ]]. ## developer resources The [[RoadMap]] describes where the project is going. +The [[forum]] is open for discussions. [[Bugs]], [[TODO]] items, [[wishlist]] items, and [[patches|patch]] can be submitted and tracked using this wiki. diff --git a/ikiwiki-mass-rebuild b/ikiwiki-mass-rebuild index bbef4946b..f13033e7f 100755 --- a/ikiwiki-mass-rebuild +++ b/ikiwiki-mass-rebuild @@ -2,45 +2,80 @@ use warnings; use strict; -my $etcfile="/etc/ikiwiki/wikilist"; +sub supplemental_groups { + my $user=shift; + + my @list; + while (my @fields=getgrent()) { + if (grep { $_ eq $user } split(' ', $fields[3])) { + push @list, $fields[2]; + } + } -sub root { - $> == 0; + return @list; } -sub username { - (getpwuid($>))[0]; +sub samelists { + my %a=map { $_ => 1 } split(' ', shift()); + my %b=map { $_ => 1 } split(' ', shift()); + + foreach my $i (keys %b) { + if (! exists $a{$i}) { + return 0; + } + } + foreach my $i (keys %a) { + if (! exists $b{$i}) { + return 0; + } + } + return 1; } sub processline { + my $user=shift; my $setup=shift; + if (! getpwnam("$user")) { + print STDERR "warning: user $user does not exist\n"; + return + } if (! -f "$setup") { print STDERR "warning: $setup does not exist, skipping\n"; return; } - print "Processing $setup as user ".username()." ...\n"; - my $ret=system("ikiwiki", "-setup", $setup, @ARGV); - if ($ret != 0) { - print STDERR "warning: processing $setup failed with code $ret\n"; + print "Processing $setup as user $user ...\n"; + # su is not used because it passes arguments through the shell, + # which is not safe for untrusted setup file names. + defined(my $pid = fork) or die "Can’t fork: $!"; + if (! $pid) { + my ($uuid, $ugid) = (getpwnam($user))[2, 3]; + my $grouplist=join(" ", $ugid, sort {$a <=> $b} $ugid, supplemental_groups($user)); + if (! samelists(($)=$grouplist), $grouplist)) { + die "failed to set egid $grouplist (got back $))"; + } + $(=$ugid; + $<=$uuid; + $>=$uuid; + if ($< != $uuid || $> != $uuid || $( != $ugid) { + die "failed to drop permissions to $user"; + } + %ENV=( + PATH => $ENV{PATH}, + HOME => (getpwnam($user))[7], + ); + exec("ikiwiki", "-setup", $setup, @ARGV); + die "failed to run ikiwiki: $!"; } -} - -my %users; -sub processuser { - my $user=shift; - next if $user=~/^-/ || $users{$user}; - $users{$user}=1; - my $ret=system("su", $user, "-s", "/bin/sh", "-c", "--", "$0 --nonglobal @ARGV"); - if ($ret != 0) { - print STDERR "warning: processing for $user failed with code $ret\n"; + waitpid($pid,0); + if ($?) { + print STDERR "Processing $setup as user $user failed with code $?\n"; } } sub processlist { my $file=shift; - - return unless -e $file; + my $forceuser=shift; my $list; open ($list, "<$file") || die "$file: $!"; @@ -49,28 +84,22 @@ sub processlist { s/^\s+//; s/\s+$//; next if /^#/ || ! length; - if (/^([-\w]+)\s+([^\s]+)$/) { + + if (/^([^\s]+)\s+([^\s]+)$/) { my $user=$1; my $setup=$2; - if (root()) { - processuser($user); - } - else { - if (username() eq $user) { - processline($setup); - } + if (defined $forceuser && $forceuser ne $user) { + print STDERR "warning: in $file line $., attempt to set user to $user, but user forced to $forceuser. Skipping\n"; } + processline($user, $setup); } - elsif (/^([-\w]+)$/) { + elsif (/^([^\s]+)$/) { my $user=$1; - if (root()) { - processuser($user); - } - else { - my $home=(getpwnam($user))[7]; - if (defined $home && -d $home) { - my $dotfile="$home/.ikiwiki/wikilist"; - processlist($dotfile); + my $home=(getpwnam($user))[7]; + if (defined $home && -d $home) { + my $dotfile="$home/.ikiwiki/wikilist"; + if (-e $dotfile) { + processlist($dotfile, $user); } } } @@ -78,13 +107,9 @@ sub processlist { close $list; } -if (@ARGV && $ARGV[0] eq "--nonglobal") { - shift; - # avoid recursively processing if the wikilist file has a root - # user in it - if (root()) { - exit 1; - } +my $wikilist="/etc/ikiwiki/wikilist"; + +if (-e $wikilist) { + processlist($wikilist); } -processlist($etcfile);