summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenzong Fan <wenzong.fan@windriver.com>2015-11-17 00:38:42 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-12-01 21:32:05 +0000
commit04034e75e0a75d97416d0e22c0a7028d14af011f (patch)
treef7c20598fa72029b2230a9a02949fd84d2c417ca
parentf91aedfb56f121883f341958fe9228dc7e75cf2f (diff)
downloadpoky-04034e75e0a75d97416d0e22c0a7028d14af011f.tar.gz
subversion: fix CVE-2015-3187
The svn_repos_trace_node_locations function in Apache Subversion before 1.7.21 and 1.8.x before 1.8.14, when path-based authorization is used, allows remote authenticated users to obtain sensitive path information by reading the history of a node that has been moved from a hidden path. Patch is from: http://subversion.apache.org/security/CVE-2015-3187-advisory.txt (From OE-Core rev: 6da25614edcad30fdb4bea8ff47b81ff81cdaed2) Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/subversion/subversion-1.8.13/subversion-CVE-2015-3187.patch346
-rw-r--r--meta/recipes-devtools/subversion/subversion_1.8.13.bb1
2 files changed, 347 insertions, 0 deletions
diff --git a/meta/recipes-devtools/subversion/subversion-1.8.13/subversion-CVE-2015-3187.patch b/meta/recipes-devtools/subversion/subversion-1.8.13/subversion-CVE-2015-3187.patch
new file mode 100644
index 0000000000..494e11c6c7
--- /dev/null
+++ b/meta/recipes-devtools/subversion/subversion-1.8.13/subversion-CVE-2015-3187.patch
@@ -0,0 +1,346 @@
1Fix CVE-2015-3187
2
3Patch is from:
4http://subversion.apache.org/security/CVE-2015-3187-advisory.txt
5
6Upstream-Status: Backport
7
8Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
9
10Index: subversion/libsvn_repos/rev_hunt.c
11===================================================================
12--- a/subversion/libsvn_repos/rev_hunt.c (revision 1685077)
13+++ b/subversion/libsvn_repos/rev_hunt.c (working copy)
14@@ -726,23 +726,6 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
15 if (! prev_path)
16 break;
17
18- if (authz_read_func)
19- {
20- svn_boolean_t readable;
21- svn_fs_root_t *tmp_root;
22-
23- SVN_ERR(svn_fs_revision_root(&tmp_root, fs, revision, currpool));
24- SVN_ERR(authz_read_func(&readable, tmp_root, path,
25- authz_read_baton, currpool));
26- if (! readable)
27- {
28- svn_pool_destroy(lastpool);
29- svn_pool_destroy(currpool);
30-
31- return SVN_NO_ERROR;
32- }
33- }
34-
35 /* Assign the current path to all younger revisions until we reach
36 the copy target rev. */
37 while ((revision_ptr < revision_ptr_end)
38@@ -765,6 +748,20 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
39 path = prev_path;
40 revision = prev_rev;
41
42+ if (authz_read_func)
43+ {
44+ svn_boolean_t readable;
45+ SVN_ERR(svn_fs_revision_root(&root, fs, revision, currpool));
46+ SVN_ERR(authz_read_func(&readable, root, path,
47+ authz_read_baton, currpool));
48+ if (!readable)
49+ {
50+ svn_pool_destroy(lastpool);
51+ svn_pool_destroy(currpool);
52+ return SVN_NO_ERROR;
53+ }
54+ }
55+
56 /* Clear last pool and switch. */
57 svn_pool_clear(lastpool);
58 tmppool = lastpool;
59Index: subversion/tests/cmdline/authz_tests.py
60===================================================================
61--- a/subversion/tests/cmdline/authz_tests.py (revision 1685077)
62+++ b/subversion/tests/cmdline/authz_tests.py (working copy)
63@@ -609,8 +609,10 @@ def authz_log_and_tracing_test(sbox):
64
65 ## cat
66
67+ expected_err2 = ".*svn: E195012: Unable to find repository location.*"
68+
69 # now see if we can look at the older version of rho
70- svntest.actions.run_and_verify_svn(None, None, expected_err,
71+ svntest.actions.run_and_verify_svn(None, None, expected_err2,
72 'cat', '-r', '2', D_url+'/rho')
73
74 if sbox.repo_url.startswith('http'):
75@@ -627,10 +629,11 @@ def authz_log_and_tracing_test(sbox):
76 svntest.actions.run_and_verify_svn(None, None, expected_err,
77 'diff', '-r', 'HEAD', G_url+'/rho')
78
79- svntest.actions.run_and_verify_svn(None, None, expected_err,
80+ # diff treats the unreadable path as indicating an add so no error
81+ svntest.actions.run_and_verify_svn(None, None, [],
82 'diff', '-r', '2', D_url+'/rho')
83
84- svntest.actions.run_and_verify_svn(None, None, expected_err,
85+ svntest.actions.run_and_verify_svn(None, None, [],
86 'diff', '-r', '2:4', D_url+'/rho')
87
88 # test whether read access is correctly granted and denied
89Index: subversion/tests/libsvn_repos/repos-test.c
90===================================================================
91--- a/subversion/tests/libsvn_repos/repos-test.c (revision 1685077)
92+++ b/subversion/tests/libsvn_repos/repos-test.c (working copy)
93@@ -3524,6 +3524,245 @@ test_load_r0_mergeinfo(const svn_test_opts_t *opts
94 return SVN_NO_ERROR;
95 }
96
97+static svn_error_t *
98+mkdir_delete_copy(svn_repos_t *repos,
99+ const char *src,
100+ const char *dst,
101+ apr_pool_t *pool)
102+{
103+ svn_fs_t *fs = svn_repos_fs(repos);
104+ svn_revnum_t youngest_rev;
105+ svn_fs_txn_t *txn;
106+ svn_fs_root_t *txn_root, *rev_root;
107+
108+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
109+
110+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
111+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
112+ SVN_ERR(svn_fs_make_dir(txn_root, "A/T", pool));
113+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
114+
115+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
116+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
117+ SVN_ERR(svn_fs_delete(txn_root, "A/T", pool));
118+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
119+
120+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
121+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
122+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, youngest_rev - 1, pool));
123+ SVN_ERR(svn_fs_copy(rev_root, src, txn_root, dst, pool));
124+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
125+
126+ return SVN_NO_ERROR;
127+}
128+
129+struct authz_read_baton_t {
130+ apr_hash_t *paths;
131+ apr_pool_t *pool;
132+ const char *deny;
133+};
134+
135+static svn_error_t *
136+authz_read_func(svn_boolean_t *allowed,
137+ svn_fs_root_t *root,
138+ const char *path,
139+ void *baton,
140+ apr_pool_t *pool)
141+{
142+ struct authz_read_baton_t *b = baton;
143+
144+ if (b->deny && !strcmp(b->deny, path))
145+ *allowed = FALSE;
146+ else
147+ *allowed = TRUE;
148+
149+ svn_hash_sets(b->paths, apr_pstrdup(b->pool, path), (void*)1);
150+
151+ return SVN_NO_ERROR;
152+}
153+
154+static svn_error_t *
155+verify_locations(apr_hash_t *actual,
156+ apr_hash_t *expected,
157+ apr_hash_t *checked,
158+ apr_pool_t *pool)
159+{
160+ apr_hash_index_t *hi;
161+
162+ for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi))
163+ {
164+ const svn_revnum_t *rev = svn__apr_hash_index_key(hi);
165+ const char *path = apr_hash_get(actual, rev, sizeof(svn_revnum_t));
166+
167+ if (!path)
168+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
169+ "expected %s for %d found (null)",
170+ (char*)svn__apr_hash_index_val(hi),
171+ (int)*rev);
172+ else if (strcmp(path, svn__apr_hash_index_val(hi)))
173+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
174+ "expected %s for %d found %s",
175+ (char*)svn__apr_hash_index_val(hi),
176+ (int)*rev, path);
177+
178+ }
179+
180+ for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi))
181+ {
182+ const svn_revnum_t *rev = svn__apr_hash_index_key(hi);
183+ const char *path = apr_hash_get(expected, rev, sizeof(svn_revnum_t));
184+
185+ if (!path)
186+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
187+ "found %s for %d expected (null)",
188+ (char*)svn__apr_hash_index_val(hi),
189+ (int)*rev);
190+ else if (strcmp(path, svn__apr_hash_index_val(hi)))
191+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
192+ "found %s for %d expected %s",
193+ (char*)svn__apr_hash_index_val(hi),
194+ (int)*rev, path);
195+
196+ if (!svn_hash_gets(checked, path))
197+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
198+ "did not check %s", path);
199+ }
200+
201+ return SVN_NO_ERROR;
202+}
203+
204+static void
205+set_expected(apr_hash_t *expected,
206+ svn_revnum_t rev,
207+ const char *path,
208+ apr_pool_t *pool)
209+{
210+ svn_revnum_t *rp = apr_palloc(pool, sizeof(svn_revnum_t));
211+ *rp = rev;
212+ apr_hash_set(expected, rp, sizeof(svn_revnum_t), path);
213+}
214+
215+static svn_error_t *
216+trace_node_locations_authz(const svn_test_opts_t *opts,
217+ apr_pool_t *pool)
218+{
219+ svn_repos_t *repos;
220+ svn_fs_t *fs;
221+ svn_revnum_t youngest_rev = 0;
222+ svn_fs_txn_t *txn;
223+ svn_fs_root_t *txn_root;
224+ struct authz_read_baton_t arb;
225+ apr_array_header_t *revs = apr_array_make(pool, 10, sizeof(svn_revnum_t));
226+ apr_hash_t *locations;
227+ apr_hash_t *expected = apr_hash_make(pool);
228+ int i;
229+
230+ /* Create test repository. */
231+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-trace-node-locations-authz",
232+ opts, pool));
233+ fs = svn_repos_fs(repos);
234+
235+ /* r1 create A */
236+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
237+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
238+ SVN_ERR(svn_fs_make_dir(txn_root, "A", pool));
239+ SVN_ERR(svn_fs_make_file(txn_root, "A/f", pool));
240+ SVN_ERR(svn_test__set_file_contents(txn_root, "A/f", "foobar", pool));
241+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
242+
243+ /* r4 copy A to B */
244+ SVN_ERR(mkdir_delete_copy(repos, "A", "B", pool));
245+
246+ /* r7 copy B to C */
247+ SVN_ERR(mkdir_delete_copy(repos, "B", "C", pool));
248+
249+ /* r10 copy C to D */
250+ SVN_ERR(mkdir_delete_copy(repos, "C", "D", pool));
251+
252+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
253+ SVN_ERR_ASSERT(youngest_rev == 10);
254+
255+ arb.paths = apr_hash_make(pool);
256+ arb.pool = pool;
257+ arb.deny = NULL;
258+
259+ apr_array_clear(revs);
260+ for (i = 0; i <= youngest_rev; ++i)
261+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
262+ set_expected(expected, 10, "/D/f", pool);
263+ set_expected(expected, 8, "/C/f", pool);
264+ set_expected(expected, 7, "/C/f", pool);
265+ set_expected(expected, 5, "/B/f", pool);
266+ set_expected(expected, 4, "/B/f", pool);
267+ set_expected(expected, 2, "/A/f", pool);
268+ set_expected(expected, 1, "/A/f", pool);
269+ apr_hash_clear(arb.paths);
270+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
271+ authz_read_func, &arb, pool));
272+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
273+
274+ apr_array_clear(revs);
275+ for (i = 1; i <= youngest_rev; ++i)
276+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
277+ apr_hash_clear(arb.paths);
278+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
279+ authz_read_func, &arb, pool));
280+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
281+
282+ apr_array_clear(revs);
283+ for (i = 2; i <= youngest_rev; ++i)
284+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
285+ set_expected(expected, 1, NULL, pool);
286+ apr_hash_clear(arb.paths);
287+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
288+ authz_read_func, &arb, pool));
289+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
290+
291+ apr_array_clear(revs);
292+ for (i = 3; i <= youngest_rev; ++i)
293+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
294+ set_expected(expected, 2, NULL, pool);
295+ apr_hash_clear(arb.paths);
296+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
297+ authz_read_func, &arb, pool));
298+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
299+
300+ apr_array_clear(revs);
301+ for (i = 6; i <= youngest_rev; ++i)
302+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
303+ set_expected(expected, 5, NULL, pool);
304+ set_expected(expected, 4, NULL, pool);
305+ apr_hash_clear(arb.paths);
306+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
307+ authz_read_func, &arb, pool));
308+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
309+
310+ arb.deny = "/B/f";
311+ apr_array_clear(revs);
312+ for (i = 0; i <= youngest_rev; ++i)
313+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
314+ apr_hash_clear(arb.paths);
315+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
316+ authz_read_func, &arb, pool));
317+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
318+
319+ apr_array_clear(revs);
320+ for (i = 6; i <= youngest_rev; ++i)
321+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
322+ apr_hash_clear(arb.paths);
323+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
324+ authz_read_func, &arb, pool));
325+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
326+
327+ APR_ARRAY_PUSH(revs, svn_revnum_t) = 0;
328+ apr_hash_clear(arb.paths);
329+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
330+ authz_read_func, &arb, pool));
331+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
332+
333+ return SVN_NO_ERROR;
334+}
335+
336 /* The test table. */
337
338 struct svn_test_descriptor_t test_funcs[] =
339@@ -3573,5 +3812,7 @@ struct svn_test_descriptor_t test_funcs[] =
340 "test dumping with r0 mergeinfo"),
341 SVN_TEST_OPTS_PASS(test_load_r0_mergeinfo,
342 "test loading with r0 mergeinfo"),
343+ SVN_TEST_OPTS_PASS(trace_node_locations_authz,
344+ "authz for svn_repos_trace_node_locations"),
345 SVN_TEST_NULL
346 };
diff --git a/meta/recipes-devtools/subversion/subversion_1.8.13.bb b/meta/recipes-devtools/subversion/subversion_1.8.13.bb
index 9505247be5..68934b7e02 100644
--- a/meta/recipes-devtools/subversion/subversion_1.8.13.bb
+++ b/meta/recipes-devtools/subversion/subversion_1.8.13.bb
@@ -15,6 +15,7 @@ SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \
15 file://disable_macos.patch \ 15 file://disable_macos.patch \
16 file://serf.m4-Regex-modified-to-allow-D-in-paths.patch \ 16 file://serf.m4-Regex-modified-to-allow-D-in-paths.patch \
17 file://subversion-CVE-2015-3184.patch \ 17 file://subversion-CVE-2015-3184.patch \
18 file://subversion-CVE-2015-3187.patch \
18" 19"
19SRC_URI[md5sum] = "4413417b529d7bdf82f74e50df02e88b" 20SRC_URI[md5sum] = "4413417b529d7bdf82f74e50df02e88b"
20SRC_URI[sha256sum] = "1099cc68840753b48aedb3a27ebd1e2afbcc84ddb871412e5d500e843d607579" 21SRC_URI[sha256sum] = "1099cc68840753b48aedb3a27ebd1e2afbcc84ddb871412e5d500e843d607579"