[dpkg] 17/192: build: Detect the required GNU patch

Ximin Luo infinity0 at debian.org
Tue Oct 17 11:03:52 UTC 2017


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

infinity0 pushed a commit to branch pu/reproducible_builds
in repository dpkg.

commit 8ba04d41c839318b5a024f6c5298848d3b54c723
Author: Guillem Jover <guillem at debian.org>
Date:   Tue Mar 28 22:44:36 2017 +0200

    build: Detect the required GNU patch
    
    This makes sure the perl module is using a directory traversal resistant
    patch implementation, currently that's only GNU patch.
    
    Fixes: CVE-2017-8283
    Stable-Candidate: 1.17.x
---
 configure.ac                 |  1 +
 debian/changelog             |  4 ++++
 m4/dpkg-progs.m4             | 15 +++++++++++++++
 scripts/Dpkg.pm              | 13 ++++++++++++-
 scripts/Dpkg/Source/Patch.pm |  9 +++++----
 scripts/Makefile.am          |  2 ++
 6 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index d507550..87c1e9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,7 @@ AC_PROG_CC
 DPKG_C_C99
 AC_PROG_CXX
 DPKG_CXX_CXX11
+DPKG_PROG_PATCH
 AC_CHECK_PROGS([DOXYGEN], [doxygen])
 AC_CHECK_PROG([HAVE_DOT], [dot], [YES], [NO])
 DPKG_PROG_PO4A
diff --git a/debian/changelog b/debian/changelog
index c6b663f..ca7edcf 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -16,6 +16,10 @@ dpkg (1.18.24) UNRELEASED; urgency=medium
     - Use libexec variable for auxiliary internal programs, and set it to
       /usr/lib on Debian and derivatives.
     - Check that the detected tar is a GNU tar.
+    - Check that the detected patch is a GNU patch, so that we get a directory
+      traversal resistant patch implementation. This fixes CVE-2017-8283 by
+      delegating those checks to patch(1), so that we trap blank-indented
+      diff hunks trying to escape from the source tree.
 
   [ Updated programs translations ]
   * Catalan (Guillem Jover).
diff --git a/m4/dpkg-progs.m4 b/m4/dpkg-progs.m4
index 96c074e..166bc8b 100644
--- a/m4/dpkg-progs.m4
+++ b/m4/dpkg-progs.m4
@@ -64,3 +64,18 @@ AC_DEFUN([DPKG_DEB_PROG_TAR], [
   ])
   AC_DEFINE_UNQUOTED([TAR], ["$TAR"], [GNU tar program])
 ])# DPKG_DEB_PROG_TAR
+
+# DPKG_PROG_PATCH
+# ---------------
+# Specify GNU patch program name to use by dpkg-source. On GNU systems this
+# is usually simply patch, on BSD systems this is usually gpatch.
+# Even though most invocations would work with other patch implementations,
+# currently only GNU patch is directory traversal resistant.
+AC_DEFUN([DPKG_PROG_PATCH], [
+  AC_ARG_VAR([PATCH], [GNU patch program])
+  AC_CHECK_PROGS([PATCH], [gpatch patch], [patch])
+  AS_IF([! $PATCH --version 2>/dev/null | grep -q '^GNU patch'], [
+    AC_MSG_ERROR([cannot find a GNU patch program])
+  ])
+  AC_DEFINE_UNQUOTED([PATCH], ["$PATCH"], [GNU patch program])
+])# DPKG_PROG_PATCH
diff --git a/scripts/Dpkg.pm b/scripts/Dpkg.pm
index 1b9624c..3deb933 100644
--- a/scripts/Dpkg.pm
+++ b/scripts/Dpkg.pm
@@ -29,12 +29,13 @@ this system installation.
 use strict;
 use warnings;
 
