From 62a1700ddb370966bfe34820a6c0dd6603d46a45 Mon Sep 17 00:00:00 2001 From: Raphael Hertzog Date: Thu, 8 May 2008 19:12:23 +0200 Subject: [PATCH] dpkg-source (2.0/3.0 (quilt)): refuse binary files in debian subdir * scripts/Dpkg/Source/Functions.pm (is_binary): New function to check if a file is binary by using diff against it. * scripts/Dpkg/Source/Package/V2.pm (do_build): Check that all files from the debian sub-directory are non-binary and only allow whitelisted binary files. * man/dpkg-source.1: Document this behaviour. --- ChangeLog | 9 +++++++++ debian/changelog | 3 +++ man/dpkg-source.1 | 4 +++- scripts/Dpkg/Source/Functions.pm | 28 +++++++++++++++++++++++++++- scripts/Dpkg/Source/Package/V2.pm | 21 +++++++++++++++++++-- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 961e4df8..9feccac9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-05-08 Raphael Hertzog + + * scripts/Dpkg/Source/Functions.pm (is_binary): New function + to check if a file is binary by using diff against it. + * scripts/Dpkg/Source/Package/V2.pm: Check that all files from the + debian sub-directory are non-binary and only allow whitelisted + binary files. + * man/dpkg-source.1: Document this behaviour. + 2008-05-08 Raphael Hertzog * scripts/Dpkg/Changelog/Debian.pm (parse): Bugfix in creation of diff --git a/debian/changelog b/debian/changelog index 6c525937..d4fe9305 100644 --- a/debian/changelog +++ b/debian/changelog @@ -36,6 +36,9 @@ dpkg (1.14.19) UNRELEASED; urgency=low ::V3::quilt instead of ::V3_0::quilt. * Fix changelog parser to not fail when an unexpected changelog entry appears without the preceding heading line. Closes: #478925 + * Change the "2.0" and "3.0 (quilt)" source packages to refuse by default + binary files in the debian sub-directory. They have to be whitelisted + through debian/source/include-binaries. Closes: #473041 [ Helge Kreutzmann ] * Minor fixes and clarifications to man pages. diff --git a/man/dpkg-source.1 b/man/dpkg-source.1 index b5c6a587..cccfc2e3 100644 --- a/man/dpkg-source.1 +++ b/man/dpkg-source.1 @@ -378,7 +378,9 @@ and the diff (if non-empty) is stored in on a binary file is not representable in a diff and will thus lead to a failure unless the maintainer deliberately decided to include that modified binary file in the debian tarball (by listing it in -\fBdebian/source/include-binaries\fP). +\fBdebian/source/include-binaries\fP). The build will also fail if it +finds binary files in the debian sub-directory unless they have been +whitelisted through \fBdebian/source/include-binaries\fP. The updated debian directory and the list of modified binaries is then used to regenerate the debian tarball. diff --git a/scripts/Dpkg/Source/Functions.pm b/scripts/Dpkg/Source/Functions.pm index 9ad04632..7c8ca88f 100644 --- a/scripts/Dpkg/Source/Functions.pm +++ b/scripts/Dpkg/Source/Functions.pm @@ -5,10 +5,11 @@ use warnings; use Exporter; our @ISA = qw(Exporter); -our @EXPORT_OK = qw(erasedir fixperms); +our @EXPORT_OK = qw(erasedir fixperms is_binary); use Dpkg::ErrorHandling qw(syserr subprocerr failure); use Dpkg::Gettext; +use Dpkg::IPC; use POSIX; @@ -49,5 +50,30 @@ sub fixperms { subprocerr("chmod -R $modes_set $dir") if $?; } +sub is_binary($) { + my ($file) = @_; + + # Use diff to check if it's a binary file + my $diffgen; + my $diff_pid = fork_and_exec( + 'exec' => [ 'diff', '-u', '--', '/dev/null', $file ], + 'env' => { LC_ALL => 'C', LANG => 'C', TZ => 'UTC0' }, + 'to_pipe' => \$diffgen + ); + my $result = 0; + while (<$diffgen>) { + if (m/^binary/i) { + $result = 1; + last; + } elsif (m/^[-+\@ ]/) { + $result = 0; + last; + } + } + close($diffgen) or syserr("close on diff pipe"); + wait_child($diff_pid, nocheck => 1, cmdline => "diff -u -- /dev/null $file"); + return $result; +} + # vim: set et sw=4 ts=8 1; diff --git a/scripts/Dpkg/Source/Package/V2.pm b/scripts/Dpkg/Source/Package/V2.pm index f6b99da9..dd39976e 100644 --- a/scripts/Dpkg/Source/Package/V2.pm +++ b/scripts/Dpkg/Source/Package/V2.pm @@ -29,7 +29,7 @@ use Dpkg::Source::Archive; use Dpkg::Source::Patch; use Dpkg::Version qw(check_version); use Dpkg::Exit; -use Dpkg::Source::Functions qw(erasedir); +use Dpkg::Source::Functions qw(erasedir is_binary); use POSIX; use File::Basename; @@ -308,6 +308,23 @@ sub do_build { $self->register_error(); } }; + # Check if the debian directory contains unwanted binary files + my $unwanted_binaries = 0; + my $check_binary = sub { + my $fn = File::Spec->abs2rel($_, $dir); + if (-f $_ and is_binary($_)) { + if ($include_binaries or $auth_bin_files{$fn}) { + push @binary_files, $fn; + } else { + errormsg(_g("unwanted binary file: %s"), $fn); + $unwanted_binaries++; + } + } + }; + find({ wanted => $check_binary, no_chdir => 1 }, File::Spec->catdir($dir, "debian")); + error(_g("detected %d unwanted binary file(s) " . + "(add them in debian/source/include-binaries to allow their " . + "inclusion)."), $unwanted_binaries) if $unwanted_binaries; # Create a patch my ($difffh, $tmpdiff) = tempfile("$basenamerev.diff.XXXXXX", @@ -360,7 +377,7 @@ sub do_build { $tar->create(options => \@tar_ignore, 'chdir' => $dir); $tar->add_directory("debian"); foreach my $binary (@binary_files) { - $tar->add_file($binary); + $tar->add_file($binary) unless $binary =~ m{^debian/}; } $tar->finish(); -- 2.39.5