From dbdab4a777f59cfa16e4257796b539e2b87cb0ac Mon Sep 17 00:00:00 2001 From: Jacob Bachmeyer Date: Wed, 26 Oct 2022 22:46:47 -0500 Subject: [PATCH] Avoid processing invalid directive elements The old code simply abandoned the entire loop at the first error; this meant that a "directory" element after an error would not be seen and was fixed in commit 86b458910ddda2c227622cafa3c37b10682d0561. That commit allowed the values of the capture variables from the last successful match to be reused if a later line did not match its filter pattern. No exploit was possible, since an error was recorded and an exception would be thrown instead of returning the corrupted operation list, but this had side effects that caused failures in the testsuite that were traced to this issue, now fixed. --- gatekeeper.pl | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/gatekeeper.pl b/gatekeeper.pl index b50a07f..9e54469 100755 --- a/gatekeeper.pl +++ b/gatekeeper.pl @@ -1687,8 +1687,10 @@ sub interpret_directive { $header{package} = $info{package}; } elsif ($tainted_cmd eq 'filename') { # We use the same filename restrictions as scan_incoming - $tainted_val =~ /^($RE_filename_here)$/ - or push @errors, "invalid filename $tainted_val"; + unless ($tainted_val =~ /^($RE_filename_here)$/) { + push @errors, "invalid filename $tainted_val"; + next; + } my $val = $1; # so far so good # Only let them specify one filename directive. @@ -1702,29 +1704,36 @@ sub interpret_directive { } elsif ($tainted_cmd eq 'version') { # already handled above } elsif ($tainted_cmd eq 'symlink') { - $tainted_val =~ /^($RE_filename_relative)\s+($RE_filename_relative)$/ - or push @errors, - "invalid parameters for symlink command: $tainted_val"; + unless ($tainted_val =~ + /^($RE_filename_relative)\s+($RE_filename_relative)$/) { + push @errors, "invalid parameters for symlink command: $tainted_val"; + next; + } # $1 -- link target $2 -- link name push @ops, [symlink => $1, $2]; $info{"symlink-$1"} = {"link" => $2, "order" => $cnt++}; #ok. } elsif ($tainted_cmd eq 'rmsymlink') { - $tainted_val =~ /^($RE_filename_relative)$/ - or push @errors, - "invalid parameters for rmsymlink command: $tainted_val"; + unless ($tainted_val =~ /^($RE_filename_relative)$/) { + push @errors, "invalid parameters for rmsymlink command: $tainted_val"; + next; + } push @ops, [rmsymlink => $1]; $info{"rmsymlink-$1"} = {"order" => $cnt++}; #ok. } elsif ($tainted_cmd eq 'archive') { - $tainted_val =~ /^($RE_filename_relative)$/ - or push @errors, + unless ($tainted_val =~ /^($RE_filename_relative)$/) { + push @errors, "invalid parameters for archive command: $tainted_val"; + next; + } push @ops, [archive => $1]; $info{"archive-$1"} = {"order" => $cnt++}; #ok. } elsif ($tainted_cmd eq 'replace') { # This command is only supported from v1.2 - $tainted_val =~ /^(true|false)$/ - or push @errors, + unless ($tainted_val =~ /^(true|false)$/) { + push @errors, "invalid parameters for replace command: $tainted_val"; + next; + } push @errors, "invalid directive 'replace', not supported prior to version 1.2" -- 2.25.1