quilt-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Quilt-dev] [PATCH] test: Prevent test cases from escaping


From: Jean Delvare
Subject: [Quilt-dev] [PATCH] test: Prevent test cases from escaping
Date: Tue, 12 Mar 2019 11:44:46 +0100

By default, we continue running tests even after a failure, to make
diagnostics easier. If a chdir command fails, there is a chance that
subsequent chdir commands could accidentally move outside the
temporary directory where the test is being run, and then we start
messing up with the host's files.

In general, the consequence is to leave garbage files and directories
behind. However, some of the files can have side effects (for example
a "series" file or a "patches" directory could confuse quilt later),
and in theory this could also lead to the corruption or deletion of
existing files, which is pretty bad.

So add a safety check after every chdir command that we are still
inside the test case's working directory. If not, stop the test
immediately.

Note: this is not about being 100% safe and bullet-proof. The only
way to achieve this would be to use chroot or even containers. We
still need to trust the test cases to not do anything nasty on
purpose. This is only protecting against good test cases going wild on
failure.

Signed-off-by: Jean Delvare <address@hidden>
---
 test/run |   20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

--- quilt.orig/test/run 2019-03-12 10:32:57.867742224 +0100
+++ quilt/test/run      2019-03-12 11:06:56.085457429 +0100
@@ -70,6 +70,7 @@ my $lineno;
 my $width = ($ENV{COLUMNS} || 80) >> 1;
 my $origdir = getcwd;
 my $workdir = defined $ARGV[0] ? "$ARGV[0].$$" : "d.$$";
+my $workdir_absolute;
 my $keep_workdir = $ENV{KEEP_WORKDIR_IF_FAILED} || 0;
 
 sub print_header($)
@@ -116,6 +117,11 @@ sub substitute_vars($)
        return $line;
 }
 
+sub begins_with($$)
+{
+       return substr($_[0], 0, length($_[1])) eq $_[1];
+}
+
 sub exec_test($$) {
        my ($raw_prog, $in) = @_;
        local (*IN, *IN_DUP, *IN2, *OUT_DUP, *OUT, *OUT2);
@@ -130,6 +136,10 @@ sub exec_test($$) {
                        return 1, [ "chdir: $prog->[1]: $!\n" ];
                }
                $ENV{PWD} = getcwd;
+               # We must always stay inside the test directory
+               unless (begins_with("$ENV{PWD}/", "$workdir_absolute/")) {
+                       return 1, [ "Illegal chdir $prog->[1]\n", "$ENV{PWD} is 
not inside $workdir_absolute" ], 1;
+               }
                return 0, [];
        } elsif ($prog->[0] eq "export") {
                my ($name, $value) = split /=/, $prog->[1];
@@ -220,7 +230,7 @@ sub process_test($$$$) {
        my ($prog, $prog_line, $in, $out) = @_;
 
        print_body "[$prog_line] \$ $prog -- ";
-       my ($exec_status, $result) = exec_test($prog, $in);
+       my ($exec_status, $result, $stop) = exec_test($prog, $in);
        my @good = ();
        my $good = 1;
        my $nmax = (@$out > @$result) ? @$out : @$result;
@@ -250,7 +260,7 @@ sub process_test($$$$) {
                }
        }
 
-       return $exec_status;
+       return $exec_status, $stop;
 }
 
 # Create a dedicated working directory
@@ -259,6 +269,7 @@ mkdir $workdir or die "Failed to create
 $SIG{INT} = sub { if (chdir $origdir) { system "rm -rf $workdir" }; exit 1; };
 chdir $workdir or die "Failed to change to directory $workdir: $!";
 $ENV{PWD} = getcwd;
+$workdir_absolute = $ENV{PWD};
 
 if (defined $ARGV[0]) {
        open(SOURCE, "$origdir/$ARGV[0]");
@@ -282,9 +293,10 @@ while (defined(my $line = <SOURCE>)) {
 
        # We have all input and output, we can execute the command
        if (defined $prog) {
-               $last_status = process_test($prog, $prog_line, $in, $out);
+               my $stop;
+               ($last_status, $stop) = process_test($prog, $prog_line, $in, 
$out);
                $prog = undef;
-               last if $prog_line >= $opt_l;
+               last if $prog_line >= $opt_l || $stop;
        }
 
        # Parse the next command


-- 
Jean Delvare
SUSE L3 Support



reply via email to

[Prev in Thread] Current Thread [Next in Thread]