summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch
blob: b4c8df1cf225f0ae752f7dc214b27954c3421c44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
From 67f2bc55ec79926f3334eb2956a62719f824e85b Mon Sep 17 00:00:00 2001
From: Sona Sarmadi <sona.sarmadi@enea.com>
Date: Thu, 14 Dec 2017 10:21:01 +0100
Subject: [PATCH]  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.

CVE: CVE-2017-8283
Upstream-Status: Backport [remotes/origin/1.18.x: 8ba04d41c839318b5a024f6c5298848d3b54c723]

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
---
 configure.ac                 |  1 +
 debian/changelog             |  5 +++++
 m4/dpkg-progs.m4             | 15 +++++++++++++++
 scripts/Dpkg.pm              | 13 ++++++++++++-
 scripts/Dpkg/Source/Patch.pm |  9 +++++----
 scripts/Makefile.am          |  4 +++-
 6 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3123d0c..0112d4d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,6 +61,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 695c55d..4b5b36b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,8 @@
+    - 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.
+
 dpkg (1.18.10) unstable; urgency=medium
 
   [ Guillem Jover ]
diff --git a/m4/dpkg-progs.m4 b/m4/dpkg-progs.m4
index c59f595..577d50d 100644
--- a/m4/dpkg-progs.m4
+++ b/m4/dpkg-progs.m4
@@ -49,3 +49,18 @@ AC_ARG_VAR([TAR], [GNU tar program])
 AC_CHECK_PROGS([TAR], [gnutar gtar tar], [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 deecfb3..4905ab8 100644
--- a/scripts/Dpkg.pm
+++ b/scripts/Dpkg.pm
@@ -29,10 +29,11 @@ this system installation.
 use strict;
 use warnings;
 
-our $VERSION = '1.01';
+our $VERSION = '1.03';
 our @EXPORT_OK = qw(
     $PROGNAME
     $PROGVERSION
+    $PROGPATCH
     $CONFDIR
     $ADMINDIR
     $LIBDIR
@@ -60,6 +61,11 @@ Contains the name of the current program.
 
 Contains the version of the dpkg suite.
 
+=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.
@@ -84,6 +90,7 @@ our ($PROGNAME) = $0 =~ m{(?:.*/)?([^/]*)};
 
 # The following lines are automatically fixed at install time
 our $PROGVERSION = '1.18.x';
+our $PROGPATCH = $ENV{DPKG_PROGPATCH} // 'patch';
 our $CONFDIR = '/etc/dpkg';
 our $ADMINDIR = '/var/lib/dpkg';
 our $LIBDIR = '.';
@@ -100,6 +107,10 @@ our $pkgdatadir = $DATADIR;
 
 =head1 CHANGES
 
+=head2 Version 1.03 (dpkg 1.18.10)
+
+New variable: $PROGPATCH.
+
 =head2 Version 1.01 (dpkg 1.17.0)
 
 New variables: $PROGNAME, $PROGVERSION, $CONFDIR, $ADMINDIR, $LIBDIR and
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 7b1ac36..84059c1 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -127,6 +127,7 @@ do_perl_subst = $(AM_V_GEN) \
 		    -e "s:\$$ADMINDIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$ADMINDIR='$(admindir)':" \
 		    -e "s:\$$LIBDIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$LIBDIR='$(pkglibdir)':" \
 		    -e "s:\$$DATADIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$DATADIR='$(pkgdatadir)':" \
+                    -e "s:our \$$PROGPATCH = .*;:our \$$PROGPATCH = '$(PATCH)';:" \
 		    -e "s:\$$PROGVERSION[[:space:]]*=[[:space:]]*['\"][^'\"]*[\"']:\$$PROGVERSION='$(PACKAGE_VERSION)':"
 
 do_shell_subst = $(AM_V_GEN) \
@@ -187,7 +188,8 @@ coverage-clean:
 	rm -rf cover_db
 
 TEST_ENV_VARS = \
-	DPKG_DATADIR=$(srcdir)/.. \
+	DPKG_PROGPATCH=$(PATCH) \
+        DPKG_DATADIR=$(srcdir)/.. \
 	DPKG_ORIGINS_DIR=$(srcdir)/t/origins
 TEST_COVERAGE = $(PERL_COVERAGE)
 
-- 
1.9.1