[devscripts] 01/01: Fix whitespace handling for "find | xargs"

Stig Sandbeck Mathisen ssm at debian.org
Sun Dec 22 00:08:35 UTC 2013


This is an automated email from the git hooks/post-receive script.

ssm pushed a commit to branch CVE-2013-7085-ruin-someones-yuletide
in repository devscripts.

commit f3b48a97d10fce5bb368b3af195b3c1cdb09e4b2
Author: Stig Sandbeck Mathisen <ssm at debian.org>
Date:   Sun Dec 22 01:02:08 2013 +0100

    Fix whitespace handling for "find | xargs"
    
     - Use IPC::Open3 instead of backticks, to avoid spawning a shell to
       parse command line options.
    
     - Adds more debugging, warning and error handling.
    
     - Bonus: This also fixes an issue where a non-empty top level directory
       could not be excluded.
    
    Closes: CVE-2013-7085
---
 scripts/uscan.pl | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/scripts/uscan.pl b/scripts/uscan.pl
index 0ffe9f2..75ec12e 100755
--- a/scripts/uscan.pl
+++ b/scripts/uscan.pl
@@ -30,6 +30,7 @@ use Dpkg::IPC;
 use File::Basename;
 use File::Copy;
 use File::Temp qw/tempfile tempdir/;
+use IPC::Open3 qw( open3 );
 use filetest 'access';
 use Getopt::Long qw(:config gnu_getopt);
 use lib '/usr/share/devscripts';
@@ -1523,15 +1524,10 @@ EOF
 		print STDERR "Error: $main_source_dir is no directory";
 	    }
 	    my $nfiles_before = `find $main_source_dir | wc -l`;
-	    foreach (grep {/\//} split /\s+/, $data->{"files-excluded"}) {
-		# delete trailing '/' because otherwise find -path will fail
-		s?/+$?? ;
-		# use rm -rf to enable deleting non-empty directories
-		`find $main_source_dir -path "$main_source_dir/$_" | xargs rm -rf`;
-	    };
-	    foreach (grep {/^[^\/]+$/} split /\s+/, $data->{"files-excluded"}) {
-		`find $main_source_dir -type f -name $_ -delete`;
-	    };
+
+	    delete_excluded_files( { files_excluded  => $data->{"files-excluded"},
+				     main_source_dir => $main_source_dir } );
+
 	    my $nfiles_after = `find $main_source_dir | wc -l`;
 	    if ( $nfiles_before == $nfiles_after ) {
 		print "-- Source tree remains identical - no need for repacking.\n" if $verbose;
@@ -1632,6 +1628,74 @@ EOF
     return 0;
 }
 
+sub delete_excluded_files {
+    my ($args)          = @_;
+    my $files_excluded  = $args->{files_excluded};
+    my $main_source_dir = $args->{main_source_dir};
+
+    my @exclude_patterns = valid_patterns (split( /\s+/, $files_excluded ));
+
+    foreach my $exclude_pattern (@exclude_patterns) {
+        my $ok = delete_pattern_from(
+            {   pattern => $exclude_pattern,
+                dir     => $main_source_dir
+            }
+        );
+        uscan_warn( "$progname warning: failed to exclude pattern: "
+                . $exclude_pattern )
+            unless $ok;
+    }
+}
+
+sub valid_patterns {
+    my @patterns = @_;
+    return grep { $_ } @patterns;
+}
+
+sub delete_pattern_from {
+    my ($args) = @_;
+    my $pattern = $args->{pattern};
+    my $dir     = $args->{dir};
+
+    my ( $find_in, $find_err, $xargs_out, $xargs_err );
+    local *PIPE;
+
+    my $path_pattern = join ('/', $dir, $pattern );
+
+    print "$progname debug: excluding pattern \"" . $pattern . "\"\n"
+	if $debug;
+
+    my @find_cmd = ( 'find', $dir, '-path', $path_pattern, '-print0' );
+
+    my @xargs_cmd = ( 'xargs', '--null', '--no-run-if-empty',
+		      'rm', '-rf' );
+
+    my $find_pid  = open3( $find_in, \*PIPE, $find_err, @find_cmd );
+    my $xargs_pid = open3( '<&PIPE', $xargs_out, $xargs_err, @xargs_cmd );
+
+    waitpid( $find_pid, 0 );
+    my $find_exit_code = $? >> 8;
+    if ( $find_exit_code != 0 ) {
+	uscan_debug( "$progname debug: \"find\" exit code: $find_exit_code\n");
+	uscan_debug( "$progname debug: \"find\" stderr: $find_err")
+	    if $find_err;
+    }
+
+    waitpid( $xargs_pid, 0 );
+    my $xargs_exit_code = $? >> 8;
+    if ( $xargs_exit_code != 0 ) {
+	uscan_warn( "$progname debug: \"xargs rm\" exit code: $xargs_exit_code\n" );
+	uscan_warn( "$progname debug: \"xargs rm\" stderr: $xargs_err\n" )
+	    if $xargs_err;
+    }
+
+    if ($find_exit_code == 0 and $xargs_exit_code == 0) {
+	return 1;
+    }
+    else {
+	return;
+    }
+}
 
 sub recursive_regex_dir ($$$) {
     my ($base, $optref, $watchfile)=@_;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/devscripts.git



More information about the devscripts-devel mailing list