diff -u subversion-1.7.5/debian/changelog subversion-1.7.5/debian/changelog --- subversion-1.7.5/debian/changelog +++ subversion-1.7.5/debian/changelog @@ -1,3 +1,74 @@ +subversion (1.7.5-1+rpi4) wheezy-staging; urgency=low + + * Apply patch from upstream to bring us up to the same security fix level + as 1.6.17dfsg-4+deb7u10 + + patches/CVE-2015-3187.patch: svn_repos_trace_node_locations() reveals + paths hidden by authz + + -- Peter Michael Green Thu, 18 Feb 2016 12:21:25 +0000 + +subversion (1.7.5-1+rpi3) wheezy-staging; urgency=low + + * Apply security patches from upstream to bring us up to the same secuity + fix level as 1.6.17dfsg-4+deb7u9 + + patches/CVE-2015-0248.patch: Assertion DoS vulnerability for certain + mod_dav_svn and svnserve requests with dynamically evaluated revision + numbers + + patches/CVE-2015-0251.patch: mod_dav_svn allows spoofing svn:author + property values for new revisions + + -- Peter Michael Green Sat, 02 May 2015 00:44:51 +0000 + +subversion (1.7.5-1+rpi2) wheezy-staging; urgency=low + + * Apply fix from http://subversion.apache.org/security/CVE-2014-3580-advisory.txt + + This should bring us up to the same security fix level as + 1.6.17dfsg-4+deb7u8 + - note: the "regression fix" in 1.6.17dfsg-4+deb7u8 appears to be a + screwup in backporting the fix to the 1.6 series and therefore not + relavent for us. + * Disable testsuite, some ruby related stuff is failing. + + -- Peter Michael Green Sun, 11 Jan 2015 00:41:51 +0000 + +subversion (1.7.5-1+rpi1) wheezy-staging; urgency=low + * Add various security fixes, this should give us the same security fixes that + version 1.6.17dfsg-4+deb7u6 has. + + Fix taken from http://svn.apache.org/viewvc?view=revision&revision=r1557320 + * debian/patches/CVE-2014-0032.patch Disallow methods other than GET/HEAD + for the parentpath list. + + Fixes taken from 1.7.5-1ubuntu2.1 + * SECURITY UPDATE: denial of service in mod_dav_svn + - debian/patches/CVE-2013-1845.patch: handle multiple calls in + subversion/mod_dav_svn/deadprops.c. + - CVE-2013-1845 + * SECURITY UPDATE: denial of service in mod_dav_svn via LOCK + - debian/patches/CVE-2013-1846_1847.patch: properly validate locks in + subversion/mod_dav_svn/lock.c. + - CVE-2013-1846 + - CVE-2013-1847 + * SECURITY UPDATE: denial of service in mod_dav_svn via PROPFIND + - debian/patches/CVE-2013-1849.patch: validate type in + subversion/mod_dav_svn/liveprops.c. + - CVE-2013-1849 + * SECURITY UPDATE: denial of service in mod_dav_svn via log REPORT + - debian/patches/CVE-2013-1884.patch: fix error handling in + subversion/mod_dav_svn/reports/log.c. + - CVE-2013-1884 + * SECURITY UPDATE: repo corruption via newline chars in filenames + - debian/patches/CVE-2013-1968.patch: properly escape paths in + subversion/libsvn_fs_fs/tree.c, added test to + subversion/tests/libsvn_fs/fs-test.c. + - CVE-2013-1968 + * SECURITY UPDATE: denial of service via closed connection + - debian/patches/CVE-2013-2112.patch: check for closed connections in + subversion/svnserve/main.c. + - CVE-2013-2112 + + -- Peter Michael Green Sat, 22 Mar 2014 01:42:44 +0000 + subversion (1.7.5-1) unstable; urgency=low [ Peter Samuelson ] diff -u subversion-1.7.5/debian/rules subversion-1.7.5/debian/rules --- subversion-1.7.5/debian/rules +++ subversion-1.7.5/debian/rules @@ -130,6 +130,8 @@ DEB_OPT_NOCHECK := 1 endif +#Disable testsuite, some ruby related stuff is failing +DEB_OPT_NOCHECK := 1 # I'm not trying to be difficult: this check exists because building as # root really _does_ fail. The failure mode as of 1.4.0 is test 17 diff -u subversion-1.7.5/debian/patches/series subversion-1.7.5/debian/patches/series --- subversion-1.7.5/debian/patches/series +++ subversion-1.7.5/debian/patches/series @@ -23 +23,12 @@ +CVE-2013-1845.patch +CVE-2013-1846_1847.patch +CVE-2013-1849.patch +CVE-2013-1884.patch +CVE-2013-1968.patch +CVE-2013-2112.patch java-osgi-metadata +CVE-2014-0032.patch +CVE-2014-3580.patch +CVE-2015-0248.patch +CVE-2015-0251.patch +CVE-2015-3187.patch only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2013-2112.patch +++ subversion-1.7.5/debian/patches/CVE-2013-2112.patch @@ -0,0 +1,19 @@ +Description: fix denial of service via closed connection +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=711033 +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1485047 + +Index: subversion-1.7.5/subversion/svnserve/main.c +=================================================================== +--- subversion-1.7.5.orig/subversion/svnserve/main.c 2011-06-21 14:00:13.000000000 -0400 ++++ subversion-1.7.5/subversion/svnserve/main.c 2013-06-21 13:08:06.362542862 -0400 +@@ -928,7 +928,9 @@ + connection_pool) == APR_CHILD_DONE) + ; + } +- if (APR_STATUS_IS_EINTR(status)) ++ if (APR_STATUS_IS_EINTR(status) ++ || APR_STATUS_IS_ECONNABORTED(status) ++ || APR_STATUS_IS_ECONNRESET(status)) + { + svn_pool_destroy(connection_pool); + continue; only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2013-1849.patch +++ subversion-1.7.5/debian/patches/CVE-2013-1849.patch @@ -0,0 +1,28 @@ +Description: fix denial of service in mod_dav_svn via PROPFIND +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1461944 + +Index: subversion-1.7.5/subversion/mod_dav_svn/liveprops.c +=================================================================== +--- subversion-1.7.5.orig/subversion/mod_dav_svn/liveprops.c 2012-02-03 15:04:00.000000000 -0500 ++++ subversion-1.7.5/subversion/mod_dav_svn/liveprops.c 2013-06-21 13:06:23.922540239 -0400 +@@ -429,7 +429,8 @@ + svn_filesize_t len = 0; + + /* our property, but not defined on collection resources */ +- if (resource->collection || resource->baselined) ++ if (resource->type == DAV_RESOURCE_TYPE_ACTIVITY ++ || resource->collection || resource->baselined) + return DAV_PROP_INSERT_NOTSUPP; + + serr = svn_fs_file_length(&len, resource->info->root.root, +@@ -453,7 +454,9 @@ + svn_string_t *pval; + const char *mime_type = NULL; + +- if (resource->baselined && resource->type == DAV_RESOURCE_TYPE_VERSION) ++ if (resource->type == DAV_RESOURCE_TYPE_ACTIVITY ++ || (resource->baselined ++ && resource->type == DAV_RESOURCE_TYPE_VERSION)) + return DAV_PROP_INSERT_NOTSUPP; + + if (resource->type == DAV_RESOURCE_TYPE_PRIVATE only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2013-1845.patch +++ subversion-1.7.5/debian/patches/CVE-2013-1845.patch @@ -0,0 +1,107 @@ +Description: fix denial of service in mod_dav_svn +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1454237 + +Index: subversion-1.7.5/subversion/mod_dav_svn/deadprops.c +=================================================================== +--- subversion-1.7.5.orig/subversion/mod_dav_svn/deadprops.c 2010-12-30 15:46:50.000000000 -0500 ++++ subversion-1.7.5/subversion/mod_dav_svn/deadprops.c 2013-06-21 13:05:32.326538918 -0400 +@@ -168,6 +168,7 @@ + const char *propname; + svn_error_t *serr; + const dav_resource *resource = db->resource; ++ apr_pool_t *subpool; + + /* get the repos-local name */ + get_repos_propname(db, name, &propname); +@@ -202,13 +203,16 @@ + + */ + ++ /* A subpool to cope with mod_dav making multiple calls, e.g. during ++ PROPPATCH with multiple values. */ ++ subpool = svn_pool_create(db->resource->pool); + if (db->resource->baselined) + { + if (db->resource->working) + { + serr = svn_repos_fs_change_txn_prop(resource->info->root.txn, + propname, value, +- resource->pool); ++ subpool); + } + else + { +@@ -219,7 +223,7 @@ + TRUE, TRUE, + db->authz_read_func, + db->authz_read_baton, +- resource->pool); ++ subpool); + + /* Prepare any hook failure message to get sent over the wire */ + if (serr) +@@ -242,20 +246,21 @@ + dav_svn__operational_log(resource->info, + svn_log__change_rev_prop( + resource->info->root.rev, +- propname, resource->pool)); ++ propname, subpool)); + } + } + else if (resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION) + { + serr = svn_repos_fs_change_txn_prop(resource->info->root.txn, +- propname, value, resource->pool); ++ propname, value, subpool); + } + else + { + serr = svn_repos_fs_change_node_prop(resource->info->root.root, + get_repos_path(resource->info), +- propname, value, resource->pool); ++ propname, value, subpool); + } ++ svn_pool_destroy(subpool); + + if (serr != NULL) + return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, +@@ -540,6 +545,7 @@ + { + svn_error_t *serr; + const char *propname; ++ apr_pool_t *subpool; + + /* get the repos-local name */ + get_repos_propname(db, name, &propname); +@@ -548,11 +554,15 @@ + if (propname == NULL) + return NULL; + ++ /* A subpool to cope with mod_dav making multiple calls, e.g. during ++ PROPPATCH with multiple values. */ ++ subpool = svn_pool_create(db->resource->pool); ++ + /* Working Baseline or Working (Version) Resource */ + if (db->resource->baselined) + if (db->resource->working) + serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn, +- propname, NULL, db->resource->pool); ++ propname, NULL, subpool); + else + /* ### VIOLATING deltaV: you can't proppatch a baseline, it's + not a working resource! But this is how we currently +@@ -564,11 +574,12 @@ + propname, NULL, NULL, TRUE, TRUE, + db->authz_read_func, + db->authz_read_baton, +- db->resource->pool); ++ subpool); + else + serr = svn_repos_fs_change_node_prop(db->resource->info->root.root, + get_repos_path(db->resource->info), +- propname, NULL, db->resource->pool); ++ propname, NULL, subpool); ++ svn_pool_destroy(subpool); + if (serr != NULL) + return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, + "could not remove a property", only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2015-3187.patch +++ subversion-1.7.5/debian/patches/CVE-2015-3187.patch @@ -0,0 +1,416 @@ +Based on https://subversion.apache.org/security/CVE-2015-3187-advisory.txt + + svn_repos_trace_node_locations() reveals paths hidden by authz + +Summary +======= + + Subversion servers, both httpd and svnserve, will reveal some paths + that should be hidden by path-based authz. When a node is copied + from an unreadable location to a readable location the unreadable + path may be revealed. This vulnerablity only reveals the path, it + does not reveal the contents of the path. + +Known vulnerable +================ + + Subversion 1.8.0 to 1.8.13 + Subversion 1.7.0 to 1.7.20 + All older versions + +Known fixed +=========== + + Subversion 1.8.14 + Subversion 1.7.21 + +Details +======= + + The function svn_repos_trace_node_locations() follows the history of + a node through earlier revisions and shows any copies. It should + stop following history when an unreadable path is encountered but an + implementation error causes the first unreadable path to be returned + in some circumstances. This only reveals the unreadable path, it + does not reveal the content of the file or directory at that path. + Any attempts to obtain the content will fail with an authorization + error. + + Examples: + + 1. After copying "unreadable-path" to "readable-path" then following + the history of "readable-path" may reveal "unreadable-path". + + 2. After copying "unreadable/some-path" to "readable/other-path" + then following the history of "readable/other-path" may reveal + "unreadable/some-path". + +Severity +======== + + CVSSv2 Base Score: 3.5 + CVSSv2 Base Vector: AV:N/AC:M/Au:S/C:P/I:N/A:N + +Recommendations +=============== + + All Subversion servers using path-based authz to deny read access + to sensitive paths should be upgraded. + +References +========== + + CVE-2015-3187 (Subversion) + +Reported by +=========== + + C. Michael Pilato, CollabNet + +Patches +======= + +Patches: +======== + + + Patch for Subversion 1.7.20: +[[[ +Index: subversion-1.7.5/subversion/libsvn_repos/rev_hunt.c +=================================================================== +--- subversion-1.7.5.orig/subversion/libsvn_repos/rev_hunt.c 2012-02-02 13:43:43.000000000 +0000 ++++ subversion-1.7.5/subversion/libsvn_repos/rev_hunt.c 2016-02-18 12:38:22.959481657 +0000 +@@ -721,23 +721,6 @@ + if (! prev_path) + break; + +- if (authz_read_func) +- { +- svn_boolean_t readable; +- svn_fs_root_t *tmp_root; +- +- SVN_ERR(svn_fs_revision_root(&tmp_root, fs, revision, currpool)); +- SVN_ERR(authz_read_func(&readable, tmp_root, path, +- authz_read_baton, currpool)); +- if (! readable) +- { +- svn_pool_destroy(lastpool); +- svn_pool_destroy(currpool); +- +- return SVN_NO_ERROR; +- } +- } +- + /* Assign the current path to all younger revisions until we reach + the copy target rev. */ + while ((revision_ptr < revision_ptr_end) +@@ -760,6 +743,20 @@ + path = prev_path; + revision = prev_rev; + ++ if (authz_read_func) ++ { ++ svn_boolean_t readable; ++ SVN_ERR(svn_fs_revision_root(&root, fs, revision, currpool)); ++ SVN_ERR(authz_read_func(&readable, root, path, ++ authz_read_baton, currpool)); ++ if (!readable) ++ { ++ svn_pool_destroy(lastpool); ++ svn_pool_destroy(currpool); ++ return SVN_NO_ERROR; ++ } ++ } ++ + /* Clear last pool and switch. */ + svn_pool_clear(lastpool); + tmppool = lastpool; +Index: subversion-1.7.5/subversion/tests/cmdline/authz_tests.py +=================================================================== +--- subversion-1.7.5.orig/subversion/tests/cmdline/authz_tests.py 2011-10-20 13:02:54.000000000 +0000 ++++ subversion-1.7.5/subversion/tests/cmdline/authz_tests.py 2016-02-18 12:38:22.959481657 +0000 +@@ -608,8 +608,10 @@ + + ## cat + ++ expected_err2 = ".*svn: E195012: Unable to find repository location.*" ++ + # now see if we can look at the older version of rho +- svntest.actions.run_and_verify_svn(None, None, expected_err, ++ svntest.actions.run_and_verify_svn(None, None, expected_err2, + 'cat', '-r', '2', D_url+'/rho') + + if sbox.repo_url.startswith('http'): +@@ -626,10 +628,11 @@ + svntest.actions.run_and_verify_svn(None, None, expected_err, + 'diff', '-r', 'HEAD', G_url+'/rho') + +- svntest.actions.run_and_verify_svn(None, None, expected_err, ++ # diff treats the unreadable path as indicating an add so no error ++ svntest.actions.run_and_verify_svn(None, None, [], + 'diff', '-r', '2', D_url+'/rho') + +- svntest.actions.run_and_verify_svn(None, None, expected_err, ++ svntest.actions.run_and_verify_svn(None, None, [], + 'diff', '-r', '2:4', D_url+'/rho') + + # test whether read access is correctly granted and denied +Index: subversion-1.7.5/subversion/tests/libsvn_repos/repos-test.c +=================================================================== +--- subversion-1.7.5.orig/subversion/tests/libsvn_repos/repos-test.c 2011-11-15 18:13:44.000000000 +0000 ++++ subversion-1.7.5/subversion/tests/libsvn_repos/repos-test.c 2016-02-18 12:38:22.964481646 +0000 +@@ -2526,6 +2526,246 @@ + return SVN_NO_ERROR; + } + ++static svn_error_t * ++mkdir_delete_copy(svn_repos_t *repos, ++ const char *src, ++ const char *dst, ++ apr_pool_t *pool) ++{ ++ svn_fs_t *fs = svn_repos_fs(repos); ++ svn_revnum_t youngest_rev; ++ svn_fs_txn_t *txn; ++ svn_fs_root_t *txn_root, *rev_root; ++ ++ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool)); ++ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_make_dir(txn_root, "A/T", pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_delete(txn_root, "A/T", pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_revision_root(&rev_root, fs, youngest_rev - 1, pool)); ++ SVN_ERR(svn_fs_copy(rev_root, src, txn_root, dst, pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ return SVN_NO_ERROR; ++} ++ ++struct authz_read_baton_t { ++ apr_hash_t *paths; ++ apr_pool_t *pool; ++ const char *deny; ++}; ++ ++static svn_error_t * ++authz_read_func(svn_boolean_t *allowed, ++ svn_fs_root_t *root, ++ const char *path, ++ void *baton, ++ apr_pool_t *pool) ++{ ++ struct authz_read_baton_t *b = baton; ++ ++ if (b->deny && !strcmp(b->deny, path)) ++ *allowed = FALSE; ++ else ++ *allowed = TRUE; ++ ++ apr_hash_set(b->paths, apr_pstrdup(b->pool, path), APR_HASH_KEY_STRING, ++ (void*)1); ++ ++ return SVN_NO_ERROR; ++} ++ ++static svn_error_t * ++verify_locations(apr_hash_t *actual, ++ apr_hash_t *expected, ++ apr_hash_t *checked, ++ apr_pool_t *pool) ++{ ++ apr_hash_index_t *hi; ++ ++ for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi)) ++ { ++ const svn_revnum_t *rev = svn__apr_hash_index_key(hi); ++ const char *path = apr_hash_get(actual, rev, sizeof(svn_revnum_t)); ++ ++ if (!path) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "expected %s for %d found (null)", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev); ++ else if (strcmp(path, svn__apr_hash_index_val(hi))) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "expected %s for %d found %s", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev, path); ++ ++ } ++ ++ for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi)) ++ { ++ const svn_revnum_t *rev = svn__apr_hash_index_key(hi); ++ const char *path = apr_hash_get(expected, rev, sizeof(svn_revnum_t)); ++ ++ if (!path) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "found %s for %d expected (null)", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev); ++ else if (strcmp(path, svn__apr_hash_index_val(hi))) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "found %s for %d expected %s", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev, path); ++ ++ if (!apr_hash_get(checked, path, APR_HASH_KEY_STRING)) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "did not check %s", path); ++ } ++ ++ return SVN_NO_ERROR; ++} ++ ++static void ++set_expected(apr_hash_t *expected, ++ svn_revnum_t rev, ++ const char *path, ++ apr_pool_t *pool) ++{ ++ svn_revnum_t *rp = apr_palloc(pool, sizeof(svn_revnum_t)); ++ *rp = rev; ++ apr_hash_set(expected, rp, sizeof(svn_revnum_t), path); ++} ++ ++static svn_error_t * ++trace_node_locations_authz(const svn_test_opts_t *opts, ++ apr_pool_t *pool) ++{ ++ svn_repos_t *repos; ++ svn_fs_t *fs; ++ svn_revnum_t youngest_rev = 0; ++ svn_fs_txn_t *txn; ++ svn_fs_root_t *txn_root; ++ struct authz_read_baton_t arb; ++ apr_array_header_t *revs = apr_array_make(pool, 10, sizeof(svn_revnum_t)); ++ apr_hash_t *locations; ++ apr_hash_t *expected = apr_hash_make(pool); ++ int i; ++ ++ /* Create test repository. */ ++ SVN_ERR(svn_test__create_repos(&repos, "test-repo-trace-node-locations-authz", ++ opts, pool)); ++ fs = svn_repos_fs(repos); ++ ++ /* r1 create A */ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_make_dir(txn_root, "A", pool)); ++ SVN_ERR(svn_fs_make_file(txn_root, "A/f", pool)); ++ SVN_ERR(svn_test__set_file_contents(txn_root, "A/f", "foobar", pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ /* r4 copy A to B */ ++ SVN_ERR(mkdir_delete_copy(repos, "A", "B", pool)); ++ ++ /* r7 copy B to C */ ++ SVN_ERR(mkdir_delete_copy(repos, "B", "C", pool)); ++ ++ /* r10 copy C to D */ ++ SVN_ERR(mkdir_delete_copy(repos, "C", "D", pool)); ++ ++ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool)); ++ SVN_ERR_ASSERT(youngest_rev == 10); ++ ++ arb.paths = apr_hash_make(pool); ++ arb.pool = pool; ++ arb.deny = NULL; ++ ++ apr_array_clear(revs); ++ for (i = 0; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 10, "/D/f", pool); ++ set_expected(expected, 8, "/C/f", pool); ++ set_expected(expected, 7, "/C/f", pool); ++ set_expected(expected, 5, "/B/f", pool); ++ set_expected(expected, 4, "/B/f", pool); ++ set_expected(expected, 2, "/A/f", pool); ++ set_expected(expected, 1, "/A/f", pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 1; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 2; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 1, NULL, pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 3; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 2, NULL, pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 6; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 5, NULL, pool); ++ set_expected(expected, 4, NULL, pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ arb.deny = "/B/f"; ++ apr_array_clear(revs); ++ for (i = 0; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 6; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = 0; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ return SVN_NO_ERROR; ++} ++ + + /* The test table. */ + +@@ -2562,5 +2802,7 @@ + "test svn_repos_get_file_revsN"), + SVN_TEST_OPTS_PASS(issue_4060, + "test issue 4060"), ++ SVN_TEST_OPTS_PASS(trace_node_locations_authz, ++ "authz for svn_repos_trace_node_locations"), + SVN_TEST_NULL + }; only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2014-3580.patch +++ subversion-1.7.5/debian/patches/CVE-2014-3580.patch @@ -0,0 +1,173 @@ +Note: the bulk of this file was taken unmodified from +http://subversion.apache.org/security/CVE-2014-3580-advisory.txt +but the 1.7.x patch had some filename tweaking so quilt can apply it +and the 1.8.x patch was removed to stop quilt trying to apply it. + + mod_dav_svn is vulnerable to a remotely triggerable segfault DoS + vulnerability with certain invalid REPORT requests. + +Summary: +======== + + Subversion's mod_dav_svn Apache HTTPD server module will crash when it + receives a REPORT request for some invalid formatted special URIs. + + This can lead to a DoS. There are no known instances of this problem + being exploited in the wild. + +Known vulnerable: +================= + + Subversion HTTPD servers 1.0.0 through 1.7.18 (inclusive) + Subversion HTTPD servers 1.8.0 through 1.8.10 (inclusive) + +Known fixed: +============ + + Subversion 1.7.19 + Subversion 1.8.11 + +Details: +======== + + Subversion's HTTP support is implemented as an interaction between mod_dav + and mod_dav_svn. mod_dav asks mod_dav_svn to fill a resource struct when + a request is made. When the resource doesn't exist in the repository the + repository path is calculated as a NULL. Later mod_dav calls into + mod_dav_svn to actually handle the request and Subversion attempts to + use the repostiory path which is NULL, resulting in the SEGFAULT. + +Severity: +========= + + CVSSv2 Base Score: 5.0 + CVSSv2 Base Vector: AV:N/AC:L/Au:N/C:N/I:N/A:P + + We consider this to be a medium risk vulnerability. Repositories which + allow for anonymous reads will be vulnerable without authentication. + Unfortunately, no special configuration is required and all mod_dav_svn + servers are vulnerable. + + A remote attacker may be able to crash a Subversion server. Many Apache + servers will respawn the listener processes, but a determined attacker + will be able to crash these processes as they appear, denying service to + legitimate users. Servers using threaded MPMs will close the connection + on other clients being served by the same process that services the + request from the attacker. In either case there is an increased + processing impact of restarting a process and the cost of per process + caches being lost. + +Recommendations: +================ + + We recommend all users to upgrade to Subversion 1.8.11. Users of + Subversion 1.7.x or 1.8.x who are unable to upgrade may apply the + included patch. + + New Subversion packages can be found at: + http://subversion.apache.org/packages.html + + No known workarounds are available. + +References: +=========== + + CVE-2014-3580 (Subversion) + +Reported by: +============ + + Evgeny Kotkov, VisualSVN + +Patches: +======== + + Patch against 1.7.18: + +[[[ +Index: x/subversion/mod_dav_svn/reports/deleted-rev.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/deleted-rev.c (revision 1624477) ++++ x/subversion/mod_dav_svn/reports/deleted-rev.c (working copy) +@@ -56,6 +56,9 @@ dav_svn__get_deleted_rev_report(const dav_resource + dav_error *derr = NULL; + + /* Sanity check. */ ++ if (!resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, ++ "The request does not specify a repository path"); + ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); + if (ns == -1) + return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, +Index: x/subversion/mod_dav_svn/reports/file-revs.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/file-revs.c (revision 1624477) ++++ x/subversion/mod_dav_svn/reports/file-revs.c (working copy) +@@ -251,6 +251,9 @@ dav_svn__file_revs_report(const dav_resource *reso + arb.repos = resource->info->repos; + + /* Sanity check. */ ++ if (!resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, ++ "The request does not specify a repository path"); + ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); + /* ### This is done on other places, but the document element is + in this namespace, so is this necessary at all? */ +Index: x/subversion/mod_dav_svn/reports/get-location-segments.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/get-location-segments.c (revision 1624477) ++++ x/subversion/mod_dav_svn/reports/get-location-segments.c (working copy) +@@ -123,6 +123,9 @@ dav_svn__get_location_segments_report(const dav_re + struct location_segment_baton location_segment_baton; + + /* Sanity check. */ ++ if (!resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, ++ "The request does not specify a repository path"); + ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); + if (ns == -1) + { +Index: x/subversion/mod_dav_svn/reports/get-locations.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/get-locations.c (revision 1624477) ++++ x/subversion/mod_dav_svn/reports/get-locations.c (working copy) +@@ -106,6 +106,9 @@ dav_svn__get_locations_report(const dav_resource * + sizeof(svn_revnum_t)); + + /* Sanity check. */ ++ if (!resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, ++ "The request does not specify a repository path"); + ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); + if (ns == -1) + { +Index: x/subversion/mod_dav_svn/reports/log.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/log.c (revision 1624477) ++++ x/subversion/mod_dav_svn/reports/log.c (working copy) +@@ -307,6 +307,9 @@ dav_svn__log_report(const dav_resource *resource, + = apr_array_make(resource->pool, 1, sizeof(const char *)); + + /* Sanity check. */ ++ if (!resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, ++ "The request does not specify a repository path"); + ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); + if (ns == -1) + { +Index: x/subversion/mod_dav_svn/reports/mergeinfo.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/mergeinfo.c (revision 1624477) ++++ x/subversion/mod_dav_svn/reports/mergeinfo.c (working copy) +@@ -67,6 +67,9 @@ dav_svn__get_mergeinfo_report(const dav_resource * + = apr_array_make(resource->pool, 0, sizeof(const char *)); + + /* Sanity check. */ ++ if (!resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, ++ "The request does not specify a repository path"); + ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); + if (ns == -1) + { +]]] + only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2013-1968.patch +++ subversion-1.7.5/debian/patches/CVE-2013-1968.patch @@ -0,0 +1,197 @@ +Description: fix repo corruption via newline chars in filenames +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=711033 +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1485182 + +Index: subversion-1.7.5/subversion/libsvn_fs_fs/tree.c +=================================================================== +--- subversion-1.7.5.orig/subversion/libsvn_fs_fs/tree.c 2012-03-27 00:02:36.000000000 -0400 ++++ subversion-1.7.5/subversion/libsvn_fs_fs/tree.c 2013-06-21 13:07:28.498541892 -0400 +@@ -44,6 +44,7 @@ + #include "svn_private_config.h" + #include "svn_pools.h" + #include "svn_error.h" ++#include "svn_ctype.h" + #include "svn_dirent_uri.h" + #include "svn_path.h" + #include "svn_mergeinfo.h" +@@ -1806,6 +1807,78 @@ + return svn_fs_fs__dag_dir_entries(table_p, node, pool, pool); + } + ++/* Return a copy of PATH, allocated from POOL, for which control ++ characters have been escaped using the form \NNN (where NNN is the ++ octal representation of the byte's ordinal value). */ ++static const char * ++illegal_path_escape(const char *path, apr_pool_t *pool) ++{ ++ svn_stringbuf_t *retstr; ++ apr_size_t i, copied = 0; ++ int c; ++ ++ /* At least one control character: ++ strlen - 1 (control) + \ + N + N + N + null . */ ++ retstr = svn_stringbuf_create_ensure(strlen(path) + 4, pool); ++ for (i = 0; path[i]; i++) ++ { ++ c = (unsigned char)path[i]; ++ if (! svn_ctype_iscntrl(c)) ++ continue; ++ ++ /* If we got here, we're looking at a character that isn't ++ supported by the (or at least, our) URI encoding scheme. We ++ need to escape this character. */ ++ ++ /* First things first, copy all the good stuff that we haven't ++ yet copied into our output buffer. */ ++ if (i - copied) ++ svn_stringbuf_appendbytes(retstr, path + copied, ++ i - copied); ++ ++ /* Make sure buffer is big enough for '\' 'N' 'N' 'N' (and NUL) */ ++ svn_stringbuf_ensure(retstr, retstr->len + 5); ++ /*### The backslash separator doesn't work too great with Windows, ++ but it's what we'll use for consistency with invalid utf8 ++ formatting (until someone has a better idea) */ ++ apr_snprintf(retstr->data + retstr->len, 5, "\\%03o", (unsigned char)c); ++ retstr->len += 4; ++ ++ /* Finally, update our copy counter. */ ++ copied = i + 1; ++ } ++ ++ /* If we didn't encode anything, we don't need to duplicate the string. */ ++ if (retstr->len == 0) ++ return path; ++ ++ /* Anything left to copy? */ ++ if (i - copied) ++ svn_stringbuf_appendbytes(retstr, path + copied, i - copied); ++ ++ /* retstr is null-terminated either by apr_snprintf or the svn_stringbuf ++ functions. */ ++ ++ return retstr->data; ++} ++ ++/* Raise an error if PATH contains a newline because FSFS cannot handle ++ * such paths. See issue #4340. */ ++static svn_error_t * ++check_newline(const char *path, apr_pool_t *pool) ++{ ++ const char *c; ++ ++ for (c = path; *c; c++) ++ { ++ if (*c == '\n') ++ return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL, ++ _("Invalid control character '0x%02x' in path '%s'"), ++ (unsigned char)*c, illegal_path_escape(path, pool)); ++ } ++ ++ return SVN_NO_ERROR; ++} + + /* Create a new directory named PATH in ROOT. The new directory has + no entries, and no properties. ROOT must be the root of a +@@ -1820,6 +1893,8 @@ + dag_node_t *sub_dir; + const char *txn_id = root->txn; + ++ SVN_ERR(check_newline(path, pool)); ++ + SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional, + txn_id, pool)); + +@@ -2082,6 +2157,8 @@ + const char *to_path, + apr_pool_t *pool) + { ++ SVN_ERR(check_newline(to_path, pool)); ++ + return svn_error_trace(copy_helper(from_root, from_path, to_root, to_path, + TRUE, pool)); + } +@@ -2174,6 +2251,8 @@ + dag_node_t *child; + const char *txn_id = root->txn; + ++ SVN_ERR(check_newline(path, pool)); ++ + SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional, + txn_id, pool)); + +Index: subversion-1.7.5/subversion/tests/libsvn_fs/fs-test.c +=================================================================== +--- subversion-1.7.5.orig/subversion/tests/libsvn_fs/fs-test.c 2011-04-13 05:06:07.000000000 -0400 ++++ subversion-1.7.5/subversion/tests/libsvn_fs/fs-test.c 2013-06-21 13:07:31.522541970 -0400 +@@ -4799,6 +4799,62 @@ + return SVN_NO_ERROR; + } + ++/* Issue 4340, "fs layer should reject filenames with trailing \n" */ ++static svn_error_t * ++filename_trailing_newline(const svn_test_opts_t *opts, ++ apr_pool_t *pool) ++{ ++ apr_pool_t *subpool = svn_pool_create(pool); ++ svn_fs_t *fs; ++ svn_fs_txn_t *txn; ++ svn_fs_root_t *txn_root, *root; ++ svn_revnum_t youngest_rev = 0; ++ svn_error_t *err; ++ svn_boolean_t allow_newlines; ++ ++ /* Some filesystem implementations can handle newlines in filenames ++ * and can be white-listed here. ++ * Currently, only BDB supports \n in filenames. */ ++ allow_newlines = (strcmp(opts->fs_type, "bdb") == 0); ++ ++ SVN_ERR(svn_test__create_fs(&fs, "test-filename-trailing-newline", ++ opts, pool)); ++ ++ /* Revision 1: Add a directory /foo */ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); ++ SVN_ERR(svn_fs_make_dir(txn_root, "/foo", subpool)); ++ SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn, subpool)); ++ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev)); ++ svn_pool_clear(subpool); ++ ++ /* Attempt to copy /foo to "/bar\n". This should fail on FSFS. */ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); ++ SVN_ERR(svn_fs_revision_root(&root, fs, youngest_rev, subpool)); ++ err = svn_fs_copy(root, "/foo", txn_root, "/bar\n", subpool); ++ if (allow_newlines) ++ SVN_TEST_ASSERT(err == SVN_NO_ERROR); ++ else ++ { ++ SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_FS_PATH_SYNTAX); ++ svn_error_clear(err); ++ } ++ ++ /* Attempt to create a file /foo/baz\n. This should fail on FSFS. */ ++ err = svn_fs_make_file(txn_root, "/foo/baz\n", subpool); ++ if (allow_newlines) ++ SVN_TEST_ASSERT(err == SVN_NO_ERROR); ++ else ++ { ++ SVN_TEST_ASSERT(err && err->apr_err == SVN_ERR_FS_PATH_SYNTAX); ++ svn_error_clear(err); ++ } ++ ++ return SVN_NO_ERROR; ++} ++ ++ + /* ------------------------------------------------------------------------ */ + + /* The test table. */ +@@ -4878,5 +4934,7 @@ + "test svn_fs_node_origin_rev"), + SVN_TEST_OPTS_PASS(small_file_integrity, + "create and modify small file"), ++ SVN_TEST_OPTS_PASS(filename_trailing_newline, ++ "filenames with trailing \\n might be rejected"), + SVN_TEST_NULL + }; only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2014-0032.patch +++ subversion-1.7.5/debian/patches/CVE-2014-0032.patch @@ -0,0 +1,47 @@ +Patch taken from http://svn.apache.org/viewvc?view=revision&revision=r1557320 + +Backported to version in raspbian by Peter Michael Green. + +Disallow methods other than GET/HEAD for the parentpath list. + +Fixes the segfault for `svn ls http://svn.example.com` when SVN is handling +the server root and SVNListParentPath is on. + +CVE-2014-0032 + +* subversion/mod_dav_svn/repos.c + (get_resource): Return an error when we try to get a parentpath list + resource and the method isn't GET. + +Found by: lgo + +Index: subversion-1.7.5/subversion/mod_dav_svn/repos.c +=================================================================== +--- subversion-1.7.5.orig/subversion/mod_dav_svn/repos.c 2012-04-21 04:01:42.000000000 +0000 ++++ subversion-1.7.5/subversion/mod_dav_svn/repos.c 2014-03-22 01:51:24.000000000 +0000 +@@ -1954,6 +1954,25 @@ + of private resource, iff the SVNListParentPath directive is 'on'. */ + if (fs_parent_path && dav_svn__get_list_parentpath_flag(r)) + { ++ /* Only allow GET and HEAD on the parentpath resource ++ * httpd uses the same method_number for HEAD as GET */ ++ if (r->method_number != M_GET) ++ { ++ int status; ++ ++ /* Marshall the error back to the client by generating by ++ * way of the dav_svn__error_response_tag trick. */ ++ err = dav_svn__new_error(r->pool, HTTP_METHOD_NOT_ALLOWED, ++ SVN_ERR_APMOD_MALFORMED_URI, ++ "The URI does not contain the name " ++ "of a repository."); ++ /* can't use r->allowed since the default handler isn't called */ ++ apr_table_setn(r->headers_out, "Allow", "GET,HEAD"); ++ status = dav_svn__error_response_tag(r, err); ++ ++ return dav_push_error(r->pool, status, err->error_id, NULL, err); ++ } ++ + char *uri = apr_pstrdup(r->pool, r->uri); + char *parentpath = apr_pstrdup(r->pool, root_path); + apr_size_t uri_len = strlen(uri); only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2015-0248.patch +++ subversion-1.7.5/debian/patches/CVE-2015-0248.patch @@ -0,0 +1,211 @@ +Note: the bulk of this file was taken unmodified from +http://subversion.apache.org/security/CVE-2015-0248-advisory.txt +but the 1.7.x patch had some filename tweaking so quilt can apply it +and the 1.8.x patch was removed to stop quilt trying to apply it. + + Subversion mod_dav_svn and svnserve are vulnerable to a remotely triggerable + assertion DoS vulnerability for certain requests with dynamically evaluated + revision numbers. + +Summary: +======== + + Subversion's mod_dav_svn and svnserve servers will trigger an assertion + while processing some requests with special parameters, which are evaluated + on the server side. Assertion will cause svnserve process or the process + hosting mod_dav_svn module (Apache) to abort. + + This can lead to a DoS. There are no known instances of this problem + being exploited in the wild, but an exploit has been tested. + +Known vulnerable: +================= + + Subversion servers 1.6.0 through 1.7.19 (inclusive) + Subversion servers 1.8.0 through 1.8.11 (inclusive) + +Known fixed: +============ + + Subversion 1.7.20 + Subversion 1.8.13 + + Subversion 1.8.12 was not publicly released. + +Details: +======== + + Subversion's http:// and svn:// protocol support includes certain request + types with parameters, which are evaluated on the server side. As an + example, sometimes clients need to trace the history of the object to its + origin, while not knowing the exact value of the origin (revision number) + prior to issuing the request. + + Certain parameter combinations can exploit this behavior and force a server + into attempting an operation with invalid arguments. Subversion servers + guard against these situations with assertion statements, and the default + behavior for a failed assertion is to abort the current process. + +Severity: +========= + + CVSSv2 Base Score: 5.0 + CVSSv2 Base Vector: AV:N/AC:L/Au:N/C:N/I:N/A:P + + We consider this to be a medium risk vulnerability. + + Apache HTTPD servers with repositories that allow anonymous reads will be + vulnerable without authentication. Many Apache servers will respawn the + listener processes, but a determined attacker will be able to crash these + processes as they appear, denying service to legitimate users. Servers + using threaded MPMs will close the connection on other clients being + served by the same process that services the request from the attacker. + In either case there is an increased processing impact of restarting a + process and the cost of per process caches being lost. + + Exploiting this behavior against svnserve does not require an attacker to + authenticate. A remote attacker can cause svnserve process to terminate + and thus deny service to users of the server. + + Unfortunately, no special configuration is required and all mod_dav_svn + and svnserve servers are vulnerable. + +Recommendations: +================ + + We recommend all users to upgrade to Subversion 1.8.13. Users of + Subversion 1.7.x or 1.8.x who are unable to upgrade may apply the + included patch. + + New Subversion packages can be found at: + http://subversion.apache.org/packages.html + + No known workarounds are available. + +References: +=========== + + CVE-2015-0248 (Subversion) + +Reported by: +============ + + Evgeny Kotkov, VisualSVN + +Patches: +======== + + Patch against 1.7.19: +[[[ +Index: x/subversion/mod_dav_svn/reports/get-location-segments.c +=================================================================== +--- x/subversion/mod_dav_svn/reports/get-location-segments.c (revision 1658197) ++++ x/subversion/mod_dav_svn/reports/get-location-segments.c (working copy) +@@ -181,17 +181,36 @@ dav_svn__get_location_segments_report(const dav_re + "Not all parameters passed.", + SVN_DAV_ERROR_NAMESPACE, + SVN_DAV_ERROR_TAG); +- if (SVN_IS_VALID_REVNUM(start_rev) +- && SVN_IS_VALID_REVNUM(end_rev) +- && (end_rev > start_rev)) ++ ++ /* No START_REV or PEG_REVISION? We'll use HEAD. */ ++ if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision)) ++ { ++ svn_revnum_t youngest; ++ ++ serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs, ++ resource->pool); ++ if (serr != NULL) ++ return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, ++ "Could not determine youngest revision", ++ resource->pool); ++ ++ if (!SVN_IS_VALID_REVNUM(start_rev)) ++ start_rev = youngest; ++ if (!SVN_IS_VALID_REVNUM(peg_revision)) ++ peg_revision = youngest; ++ } ++ ++ /* No END_REV? We'll use 0. */ ++ if (!SVN_IS_VALID_REVNUM(end_rev)) ++ end_rev = 0; ++ ++ if (end_rev > start_rev) + return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, + "End revision must not be younger than " + "start revision", + SVN_DAV_ERROR_NAMESPACE, + SVN_DAV_ERROR_TAG); +- if (SVN_IS_VALID_REVNUM(peg_revision) +- && SVN_IS_VALID_REVNUM(start_rev) +- && (start_rev > peg_revision)) ++ if (start_rev > peg_revision) + return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, + "Start revision must not be younger than " + "peg revision", +Index: x/subversion/svnserve/serve.c +=================================================================== +--- x/subversion/svnserve/serve.c (revision 1658197) ++++ x/subversion/svnserve/serve.c (working copy) +@@ -2266,10 +2266,31 @@ static svn_error_t *get_location_segments(svn_ra_s + + abs_path = svn_fspath__join(b->fs_path->data, relative_path, pool); + +- if (SVN_IS_VALID_REVNUM(start_rev) +- && SVN_IS_VALID_REVNUM(end_rev) +- && (end_rev > start_rev)) ++ SVN_ERR(trivial_auth_request(conn, pool, b)); ++ SVN_ERR(log_command(baton, conn, pool, "%s", ++ svn_log__get_location_segments(abs_path, peg_revision, ++ start_rev, end_rev, ++ pool))); ++ ++ /* No START_REV or PEG_REVISION? We'll use HEAD. */ ++ if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision)) + { ++ svn_revnum_t youngest; ++ ++ SVN_CMD_ERR(svn_fs_youngest_rev(&youngest, b->fs, pool)); ++ ++ if (!SVN_IS_VALID_REVNUM(start_rev)) ++ start_rev = youngest; ++ if (!SVN_IS_VALID_REVNUM(peg_revision)) ++ peg_revision = youngest; ++ } ++ ++ /* No END_REV? We'll use 0. */ ++ if (!SVN_IS_VALID_REVNUM(end_rev)) ++ end_rev = 0; ++ ++ if (end_rev > start_rev) ++ { + err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, + "Get-location-segments end revision must not be " + "younger than start revision"); +@@ -2276,9 +2297,7 @@ static svn_error_t *get_location_segments(svn_ra_s + return log_fail_and_flush(err, b, conn, pool); + } + +- if (SVN_IS_VALID_REVNUM(peg_revision) +- && SVN_IS_VALID_REVNUM(start_rev) +- && (start_rev > peg_revision)) ++ if (start_rev > peg_revision) + { + err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, + "Get-location-segments start revision must not " +@@ -2286,12 +2305,6 @@ static svn_error_t *get_location_segments(svn_ra_s + return log_fail_and_flush(err, b, conn, pool); + } + +- SVN_ERR(trivial_auth_request(conn, pool, b)); +- SVN_ERR(log_command(baton, conn, pool, "%s", +- svn_log__get_location_segments(abs_path, peg_revision, +- start_rev, end_rev, +- pool))); +- + /* All the parameters are fine - let's perform the query against the + * repository. */ + +]]] + only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2013-1884.patch +++ subversion-1.7.5/debian/patches/CVE-2013-1884.patch @@ -0,0 +1,19 @@ +Description: fix denial of service in mod_dav_svn via log REPORT +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1462332 + +Index: subversion-1.7.5/subversion/mod_dav_svn/reports/log.c +=================================================================== +--- subversion-1.7.5.orig/subversion/mod_dav_svn/reports/log.c 2012-01-11 10:57:13.000000000 -0500 ++++ subversion-1.7.5/subversion/mod_dav_svn/reports/log.c 2013-06-21 13:06:51.186540937 -0400 +@@ -341,10 +341,9 @@ + dav_xml_get_cdata(child, resource->pool, 1)); + if (serr) + { +- derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, ++ return dav_svn__convert_err(serr, HTTP_BAD_REQUEST, + "Malformed CDATA in element " + "\"limit\"", resource->pool); +- goto cleanup; + } + } + else if (strcmp(child->name, "discover-changed-paths") == 0) only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2013-1846_1847.patch +++ subversion-1.7.5/debian/patches/CVE-2013-1846_1847.patch @@ -0,0 +1,52 @@ +Description: fix denial of service via LOCK +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1462331 + +Index: subversion-1.7.5/subversion/mod_dav_svn/lock.c +=================================================================== +--- subversion-1.7.5.orig/subversion/mod_dav_svn/lock.c 2011-06-03 14:09:17.000000000 -0400 ++++ subversion-1.7.5/subversion/mod_dav_svn/lock.c 2013-06-21 13:05:59.530539614 -0400 +@@ -640,6 +640,19 @@ + svn_lock_t *slock; + svn_error_t *serr; + dav_error *derr; ++ dav_svn_repos *repos = resource->info->repos; ++ ++ /* We don't allow anonymous locks */ ++ if (! repos->username) ++ return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, ++ DAV_ERR_LOCK_SAVE_LOCK, ++ "Anonymous lock creation is not allowed."); ++ ++ /* Not a path in the repository so can't lock it. */ ++ if (! resource->info->repos_path) ++ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, ++ DAV_ERR_LOCK_SAVE_LOCK, ++ "Attempted to lock path not in repository."); + + /* If the resource's fs path is unreadable, we don't allow a lock to + be created on it. */ +@@ -663,7 +676,6 @@ + svn_fs_txn_t *txn; + svn_fs_root_t *txn_root; + const char *conflict_msg; +- dav_svn_repos *repos = resource->info->repos; + apr_hash_t *revprop_table = apr_hash_make(resource->pool); + apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, + APR_HASH_KEY_STRING, svn_string_create(repos->username, +@@ -741,14 +753,14 @@ + + /* Convert the dav_lock into an svn_lock_t. */ + derr = dav_lock_to_svn_lock(&slock, lock, resource->info->repos_path, +- info, resource->info->repos->is_svn_client, ++ info, repos->is_svn_client, + resource->pool); + if (derr) + return derr; + + /* Now use the svn_lock_t to actually perform the lock. */ + serr = svn_repos_fs_lock(&slock, +- resource->info->repos->repos, ++ repos->repos, + slock->path, + slock->token, + slock->comment, only in patch2: unchanged: --- subversion-1.7.5.orig/debian/patches/CVE-2015-0251.patch +++ subversion-1.7.5/debian/patches/CVE-2015-0251.patch @@ -0,0 +1,178 @@ +Note: the bulk of this file was taken unmodified from +http://subversion.apache.org/security/CVE-2015-0251-advisory.txt +but the 1.7.x patch had some filename tweaking so quilt can apply it +and the 1.8.x patch was removed to stop quilt trying to apply it. + + Subversion HTTP servers allow spoofing svn:author property values + for new revisions. + +Summary: +======== + + Subversion's mod_dav_svn server allows setting arbitrary svn:author + property values when committing new revisions. This can be accomplished + using a specially crafted sequence of requests. An evil-doer can fake + svn:author values on his commits. However, as authorization rules are + applied to the evil-doer's true username, forged svn:author values can + only happen on commits that touch the paths the evil-doer has write + access to. + + Doing so does not grant any additional access and does not circumvent the + standard Apache authentication or authorization mechanisms. Still, an + ability to spoof svn:author property values can impact data integrity in + environments that rely on these values. + + There are no known instances of the problem being exploited in the wild, + but an exploit has been tested. + +Known vulnerable: +================= + + Subversion HTTPD servers 1.5.0 through 1.7.19 (inclusive) + Subversion HTTPD servers 1.8.0 through 1.8.11 (inclusive) + +Known fixed: +============ + + Subversion 1.7.20 + Subversion 1.8.13 + svnserve (any version) is not vulnerable + + Subversion 1.8.12 was not publicly released. + +Details: +======== + + The Subversion http://-based protocol used for communicating with + a Subversion mod_dav_svn server has two versions, v1 and v2. The v2 + protocol was added in Subversion 1.7.0, but the server allows using both + protocol versions for compatibility reasons. When a commit happens, the + client sends a sequence of requests (POST, PUT, MERGE, etc.) that depend + on the negotiated protocol version. + + Usually, a server uses the name of the authenticated user as the svn:author + value for a new revision. However, with a specially handcrafted v1 request + sequence, a client can instruct the server to use the svn:author property + that she/he provided. In this case, the server will use an arbitrary value + coming from the client instead of the svn:author value originating from + the authentication mechanism. + +Severity: +========= + + CVSSv2 Base Score: 3.5 + CVSSv2 Base Vector: AV:N/AC:M/Au:S/C:N/I:P/A:N + + We consider this to be a medium risk vulnerability. + + An attacker needs to have commit access to the repository to exploit the + vulnerability. The ability to spoof svn:author property values can impact + data integrity in environments that expect the values to denote the actual + commit author. The real ID of the author could still be determined using + server access logs. However, it is also possible that a spoofed change + could go in unnoticed. + + Subversion's repository hooks might see the real ID of the author or the + forged value, depending on the hook type and the hook contents: + + - A start-commit hook will see the real username in the USER argument + - A start-commit hook will see the real username when performing + 'svnlook propget --revprop -t TXN_NAME' + - A pre-commit hook will see the forged username when performing + 'svnlook propget --revprop -t TXN_NAME' + - A post-commit hook will see the forged username when performing + 'svnlook propget --revprop -r REV' + + Unfortunately, no special configuration is required and all mod_dav_svn + servers are vulnerable. + +Recommendations: +================ + + We recommend all users to upgrade to Subversion 1.8.13. Users of + Subversion 1.7.x or 1.8.x who are unable to upgrade may apply the + included patch. + + New Subversion packages can be found at: + http://subversion.apache.org/packages.html + + No workaround is available. + +References: +=========== + + CVE-2015-0251 (Subversion) + +Reported by: +============ + + Ivan Zhakov, VisualSVN + +Patches: +======== + + Patch against 1.7.19: +[[[ +Index: x/subversion/mod_dav_svn/deadprops.c +=================================================================== +--- x/subversion/mod_dav_svn/deadprops.c (revision 1660122) ++++ x/subversion/mod_dav_svn/deadprops.c (working copy) +@@ -160,6 +160,23 @@ get_value(dav_db *db, const dav_prop_name *name, s + } + + ++static svn_error_t * ++change_txn_prop(svn_fs_txn_t *txn, ++ const char *propname, ++ const svn_string_t *value, ++ apr_pool_t *scratch_pool) ++{ ++ if (strcmp(propname, SVN_PROP_REVISION_AUTHOR) == 0) ++ return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, ++ "Attempted to modify 'svn:author' property " ++ "on a transaction"); ++ ++ SVN_ERR(svn_repos_fs_change_txn_prop(txn, propname, value, scratch_pool)); ++ ++ return SVN_NO_ERROR; ++} ++ ++ + static dav_error * + save_value(dav_db *db, const dav_prop_name *name, + const svn_string_t *const *old_value_p, +@@ -210,9 +227,8 @@ save_value(dav_db *db, const dav_prop_name *name, + { + if (db->resource->working) + { +- serr = svn_repos_fs_change_txn_prop(resource->info->root.txn, +- propname, value, +- subpool); ++ serr = change_txn_prop(resource->info->root.txn, propname, ++ value, subpool); + } + else + { +@@ -251,8 +267,8 @@ save_value(dav_db *db, const dav_prop_name *name, + } + else if (resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION) + { +- serr = svn_repos_fs_change_txn_prop(resource->info->root.txn, +- propname, value, subpool); ++ serr = change_txn_prop(resource->info->root.txn, propname, ++ value, subpool); + } + else + { +@@ -561,8 +577,8 @@ db_remove(dav_db *db, const dav_prop_name *name) + /* Working Baseline or Working (Version) Resource */ + if (db->resource->baselined) + if (db->resource->working) +- serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn, +- propname, NULL, subpool); ++ serr = change_txn_prop(db->resource->info->root.txn, propname, ++ NULL, subpool); + else + /* ### VIOLATING deltaV: you can't proppatch a baseline, it's + not a working resource! But this is how we currently +]]]