perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fred Moyer <f...@redhotpenguin.com>
Subject Another A:T patch for review
Date Tue, 20 Apr 2010 21:51:40 GMT
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 <<EOM;
+test::
+\t\@echo
+\t\@echo Apache::Test tests must be run as a non-privileged user on *nix
+\t\@echo based filesystems.  There are several reasons, but stemming from
+\t\@echo the fact that the httpd process is owned by a non privileged user
+\t\@echo and thus cannot access the test files if they are owned by root.
+\t\@echo
+\t\@echo Please rebuild Apache::Test as a non-privileged user and run the
+\t\@echo tests as that user, then use sudo to install the module.  Or build
+\t\@echo against your own locally installed version of Perl.
+\t\@echo
+EOM
+}
+
+
+
 sub import {
     my $class = shift;

@@ -52,6 +75,12 @@

 sub test {
     my $self = shift;
+
+    # root is not allowed to run tests
+    if (my $no_root_tests = Apache::TestMM::is_root()) {
+        return $no_root_tests;
+    }
+
     my $env = Apache::TestConfig->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


Mime
View raw message