summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Yang <liezhi.yang@windriver.com>2015-03-26 06:42:34 (GMT)
committerTudor Florea <tudor.florea@enea.com>2015-09-09 01:26:32 (GMT)
commit66db094272742977499fd51f48ccba95ab34287b (patch)
tree9fe9698bca3f9c5d34bf0c461fb453bc01be2181
parentf0ade59b8c8c2f98968ac349cd7b180a08d894d9 (diff)
downloadpoky-66db094272742977499fd51f48ccba95ab34287b.tar.gz
patch: fix CVE-2015-1196
A directory traversal flaw was reported in patch: References: http://www.openwall.com/lists/oss-security/2015/01/18/6 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=775227 https://bugzilla.redhat.com/show_bug.cgi?id=1182154 [YOCTO #7182] (From OE-Core rev: 4c389880dc9c6221344f7aed221fe8356e8c2056) (From OE-Core rev: e2032c5788f7a77aa0e4e8545b550551c23a25fb) Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
-rw-r--r--meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch200
-rw-r--r--meta/recipes-devtools/patch/patch_2.7.1.bb1
2 files changed, 201 insertions, 0 deletions
diff --git a/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch b/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch
new file mode 100644
index 0000000..d408346
--- /dev/null
+++ b/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch
@@ -0,0 +1,200 @@
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.1.bb
index 7d009fe..8cea2eb 100644
--- a/meta/recipes-devtools/patch/patch_2.7.1.bb
+++ b/meta/recipes-devtools/patch/patch_2.7.1.bb
@@ -1,6 +1,7 @@
1require patch.inc 1require patch.inc
2LICENSE = "GPLv3" 2LICENSE = "GPLv3"
3 3
4SRC_URI += "file://patch-CVE-2015-1196.patch"
4 5
5SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d" 6SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d"
6SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5" 7SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5"