summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Sarmadi <sona.sarmadi@enea.com>2017-12-14 13:17:04 +0100
committerAdrian Dudau <adrian.dudau@enea.com>2017-12-14 15:31:54 +0100
commitef74e9d6103be37e4f4a43fb4c8b948789346b7c (patch)
tree231f347725f1fb81dbe6fac45fff3790e2a33034
parent1a348139a77f2f0a4f564d759b37a76901c0dbdf (diff)
downloadmeta-el-common-ef74e9d6103be37e4f4a43fb4c8b948789346b7c.tar.gz
DPKG: Fix and test case for CVE-2017-8283
Directory Traversal Vulnerability References: https://nvd.nist.gov/vuln/detail/CVE-2017-8283 http://www.securityfocus.com/bid/98064/info Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> Signed-off-by: Adrian Dudau <adrian.dudau@enea.com>
-rw-r--r--recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch190
-rw-r--r--recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch83
-rw-r--r--recipes-devtools/dpkg/dpkg_%.bbappend6
3 files changed, 279 insertions, 0 deletions
diff --git a/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch b/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch
new file mode 100644
index 0000000..b4c8df1
--- /dev/null
+++ b/recipes-devtools/dpkg/dpkg/CVE-2017-8283.patch
@@ -0,0 +1,190 @@
1From 67f2bc55ec79926f3334eb2956a62719f824e85b Mon Sep 17 00:00:00 2001
2From: Sona Sarmadi <sona.sarmadi@enea.com>
3Date: Thu, 14 Dec 2017 10:21:01 +0100
4Subject: [PATCH] build: Detect the required GNU patch
5
6This makes sure the perl module is using a directory traversal resistant
7patch implementation, currently that's only GNU patch.
8
9CVE: CVE-2017-8283
10Upstream-Status: Backport [remotes/origin/1.18.x: 8ba04d41c839318b5a024f6c5298848d3b54c723]
11
12Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
13---
14 configure.ac | 1 +
15 debian/changelog | 5 +++++
16 m4/dpkg-progs.m4 | 15 +++++++++++++++
17 scripts/Dpkg.pm | 13 ++++++++++++-
18 scripts/Dpkg/Source/Patch.pm | 9 +++++----
19 scripts/Makefile.am | 4 +++-
20 6 files changed, 41 insertions(+), 6 deletions(-)
21
22diff --git a/configure.ac b/configure.ac
23index 3123d0c..0112d4d 100644
24--- a/configure.ac
25+++ b/configure.ac
26@@ -61,6 +61,7 @@ AC_PROG_CC
27 DPKG_C_C99
28 AC_PROG_CXX
29 DPKG_CXX_CXX11
30+DPKG_PROG_PATCH
31 AC_CHECK_PROGS([DOXYGEN], [doxygen])
32 AC_CHECK_PROG([HAVE_DOT], [dot], [YES], [NO])
33 DPKG_PROG_PO4A
34diff --git a/debian/changelog b/debian/changelog
35index 695c55d..4b5b36b 100644
36--- a/debian/changelog
37+++ b/debian/changelog
38@@ -1,3 +1,8 @@
39+ - Check that the detected patch is a GNU patch, so that we get a directory
40+ traversal resistant patch implementation. This fixes CVE-2017-8283 by
41+ delegating those checks to patch(1), so that we trap blank-indented
42+ diff hunks trying to escape from the source tree.
43+
44 dpkg (1.18.10) unstable; urgency=medium
45
46 [ Guillem Jover ]
47diff --git a/m4/dpkg-progs.m4 b/m4/dpkg-progs.m4
48index c59f595..577d50d 100644
49--- a/m4/dpkg-progs.m4
50+++ b/m4/dpkg-progs.m4
51@@ -49,3 +49,18 @@ AC_ARG_VAR([TAR], [GNU tar program])
52 AC_CHECK_PROGS([TAR], [gnutar gtar tar], [tar])
53 AC_DEFINE_UNQUOTED([TAR], ["$TAR"], [GNU tar program])
54 ])# DPKG_DEB_PROG_TAR
55+
56+# DPKG_PROG_PATCH
57+# ---------------
58+# Specify GNU patch program name to use by dpkg-source. On GNU systems this
59+# is usually simply patch, on BSD systems this is usually gpatch.
60+# Even though most invocations would work with other patch implementations,
61+# currently only GNU patch is directory traversal resistant.
62+AC_DEFUN([DPKG_PROG_PATCH], [
63+ AC_ARG_VAR([PATCH], [GNU patch program])
64+ AC_CHECK_PROGS([PATCH], [gpatch patch], [patch])
65+ AS_IF([! $PATCH --version 2>/dev/null | grep -q '^GNU patch'], [
66+ AC_MSG_ERROR([cannot find a GNU patch program])
67+ ])
68+ AC_DEFINE_UNQUOTED([PATCH], ["$PATCH"], [GNU patch program])
69+])# DPKG_PROG_PATCH
70diff --git a/scripts/Dpkg.pm b/scripts/Dpkg.pm
71index deecfb3..4905ab8 100644
72--- a/scripts/Dpkg.pm
73+++ b/scripts/Dpkg.pm
74@@ -29,10 +29,11 @@ this system installation.
75 use strict;
76 use warnings;
77
78-our $VERSION = '1.01';
79+our $VERSION = '1.03';
80 our @EXPORT_OK = qw(
81 $PROGNAME
82 $PROGVERSION
83+ $PROGPATCH
84 $CONFDIR
85 $ADMINDIR
86 $LIBDIR
87@@ -60,6 +61,11 @@ Contains the name of the current program.
88
89 Contains the version of the dpkg suite.
90
91+=item $Dpkg::PROGPATCH
92+
93+Contains the name of the system GNU patch program (or another implementation
94+that is directory traversal resistant).
95+
96 =item $Dpkg::CONFDIR
97
98 Contains the path to the dpkg system configuration directory.
99@@ -84,6 +90,7 @@ our ($PROGNAME) = $0 =~ m{(?:.*/)?([^/]*)};
100
101 # The following lines are automatically fixed at install time
102 our $PROGVERSION = '1.18.x';
103+our $PROGPATCH = $ENV{DPKG_PROGPATCH} // 'patch';
104 our $CONFDIR = '/etc/dpkg';
105 our $ADMINDIR = '/var/lib/dpkg';
106 our $LIBDIR = '.';
107@@ -100,6 +107,10 @@ our $pkgdatadir = $DATADIR;
108
109 =head1 CHANGES
110
111+=head2 Version 1.03 (dpkg 1.18.10)
112+
113+New variable: $PROGPATCH.
114+
115 =head2 Version 1.01 (dpkg 1.17.0)
116
117 New variables: $PROGNAME, $PROGVERSION, $CONFDIR, $ADMINDIR, $LIBDIR and
118diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm
119index ee5e114..22e9d21 100644
120--- a/scripts/Dpkg/Source/Patch.pm
121+++ b/scripts/Dpkg/Source/Patch.pm
122@@ -30,6 +30,7 @@ use File::Compare;
123 use Fcntl ':mode';
124 use Time::HiRes qw(stat);
125
126+use Dpkg;
127 use Dpkg::Gettext;
128 use Dpkg::ErrorHandling;
129 use Dpkg::IPC;
130@@ -582,7 +583,7 @@ sub apply {
131 $self->ensure_open('r');
132 my ($stdout, $stderr) = ('', '');
133 spawn(
134- exec => [ 'patch', @{$opts{options}} ],
135+ exec => [ $Dpkg::PROGPATCH, @{$opts{options}} ],
136 chdir => $destdir,
137 env => { LC_ALL => 'C', LANG => 'C', PATCH_GET => '0' },
138 delete_env => [ 'POSIXLY_CORRECT' ], # ensure expected patch behaviour
139@@ -595,7 +596,7 @@ sub apply {
140 if ($?) {
141 print { *STDOUT } $stdout;
142 print { *STDERR } $stderr;
143- subprocerr('LC_ALL=C patch ' . join(' ', @{$opts{options}}) .
144+ subprocerr("LC_ALL=C $Dpkg::PROGPATCH " . join(' ', @{$opts{options}}) .
145 ' < ' . $self->get_filename());
146 }
147 $self->close();
148@@ -632,7 +633,7 @@ sub check_apply {
149 # Apply the patch
150 $self->ensure_open('r');
151 my $patch_pid = spawn(
152- exec => [ 'patch', @{$opts{options}} ],
153+ exec => [ $Dpkg::PROGPATCH, @{$opts{options}} ],
154 chdir => $destdir,
155 env => { LC_ALL => 'C', LANG => 'C', PATCH_GET => '0' },
156 delete_env => [ 'POSIXLY_CORRECT' ], # ensure expected patch behaviour
157@@ -642,7 +643,7 @@ sub check_apply {
158 );
159 wait_child($patch_pid, nocheck => 1);
160 my $exit = WEXITSTATUS($?);
161- subprocerr('patch --dry-run') unless WIFEXITED($?);
162+ subprocerr("$Dpkg::PROGPATCH --dry-run") unless WIFEXITED($?);
163 $self->close();
164 return ($exit == 0);
165 }
166diff --git a/scripts/Makefile.am b/scripts/Makefile.am
167index 7b1ac36..84059c1 100644
168--- a/scripts/Makefile.am
169+++ b/scripts/Makefile.am
170@@ -127,6 +127,7 @@ do_perl_subst = $(AM_V_GEN) \
171 -e "s:\$$ADMINDIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$ADMINDIR='$(admindir)':" \
172 -e "s:\$$LIBDIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$LIBDIR='$(pkglibdir)':" \
173 -e "s:\$$DATADIR[[:space:]]*=[[:space:]]*['\"][^'\"]*['\"]:\$$DATADIR='$(pkgdatadir)':" \
174+ -e "s:our \$$PROGPATCH = .*;:our \$$PROGPATCH = '$(PATCH)';:" \
175 -e "s:\$$PROGVERSION[[:space:]]*=[[:space:]]*['\"][^'\"]*[\"']:\$$PROGVERSION='$(PACKAGE_VERSION)':"
176
177 do_shell_subst = $(AM_V_GEN) \
178@@ -187,7 +188,8 @@ coverage-clean:
179 rm -rf cover_db
180
181 TEST_ENV_VARS = \
182- DPKG_DATADIR=$(srcdir)/.. \
183+ DPKG_PROGPATCH=$(PATCH) \
184+ DPKG_DATADIR=$(srcdir)/.. \
185 DPKG_ORIGINS_DIR=$(srcdir)/t/origins
186 TEST_COVERAGE = $(PERL_COVERAGE)
187
188--
1891.9.1
190
diff --git a/recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch b/recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch
new file mode 100644
index 0000000..5632d8f
--- /dev/null
+++ b/recipes-devtools/dpkg/dpkg/test-case-for-CVE-2017-8283.patch
@@ -0,0 +1,83 @@
1From 57a3daba4d3dee1c33571e84f160aa1c67aece4c Mon Sep 17 00:00:00 2001
2From: Sona Sarmadi <sona.sarmadi@enea.com>
3Date: Thu, 14 Dec 2017 10:40:42 +0100
4Subject: [PATCH] Dpkg::Source::Patch: Indented patch test-case
5
6POSIX specifies that a diff hunk can be indented by spaces or tabs
7(while the original patch(1) by Larry Wall also accepts 'X'), as long
8as the amount of spaces is consistent for all subsequent lines. And as
9we are not checking for this condition at all, any such indented hunk
10can avoid the sanity checks performed by Dpkg::Source::Patch.
11
12On systems using GNU patch >= 2.7.5, this should, in principle, not be
13a problem anymore, as that implementation protects against directory
14traversal issue. But on other systems where the patch implementation
15does not perform such checks (such as the BSDs) this is an issue, so
16check for this in the test-suite.
17
18Those are arguably all security issues in these various patch
19implementations, but given that we are performing sanity checks and that
20those implementations are currently very lax, it seems prudent to do the
21heavy lifting ourselves and also take the possible blame too.
22
23Ref: test-case for CVE-2017-8283
24Upstream-Status: Backport
25
26Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
27---
28 debian/changelog | 3 +++
29 scripts/Makefile.am | 1 +
30 scripts/t/Dpkg_Source_Patch.t | 6 +++++-
31 3 files changed, 9 insertions(+), 1 deletion(-)
32
33diff --git a/debian/changelog b/debian/changelog
34index 4b5b36b..596a59e 100644
35--- a/debian/changelog
36+++ b/debian/changelog
37@@ -2,6 +2,9 @@
38 traversal resistant patch implementation. This fixes CVE-2017-8283 by
39 delegating those checks to patch(1), so that we trap blank-indented
40 diff hunks trying to escape from the source tree.
41+ * Test suite:
42+ - Add a test case for blank-indented patches which were the cause for
43+ CVE-2017-8283.
44
45 dpkg (1.18.10) unstable; urgency=medium
46
47diff --git a/scripts/Makefile.am b/scripts/Makefile.am
48index 84059c1..6ce0ad6 100644
49--- a/scripts/Makefile.am
50+++ b/scripts/Makefile.am
51@@ -275,6 +275,7 @@ test_data = \
52 t/Dpkg_Shlibs/spacesyms-o-map.pl \
53 t/Dpkg_Source_Patch/c-style.patch \
54 t/Dpkg_Source_Patch/ghost-hunk.patch \
55+ t/Dpkg_Source_Patch/indent-header.patch \
56 t/Dpkg_Source_Patch/index-+++.patch \
57 t/Dpkg_Source_Patch/index-alone.patch \
58 t/Dpkg_Source_Patch/index-inert.patch \
59diff --git a/scripts/t/Dpkg_Source_Patch.t b/scripts/t/Dpkg_Source_Patch.t
60index 258a9aa..30be77a 100644
61--- a/scripts/t/Dpkg_Source_Patch.t
62+++ b/scripts/t/Dpkg_Source_Patch.t
63@@ -16,7 +16,7 @@
64 use strict;
65 use warnings;
66
67-use Test::More tests => 9;
68+use Test::More tests => 10;
69
70 use File::Path qw(make_path);
71
72@@ -67,4 +67,8 @@ test_patch_escape('partial', 'symlink', 'partial.patch',
73 test_patch_escape('ghost-hunk', 'symlink', 'ghost-hunk.patch',
74 'Patch cannot escape using a disabling hunk');
75
76+# This is CVE-2017-8283
77+test_patch_escape('indent-header', 'symlink', 'indent-header.patch',
78+ 'Patch cannot escape indented hunks');
79+
80 1;
81--
821.9.1
83
diff --git a/recipes-devtools/dpkg/dpkg_%.bbappend b/recipes-devtools/dpkg/dpkg_%.bbappend
new file mode 100644
index 0000000..65d380e
--- /dev/null
+++ b/recipes-devtools/dpkg/dpkg_%.bbappend
@@ -0,0 +1,6 @@
1# look for files in the layer first
2FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
3
4SRC_URI += "file://CVE-2017-8283.patch \
5 file://test-case-for-CVE-2017-8283.patch \
6 "