-our $VERSION = '1.02';
+our $VERSION = '1.03';
 our @EXPORT_OK = qw(
     $PROGNAME
     $PROGVERSION
     $PROGMAKE
     $PROGTAR
+    $PROGPATCH
     $CONFDIR
     $ADMINDIR
     $LIBDIR
@@ -70,6 +71,11 @@ Contains the name of the system GNU make program.
 
 Contains the name of the system GNU tar program.
 
+=item $Dpkg::PROGPATCH
+
+Contains the name of the system GNU patch program (or another implementation
+that is directory traversal resistant).
+
 =item $Dpkg::CONFDIR
 
 Contains the path to the dpkg system configuration directory.
@@ -96,6 +102,7 @@ our ($PROGNAME) = $0 =~ m{(?:.*/)?([^/]*)};
 our $PROGVERSION = '1.18.x';
 our $PROGMAKE = $ENV{DPKG_PROGMAKE} // 'make';
 our $PROGTAR = $ENV{DPKG_PROGTAR} // 'tar';
+our $PROGPATCH = $ENV{DPKG_PROGPATCH} // 'patch';
 
 our $CONFDIR = '/etc/dpkg';
 our $ADMINDIR = '/var/lib/dpkg';
@@ -114,6 +121,10 @@ our $pkgdatadir = $DATADIR;
 
 =head1 CHANGES
 
+=head2 Version 1.03 (dpkg 1.18.24)
+
+New variable: $PROGPATCH.
+
 =head2 Version 1.02 (dpkg 1.18.11)
 
 New variable: $PROGTAR, $PROGMAKE.
diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm
index ee5e114..22e9d21 100644
--- a/scripts/Dpkg/Source/Patch.pm
+++ b/scripts/Dpkg/Source/Patch.pm
@@ -30,6 +30,7 @@ use File::Compare;
 use Fcntl ':mode';
 use Time::HiRes qw(stat);
 
+use Dpkg;
 use Dpkg::Gettext;
 use Dpkg::ErrorHandling;
 use Dpkg::IPC;
@@ -582,7 +583,7 @@ sub apply {
     $self->ensure_open('r');
     my ($stdout, $stderr) = ('', '');
     spawn(
-	exec => [ 'patch', @{$opts{options}} ],
+	exec => [ $Dpkg::PROGPATCH, @{$opts{options}} ],
 	chdir => $destdir,
 	env => { LC_ALL => 'C', LANG => 'C', PATCH_GET => '0' },
 	delete_env => [ 'POSIXLY_CORRECT' ], # ensure expected patch behaviour
@@ -595,7 +596,7 @@ sub apply {
     if ($?) {
 	print { *STDOUT } $stdout;
 	print { *STDERR } $stderr;
-	subprocerr('LC_ALL=C patch ' . join(' ', @{$opts{options}}) .
+	subprocerr("LC_ALL=C $Dpkg::PROGPATCH " . join(' ', @{$opts{options}}) .
 	           ' < ' . $self->get_filename());
     }
     $self->close();
@@ -632,7 +633,7 @@ sub check_apply {
     # Apply the patch
     $self->ensure_open('r');
     my $patch_pid = spawn(
-	exec => [ 'patch', @{$opts{options}} ],
+	exec => [ $Dpkg::PROGPATCH, @{$opts{options}} ],
 	chdir => $destdir,
 	env => { LC_ALL => 'C', LANG => 'C', PATCH_GET => '0' },
 	delete_env => [ 'POSIXLY_CORRECT' ], # ensure expected patch behaviour
@@ -642,7 +643,7 @@ sub check_apply {
     );
     wait_child($patch_pid, nocheck => 1);
     my $exit = WEXITSTATUS($?);
-    subprocerr('patch --dry-run') unless WIFEXITED($?);
+    subprocerr("$Dpkg::PROGPATCH --dry-run") unless WIFEXITED($?);
     $self->close();
     return ($exit == 0);
 }
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 435f0c5..cf0828f 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -132,6 +132,7 @@ do_perl_subst = $(AM_V_GEN) sed \
 	-e "s:our \$$DATADIR = .*;:our \$$DATADIR = '$(pkgdatadir)';:" \
 	-e "s:our \$$PROGMAKE = .*;:our \$$PROGMAKE = '$(MAKE)';:" \
 	-e "s:our \$$PROGTAR = .*;:our \$$PROGTAR = '$(TAR)';:" \
+	-e "s:our \$$PROGPATCH = .*;:our \$$PROGPATCH = '$(PATCH)';:" \
 	-e "s:our \$$PROGVERSION = .*;:our \$$PROGVERSION = '$(PACKAGE_VERSION)';:"
 
 do_shell_subst = $(AM_V_GEN) sed \
@@ -193,6 +194,7 @@ coverage-clean:
 
 TEST_ENV_VARS = \
 	DPKG_PROGTAR=$(TAR) \
+	DPKG_PROGPATCH=$(PATCH) \
 	DPKG_PROGMAKE=$(MAKE) \
 	DPKG_DATADIR=$(top_srcdir)/data \
 	DPKG_ORIGINS_DIR=$(srcdir)/t/origins

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git



More information about the Reproducible-commits mailing list