summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-devtools/patch/patch.inc1
-rw-r--r--meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch200
-rw-r--r--meta/recipes-devtools/patch/patch_2.7.5.bb (renamed from meta/recipes-devtools/patch/patch_2.7.1.bb)6
3 files changed, 3 insertions, 204 deletions
diff --git a/meta/recipes-devtools/patch/patch.inc b/meta/recipes-devtools/patch/patch.inc
index 332b97a85e..cbfb8cfcf5 100644
--- a/meta/recipes-devtools/patch/patch.inc
+++ b/meta/recipes-devtools/patch/patch.inc
@@ -3,6 +3,7 @@ DESCRIPTION = "patch takes a patch file containing a difference listing \
3produced by the diff program and applies those differences to one or more \ 3produced by the diff program and applies those differences to one or more \
4original files, producing patched versions." 4original files, producing patched versions."
5SECTION = "utils" 5SECTION = "utils"
6HOMEPAGE = "http://savannah.gnu.org/projects/patch/"
6 7
7SRC_URI = "${GNU_MIRROR}/patch/patch-${PV}.tar.gz" 8SRC_URI = "${GNU_MIRROR}/patch/patch-${PV}.tar.gz"
8S = "${WORKDIR}/patch-${PV}" 9S = "${WORKDIR}/patch-${PV}"
diff --git a/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch b/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch
deleted file mode 100644
index d408346ac2..0000000000
--- a/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch
+++ /dev/null
@@ -1,200 +0,0 @@
1From 4e9269a5fc1fe80a1095a92593dd85db871e1fd3 Mon Sep 17 00:00:00 2001
2From: Andreas Gruenbacher <andreas.gruenbacher@gmail.com>
3Date: Mon, 19 Jan 2015 23:18:30 +0100
4Subject: [PATCH] Make sure symlinks don't point outside working directory
5 (CVE-2015-1196)
6
7When creating symlinks from git-style patches, make sure the symlinks don't
8point above the current working directory. Otherwise, a subsequent patch could
9use the symlink to write outside the working directory.
10
11* src/pch.c (symlink_target_is_valid): New function to check for valid symlink
12targets.
13* src/util.c (move_file): Use symlink_target_is_valid() here.
14* tests/symlinks: Add valid and invalid symlink test cases.
15
16Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
17
18Upstream-Status: Backport
19
20---
21 NEWS | 3 ++
22 src/pch.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 src/pch.h | 1 +
24 src/util.c | 7 +++++++
25 tests/symlinks | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
26 5 files changed, 117 insertions(+)
27
28diff --git a/NEWS b/NEWS
29index 42afed7..d3f1c2d 100644
30--- a/NEWS
31+++ b/NEWS
32@@ -1,3 +1,6 @@
33+* With git-style patches, symlinks that point outside the working directory
34+ will no longer be created.
35+
36 Changes in version 2.7.1:
37
38 * Two critical bug fixes in the "diff --git" format support.
39diff --git a/src/pch.c b/src/pch.c
40index 55e1504..f05ef83 100644
41--- a/src/pch.c
42+++ b/src/pch.c
43@@ -454,6 +454,60 @@ name_is_valid (char const *name)
44 return is_valid;
45 }
46
47+bool
48+symlink_target_is_valid (char const *target, char const *to)
49+{
50+ bool is_valid;
51+
52+ if (IS_ABSOLUTE_FILE_NAME (to))
53+ is_valid = true;
54+ else if (IS_ABSOLUTE_FILE_NAME (target))
55+ is_valid = false;
56+ else
57+ {
58+ unsigned int depth = 0;
59+ char const *t;
60+
61+ is_valid = true;
62+ t = to;
63+ while (*t)
64+ {
65+ while (*t && ! ISSLASH (*t))
66+ t++;
67+ if (ISSLASH (*t))
68+ {
69+ while (ISSLASH (*t))
70+ t++;
71+ depth++;
72+ }
73+ }
74+
75+ t = target;
76+ while (*t)
77+ {
78+ if (*t == '.' && *++t == '.' && (! *++t || ISSLASH (*t)))
79+ {
80+ if (! depth--)
81+ {
82+ is_valid = false;
83+ break;
84+ }
85+ }
86+ else
87+ {
88+ while (*t && ! ISSLASH (*t))
89+ t++;
90+ depth++;
91+ }
92+ while (ISSLASH (*t))
93+ t++;
94+ }
95+ }
96+
97+ /* Allow any symlink target if we are in the filesystem root. */
98+ return is_valid || cwd_is_root (to);
99+}
100+
101 /* Determine what kind of diff is in the remaining part of the patch file. */
102
103 static enum diff
104diff --git a/src/pch.h b/src/pch.h
105index 0c7ff62..58861b0 100644
106--- a/src/pch.h
107+++ b/src/pch.h
108@@ -37,6 +37,7 @@ bool pch_write_line (lin, FILE *);
109 bool there_is_another_patch (bool, mode_t *);
110 char *pfetch (lin) _GL_ATTRIBUTE_PURE;
111 char pch_char (lin) _GL_ATTRIBUTE_PURE;
112+bool symlink_target_is_valid (char const *, char const *);
113 int another_hunk (enum diff, bool);
114 int pch_says_nonexistent (bool) _GL_ATTRIBUTE_PURE;
115 size_t pch_line_len (lin) _GL_ATTRIBUTE_PURE;
116diff --git a/src/util.c b/src/util.c
117index 66ae90f..636eded 100644
118--- a/src/util.c
119+++ b/src/util.c
120@@ -470,6 +470,13 @@ move_file (char const *from, bool *from_needs_removal,
121 read_fatal ();
122 buffer[size] = 0;
123
124+ if (! symlink_target_is_valid (buffer, to))
125+ {
126+ fprintf (stderr, "symbolic link target '%s' is invalid\n",
127+ buffer);
128+ fatal_exit (0);
129+ }
130+
131 if (! backup)
132 {
133 if (unlink (to) == 0)
134diff --git a/tests/symlinks b/tests/symlinks
135index 96626b3..6211026 100644
136--- a/tests/symlinks
137+++ b/tests/symlinks
138@@ -146,6 +146,59 @@ ncheck 'test ! -L symlink'
139
140 # --------------------------------------------------------------
141
142+# Patch should not create symlinks which point outside the working directory.
143+
144+cat > symlink-target.diff <<EOF
145+diff --git a/dir/foo b/dir/foo
146+new file mode 120000
147+index 0000000..cad2309
148+--- /dev/null
149++++ b/dir/foo
150+@@ -0,0 +1 @@
151++../foo
152+\ No newline at end of file
153+EOF
154+
155+check 'patch -p1 < symlink-target.diff || echo "Status: $?"' <<EOF
156+patching symbolic link dir/foo
157+EOF
158+
159+cat > bad-symlink-target1.diff <<EOF
160+diff --git a/bar b/bar
161+new file mode 120000
162+index 0000000..cad2309
163+--- /dev/null
164++++ b/bar
165+@@ -0,0 +1 @@
166++/bar
167+\ No newline at end of file
168+EOF
169+
170+check 'patch -p1 < bad-symlink-target1.diff || echo "Status: $?"' <<EOF
171+patching symbolic link bar
172+symbolic link target '/bar' is invalid
173+Status: 2
174+EOF
175+
176+cat > bad-symlink-target2.diff <<EOF
177+diff --git a/baz b/baz
178+new file mode 120000
179+index 0000000..cad2309
180+--- /dev/null
181++++ b/baz
182+@@ -0,0 +1 @@
183++../baz
184+\ No newline at end of file
185+EOF
186+
187+check 'patch -p1 < bad-symlink-target2.diff || echo "Status: $?"' <<EOF
188+patching symbolic link baz
189+symbolic link target '../baz' is invalid
190+Status: 2
191+EOF
192+
193+# --------------------------------------------------------------
194+
195 # The backup file of a new symlink is an empty regular file.
196
197 check 'patch -p1 --backup < create-symlink.diff || echo "Status: $?"' <<EOF
198--
1992.1.4
200
diff --git a/meta/recipes-devtools/patch/patch_2.7.1.bb b/meta/recipes-devtools/patch/patch_2.7.5.bb
index 1a3b9b1201..20ed6c84f9 100644
--- a/meta/recipes-devtools/patch/patch_2.7.1.bb
+++ b/meta/recipes-devtools/patch/patch_2.7.5.bb
@@ -1,10 +1,8 @@
1require patch.inc 1require patch.inc
2LICENSE = "GPLv3" 2LICENSE = "GPLv3"
3 3
4SRC_URI += "file://patch-CVE-2015-1196.patch" 4SRC_URI[md5sum] = "ed4d5674ef4543b4eb463db168886dc7"
5 5SRC_URI[sha256sum] = "7436f5a19f93c3ca83153ce9c5cbe4847e97c5d956e57a220121e741f6e7968f"
6SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d"
7SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5"
8 6
9LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" 7LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
10 8