diff options
author | Robert Yang <liezhi.yang@windriver.com> | 2015-03-25 23:42:34 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-03-31 22:23:11 +0100 |
commit | c35aba339aa3ecc0c7b15c8423e81a9c9bca037b (patch) | |
tree | 4c0bf0fb233dd8244b8da558f9e640939524cb53 /meta | |
parent | 5c76cebc24675edb3dff473fce9b67cedff615db (diff) | |
download | poky-c35aba339aa3ecc0c7b15c8423e81a9c9bca037b.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)
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r-- | meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch | 200 | ||||
-rw-r--r-- | meta/recipes-devtools/patch/patch_2.7.1.bb | 1 |
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 0000000000..d408346ac2 --- /dev/null +++ b/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch | |||
@@ -0,0 +1,200 @@ | |||
1 | From 4e9269a5fc1fe80a1095a92593dd85db871e1fd3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Andreas Gruenbacher <andreas.gruenbacher@gmail.com> | ||
3 | Date: Mon, 19 Jan 2015 23:18:30 +0100 | ||
4 | Subject: [PATCH] Make sure symlinks don't point outside working directory | ||
5 | (CVE-2015-1196) | ||
6 | |||
7 | When creating symlinks from git-style patches, make sure the symlinks don't | ||
8 | point above the current working directory. Otherwise, a subsequent patch could | ||
9 | use the symlink to write outside the working directory. | ||
10 | |||
11 | * src/pch.c (symlink_target_is_valid): New function to check for valid symlink | ||
12 | targets. | ||
13 | * src/util.c (move_file): Use symlink_target_is_valid() here. | ||
14 | * tests/symlinks: Add valid and invalid symlink test cases. | ||
15 | |||
16 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> | ||
17 | |||
18 | Upstream-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 | |||
28 | diff --git a/NEWS b/NEWS | ||
29 | index 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. | ||
39 | diff --git a/src/pch.c b/src/pch.c | ||
40 | index 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 | ||
104 | diff --git a/src/pch.h b/src/pch.h | ||
105 | index 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; | ||
116 | diff --git a/src/util.c b/src/util.c | ||
117 | index 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) | ||
134 | diff --git a/tests/symlinks b/tests/symlinks | ||
135 | index 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 | -- | ||
199 | 2.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 3db318a7ec..1a3b9b1201 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 @@ | |||
1 | require patch.inc | 1 | require patch.inc |
2 | LICENSE = "GPLv3" | 2 | LICENSE = "GPLv3" |
3 | 3 | ||
4 | SRC_URI += "file://patch-CVE-2015-1196.patch" | ||
4 | 5 | ||
5 | SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d" | 6 | SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d" |
6 | SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5" | 7 | SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5" |