Return-Path: Delivered-To: apmail-perl-dev-archive@www.apache.org Received: (qmail 71876 invoked from network); 20 Apr 2010 21:52:09 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 20 Apr 2010 21:52:09 -0000 Received: (qmail 97944 invoked by uid 500); 20 Apr 2010 21:52:08 -0000 Delivered-To: apmail-perl-dev-archive@perl.apache.org Received: (qmail 97720 invoked by uid 500); 20 Apr 2010 21:52:07 -0000 Mailing-List: contact dev-help@perl.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@perl.apache.org Received: (qmail 97702 invoked by uid 99); 20 Apr 2010 21:52:06 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Apr 2010 21:52:06 +0000 X-ASF-Spam-Status: No, hits=-0.6 required=10.0 tests=AWL,RCVD_IN_DNSWL_NONE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [209.85.222.201] (HELO mail-pz0-f201.google.com) (209.85.222.201) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Apr 2010 21:52:01 +0000 Received: by pzk39 with SMTP id 39so4601084pzk.7 for ; Tue, 20 Apr 2010 14:51:41 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.200.20 with HTTP; Tue, 20 Apr 2010 14:51:40 -0700 (PDT) Date: Tue, 20 Apr 2010 14:51:40 -0700 Received: by 10.115.98.19 with SMTP id a19mr6378070wam.82.1271800300432; Tue, 20 Apr 2010 14:51:40 -0700 (PDT) Message-ID: Subject: Another A:T patch for review From: Fred Moyer To: mod_perl Dev Content-Type: text/plain; charset=ISO-8859-1 This is a more extensive patch than the one I submitted a couple days ago. This makes a move to keep any Apache::Test tests (or tests in modules that use Apache::Test) from running as root. Most tests are likely being run as non-privileged users currently; if you ever ran them as root you likely had to change the permissions of the build files, so that seems to be an exception. There's one more addition here where the prompt to skip the test suite is skipped if the tests are running under $ENV{AUTOMATED_TESTING} Index: Makefile.PL =================================================================== --- Makefile.PL (revision 935715) +++ Makefile.PL (working copy) @@ -223,3 +223,16 @@ $string; }; } + +sub MY::test { + my $self = shift; + + # root is not allowed to run tests + if (my $no_root_tests = Apache::TestMM::is_root()) { + return $no_root_tests; + } + + # run tests normally for non root users + return $self->Apache::TestMM::test(@_); +} + Index: lib/Apache/TestRun.pm =================================================================== --- lib/Apache/TestRun.pm (revision 935715) +++ lib/Apache/TestRun.pm (working copy) @@ -46,7 +46,6 @@ my $orig_conf_opts; my %core_files = (); -my %original_t_perms = (); my @std_run = qw(start-httpd run-tests stop-httpd); my @others = qw(verbose configure clean help ssl http11 bugreport @@ -563,8 +562,6 @@ } } - $self->adjust_t_perms(); - if ($opts->{'start-httpd'}) { exit_perl 0 unless $server->start; } @@ -603,8 +600,6 @@ sub stop { my $self = shift; - $self->restore_t_perms; - return $self->{server}->stop if $self->{opts}->{'stop-httpd'}; } @@ -950,174 +945,6 @@ }, $vars->{top_dir}); } -# this function handles the cases when the test suite is run under -# 'root': -# -# 1. When user 'bar' is chosen to run Apache with, files and dirs -# created by 'root' might be not writable/readable by 'bar' -# -# 2. when the source is extracted as user 'foo', and the chosen user -# to run Apache under is 'bar', in which case normally 'bar' won't -# have the right permissions to write into the fs created by 'foo'. -# -# We solve that by 'chown -R bar.bar t/' in a portable way. -# -# 3. If the parent directory is not rwx for the chosen user, that user -# won't be able to read/write the DocumentRoot. In which case we -# have nothing else to do, but to tell the user to fix the situation. -# -sub adjust_t_perms { - my $self = shift; - - return if Apache::TestConfig::WINFU; - - %original_t_perms = (); # reset global - - my $user = getpwuid($>) || ''; - if ($user eq 'root') { - my $vars = $self->{test_config}->{vars}; - my $user = $vars->{user}; - my($uid, $gid) = (getpwnam($user))[2..3] - or die "Can't find out uid/gid of '$user'"; - - warning "root mode: ". - "changing the files ownership to '$user' ($uid:$gid)"; - finddepth(sub { - $original_t_perms{$File::Find::name} = [(stat $_)[4..5]]; - chown $uid, $gid, $_; - }, $vars->{t_dir}); - - $self->check_perms($user, $uid, $gid); - - $self->become_nonroot($user, $uid, $gid); - } -} - -sub restore_t_perms { - my $self = shift; - - return if Apache::TestConfig::WINFU; - - if (%original_t_perms) { - warning "root mode: restoring the original files ownership"; - my $vars = $self->{test_config}->{vars}; - while (my($file, $ids) = each %original_t_perms) { - next unless -e $file; # files could be deleted - chown @$ids, $file; - } - } -} - -# this sub is executed from an external process only, since it -# "sudo"'s into a uid/gid of choice -sub run_root_fs_test { - my($uid, $gid, $dir) = @_; - - # first must change gid and egid ("$gid $gid" for an empty - # setgroups() call as explained in perlvar.pod) - my $groups = "$gid $gid"; - $( = $) = $groups; - die "failed to change gid to $gid" - unless $( eq $groups && $) eq $groups; - - # only now can change uid and euid - $< = $> = $uid+0; - die "failed to change uid to $uid" unless $< == $uid && $> == $uid; - - my $file = catfile $dir, ".apache-test-file-$$-".time.int(rand); - eval "END { unlink q[$file] }"; - - # unfortunately we can't run the what seems to be an obvious test: - # -r $dir && -w _ && -x _ - # since not all perl implementations do it right (e.g. sometimes - # acls are ignored, at other times setid/gid change is ignored) - # therefore we test by trying to attempt to read/write/execute - - # -w - open TEST, ">$file" or die "failed to open $file: $!"; - - # -x - -f $file or die "$file cannot be looked up"; - close TEST; - - # -r - opendir DIR, $dir or die "failed to open dir $dir: $!"; - defined readdir DIR or die "failed to read dir $dir: $!"; - close DIR; - - # all tests passed - print "OK"; -} - -sub check_perms { - my ($self, $user, $uid, $gid) = @_; - - # test that the base dir is rwx by the selected non-root user - my $vars = $self->{test_config}->{vars}; - my $dir = $vars->{t_dir}; - my $perl = Apache::TestConfig::shell_ready($vars->{perl}); - - # find where Apache::TestRun was loaded from, so we load this - # exact package from the external process - my $inc = dirname dirname $INC{"Apache/TestRun.pm"}; - my $sub = "Apache::TestRun::run_root_fs_test"; - my $check = <<"EOI"; -$perl -Mlib=$inc -MApache::TestRun -e 'eval { $sub($uid, $gid, q[$dir]) }'; -EOI - warning "testing whether '$user' is able to -rwx $dir\n$check\n"; - - my $res = qx[$check] || ''; - warning "result: $res"; - unless ($res eq 'OK') { - $self->user_error(1); - #$self->restore_t_perms; - error <<"EOI"; -You are running the test suite under user 'root'. -Apache cannot spawn child processes as 'root', therefore -we attempt to run the test suite with user '$user' ($uid:$gid). -The problem is that the path (including all parent directories): - $dir -must be 'rwx' by user '$user', so Apache can read and write under that -path. - -There are several ways to resolve this issue. One is to move and -rebuild the distribution to '/tmp/' and repeat the 'make test' -phase. The other is not to run 'make test' as root (i.e. building -under your /home/user directory). - -You can test whether some directory is suitable for 'make test' under -'root', by running a simple test. For example to test a directory -'$dir', run: - - % $check -Only if the test prints 'OK', the directory is suitable to be used for -testing. -EOI - skip_test_suite(); - exit_perl 0; - } -} - -# in case the client side creates any files after the initial chown -# adjustments we want the server side to be able to read/write them, so -# they better be with the same permissions. dropping root permissions -# and becoming the same user as the server side solves this problem. -sub become_nonroot { - my ($self, $user, $uid, $gid) = @_; - - warning "the client side drops 'root' permissions and becomes '$user'"; - - # first must change gid and egid ("$gid $gid" for an empty - # setgroups() call as explained in perlvar.pod) - my $groups = "$gid $gid"; - $( = $) = $groups; - die "failed to change gid to $gid" unless $( eq $groups && $) eq $groups; - - # only now can change uid and euid - $< = $> = $uid+0; - die "failed to change uid to $uid" unless $< == $uid && $> == $uid; -} - sub run_request { my($test_config, $opts) = @_; @@ -1312,7 +1139,8 @@ # we can't prompt when STDIN is not attached to tty, unless we # were told that's it OK via env var (in which case some program # will feed the interactive prompts - unless (-t STDIN || $ENV{APACHE_TEST_INTERACTIVE_PROMPT_OK}) { + unless (-t STDIN || $ENV{APACHE_TEST_INTERACTIVE_PROMPT_OK} + || !$ENV{AUTOMATED_TESTING} ) { $no_doubt = 1; } Index: lib/Apache/TestMM.pm =================================================================== --- lib/Apache/TestMM.pm (revision 935715) +++ lib/Apache/TestMM.pm (working copy) @@ -22,6 +22,29 @@ use Apache::TestConfig (); use Apache::TestTrace; + +sub is_root { + my $user = getpwuid($>) || ''; + + return unless $user eq 'root'; + + return <passenv_makestr(); my $tests = "TEST_FILES =\n"; Index: Changes =================================================================== --- Changes (revision 935715) +++ Changes (working copy) @@ -8,11 +8,18 @@ =item 1.33-dev +Add check for automated testing environment variable before prompting +with EU::MM to quit the test suite. +[Adam Prime, Fred Moyer] + +Prevent tests from running as root user. Partly for security, partly +to keep test failures down which require questionable workarounds to fix. +[Fred Moyer] + https://rt.cpan.org/Public/Bug/Display.html?id=32993 use TAP::Harness for Apache::TestHarnessPHP [Mark A. Hershberger] - https://rt.cpan.org/Public/Bug/Display.html?id=54476 Fix error where non root user gets test failure with httpd suexec and mod_fcgid [Peter (Stig) Edwards] --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org For additional commands, e-mail: dev-help@perl.apache.org