On Tue, Apr 21, 2015 at 12:35:18AM -0400, James McCoy wrote: > wheezy-security upload happened today and, as expected, the patches > apply pretty cleanly to the Squeeze version. I synced all the relevant > CVE fixes from the wheezy package back to the squeeze package. > > I'm still going through build and test, but I should have something > ready in the next day or two.
Debdiff attached. Can someone handle the upload and DLA announcement? Cheers, -- James GPG Key: 4096R/331BA3DB 2011-12-05 James McCoy <james...@debian.org>
diffstat for subversion_1.6.12dfsg-7+deb6u1 subversion_1.6.12dfsg-7+deb6u2 debian/patches/CVE-2014-0032 | 33 ++++ debian/patches/CVE-2015-0248 | 99 ++++++++++++++ debian/patches/CVE-2015-0251 | 50 +++++++ debian/patches/cve-2013-1845 | 189 ++++++++++++++++++++++++++++ debian/patches/cve-2013-1846 | 66 +++++++++ debian/patches/cve-2013-1849 | 39 +++++ subversion-1.6.12dfsg/debian/changelog | 17 ++ subversion-1.6.12dfsg/debian/patches/series | 6 8 files changed, 499 insertions(+) diff -u subversion-1.6.12dfsg/debian/changelog subversion-1.6.12dfsg/debian/changelog --- subversion-1.6.12dfsg/debian/changelog +++ subversion-1.6.12dfsg/debian/changelog @@ -1,3 +1,20 @@ +subversion (1.6.12dfsg-7+deb6u2) squeeze-lts; urgency=high + + * Add patches for following CVEs + - CVE-2013-1845: Remotely triggered memory exhaustion in mod_dav_svn + (Closes: #704940) + - CVE-2013-1846: Remotely triggered crash in mod_dav_svn + - CVE-2013-1847: Remotely triggered crash in mod_dav_svn + - CVE-2013-1849: Remotely triggered crash in mod_dav_svn + - CVE-2014-0032: mod_dav_svn crash when handling certain requests with + SVNListParentPath on (Closes: #737815) + - CVE-2015-0248: Assertion DoS vulnerability for certain mod_dav_svn and + svnserve requests with dynamically evaluated revision numbers + - CVE-2015-0251: mod_dav_svn allows spoofing svn:author property values + for new revisions + + -- James McCoy <james...@debian.org> Mon, 20 Apr 2015 22:19:47 -0400 + subversion (1.6.12dfsg-7+deb6u1) squeeze-lts; urgency=medium * Non-maintainer upload by the Squeeze LTS Team. diff -u subversion-1.6.12dfsg/debian/patches/series subversion-1.6.12dfsg/debian/patches/series --- subversion-1.6.12dfsg/debian/patches/series +++ subversion-1.6.12dfsg/debian/patches/series @@ -35,0 +36,6 @@ +cve-2013-1845 +cve-2013-1846 +cve-2013-1849 +CVE-2014-0032 +CVE-2015-0248 +CVE-2015-0251 only in patch2: unchanged: --- subversion-1.6.12dfsg.orig/debian/patches/cve-2013-1849 +++ subversion-1.6.12dfsg/debian/patches/cve-2013-1849 @@ -0,0 +1,39 @@ +Author: Philip Martin <philip.mar...@wandisco.com> +Subject: Reject operations on prop if the resource is an activity + +Subversion's mod_dav_svn Apache HTTPD server module will crash when +a PROPFIND request is made against activity URLs. The patch consists +in rejecting operations on getcontentlength and getcontenttype +properties if the resource is an activity. + +Origin: upstream, commit:r1453780 +Bug-CVE: http://subversion.apache.org/security/CVE-2013-1849-advisory.txt +Bug-Debian: http://bugs.debian.org/704940 +Last-Update: 2013-04-16 +Applied-Upstream: commit:r1453780 + +Index: subversion/mod_dav_svn/liveprops.c +=================================================================== +--- a/subversion/mod_dav_svn/liveprops.c (revision 1458455) ++++ b/subversion/mod_dav_svn/liveprops.c (working copy) +@@ -410,7 +410,8 @@ insert_prop_internal(const dav_resource *resource, + 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, +@@ -434,7 +435,9 @@ insert_prop_internal(const dav_resource *resource, + 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.6.12dfsg.orig/debian/patches/CVE-2015-0248 +++ subversion-1.6.12dfsg/debian/patches/CVE-2015-0248 @@ -0,0 +1,99 @@ +--- a/subversion/mod_dav_svn/reports/get-location-segments.c ++++ b/subversion/mod_dav_svn/reports/get-location-segments.c +@@ -167,17 +167,36 @@ + "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", +--- a/subversion/svnserve/serve.c ++++ b/subversion/svnserve/serve.c +@@ -2136,26 +2136,39 @@ + + abs_path = svn_path_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) + return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, + "Get-location-segments end revision must not be " + "younger than start revision"); + +- if (SVN_IS_VALID_REVNUM(peg_revision) +- && SVN_IS_VALID_REVNUM(start_rev) +- && (start_rev > peg_revision)) ++ if (start_rev > peg_revision) + return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, + "Get-location-segments start revision must not " + "be younger than peg revision"); + +- 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.6.12dfsg.orig/debian/patches/CVE-2015-0251 +++ subversion-1.6.12dfsg/debian/patches/CVE-2015-0251 @@ -0,0 +1,50 @@ +Index: subversion/mod_dav_svn/deadprops.c +=================================================================== +--- a/subversion/mod_dav_svn/deadprops.c (revision 1660122) ++++ b/subversion/mod_dav_svn/deadprops.c (working copy) +@@ -128,6 +128,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 *value) + { +@@ -157,8 +157,8 @@ save_value(dav_db *db, const dav_prop_name *name, + subpool = svn_pool_create(db->resource->pool); + if (db->resource->baselined) + if (db->resource->working) +- serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn, +- propname, value, subpool); ++ serr = change_txn_prop(db->resource->info->root.txn, propname, ++ value, subpool); + else + { + /* ### VIOLATING deltaV: you can't proppatch a baseline, it's +@@ -425,8 +425,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, db->resource->pool); ++ 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 only in patch2: unchanged: --- subversion-1.6.12dfsg.orig/debian/patches/CVE-2014-0032 +++ subversion-1.6.12dfsg/debian/patches/CVE-2014-0032 @@ -0,0 +1,33 @@ +Author: Ben Reser <bre...@apache.org> +Subject: 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. + +Origin: upstream, backported from commit:r1557320 +Bug-CVE: http://subversion.apache.org/security/CVE-2014-0032-advisory.txt +Bug-Debian: http://bugs.debian.org/737815 +Last-Update: 2014-02-26 + +--- a/subversion/mod_dav_svn/repos.c ++++ b/subversion/mod_dav_svn/repos.c +@@ -1655,6 +1655,19 @@ + + if (strcmp(parentpath, uri) == 0) + { ++ /* 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) ++ { ++ /* can't use r->allowed since the default handler isn't called */ ++ apr_table_setn(r->headers_out, "Allow", "GET,HEAD"); ++ ++ return dav_new_error(r->pool, HTTP_METHOD_NOT_ALLOWED, ++ SVN_ERR_APMOD_MALFORMED_URI, ++ "The URI does not contain the name " ++ "of a repository."); ++ } ++ + err = get_parentpath_resource(r, root_path, resource); + if (err) + return err; only in patch2: unchanged: --- subversion-1.6.12dfsg.orig/debian/patches/cve-2013-1845 +++ subversion-1.6.12dfsg/debian/patches/cve-2013-1845 @@ -0,0 +1,189 @@ +Author: Philip Martin <philip.mar...@wandisco.com> +Subject: Introduce a subpool to control memory use + +Setting or deleting a large number of properties on a node (file or +directory) will result in a large amount of memory use. Due to the +memory pooling behavior of Apache httpd and Subversion the completion of +the request will not result in the immediate release of memory used. +Repeated commits with the same properties will result in each httpd process +plateauing out at some amount of memory. This could result in a Denial of +Service if the system is exhausted of all available memory. + +Origin: upstream, commit:r1443929 +Bug-CVE: http://subversion.apache.org/security/CVE-2013-1845-advisory.txt +Bug-Debian: http://bugs.debian.org/704940 +Last-Update: 2013-04-16 +Applied-Upstream: commit:r1443929 + + +Index: subversion/mod_dav_svn/dav_svn.h +=================================================================== +--- a/subversion/mod_dav_svn/dav_svn.h (revision 1461956) ++++ b/subversion/mod_dav_svn/dav_svn.h (working copy) +@@ -254,6 +254,9 @@ struct dav_resource_private { + interface (ie: /path/to/item?p=PEGREV]? */ + svn_boolean_t pegged; + ++ /* Cache any revprop change error */ ++ svn_error_t *revprop_error; ++ + /* Pool to allocate temporary data from */ + apr_pool_t *pool; + }; +Index: subversion/mod_dav_svn/deadprops.c +=================================================================== +--- a/subversion/mod_dav_svn/deadprops.c (revision 1461956) ++++ b/subversion/mod_dav_svn/deadprops.c (working copy) +@@ -49,8 +49,7 @@ struct dav_db { + + + struct dav_deadprop_rollback { +- dav_prop_name name; +- svn_string_t value; ++ int dummy; + }; + + +@@ -134,6 +133,7 @@ save_value(dav_db *db, const dav_prop_name *name, + { + const char *propname; + svn_error_t *serr; ++ apr_pool_t *subpool; + + /* get the repos-local name */ + get_repos_propname(db, name, &propname); +@@ -151,10 +151,14 @@ save_value(dav_db *db, const dav_prop_name *name, + } + + /* Working Baseline or Working (Version) Resource */ ++ ++ /* 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(db->resource->info->root.txn, +- propname, value, db->resource->pool); ++ propname, value, subpool); + else + { + /* ### VIOLATING deltaV: you can't proppatch a baseline, it's +@@ -168,19 +172,29 @@ save_value(dav_db *db, const dav_prop_name *name, + propname, value, TRUE, TRUE, + db->authz_read_func, + db->authz_read_baton, +- db->resource->pool); ++ subpool); + ++ /* mod_dav doesn't handle the returned error very well, it ++ generates its own generic error that will be returned to ++ the client. Cache the detailed error here so that it can ++ be returned a second time when the rollback mechanism ++ triggers. */ ++ if (serr) ++ db->resource->info->revprop_error = svn_error_dup(serr); ++ + /* Tell the logging subsystem about the revprop change. */ + dav_svn__operational_log(db->resource->info, + svn_log__change_rev_prop( + db->resource->info->root.rev, + propname, +- db->resource->pool)); ++ subpool)); + } + else + serr = svn_repos_fs_change_node_prop(db->resource->info->root.root, + get_repos_path(db->resource->info), +- propname, value, db->resource->pool); ++ propname, value, subpool); ++ svn_pool_destroy(subpool); ++ + if (serr != NULL) + return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, + NULL, +@@ -395,6 +409,7 @@ db_remove(dav_db *db, const dav_prop_name *name) + { + svn_error_t *serr; + const char *propname; ++ apr_pool_t *subpool; + + /* get the repos-local name */ + get_repos_propname(db, name, &propname); +@@ -403,6 +418,10 @@ db_remove(dav_db *db, const dav_prop_name *name) + 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) +@@ -419,11 +438,12 @@ db_remove(dav_db *db, const dav_prop_name *name) + propname, 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", +@@ -598,19 +618,14 @@ db_get_rollback(dav_db *db, + const dav_prop_name *name, + dav_deadprop_rollback **prollback) + { +- dav_error *err; +- dav_deadprop_rollback *ddp; +- svn_string_t *propval; ++ /* This gets called by mod_dav in preparation for a revprop change. ++ mod_dav_svn doesn't need to make any changes during rollback, but ++ we want the rollback mechanism to trigger. Making changes in ++ response to post-revprop-change hook errors would be positively ++ wrong. */ + +- if ((err = get_value(db, name, &propval)) != NULL) +- return err; ++ *prollback = apr_palloc(db->p, sizeof(dav_deadprop_rollback)); + +- ddp = apr_palloc(db->p, sizeof(*ddp)); +- ddp->name = *name; +- ddp->value.data = propval ? propval->data : NULL; +- ddp->value.len = propval ? propval->len : 0; +- +- *prollback = ddp; + return NULL; + } + +@@ -618,12 +633,20 @@ db_get_rollback(dav_db *db, + static dav_error * + db_apply_rollback(dav_db *db, dav_deadprop_rollback *rollback) + { +- if (rollback->value.data == NULL) +- { +- return db_remove(db, &rollback->name); +- } ++ dav_error *derr; + +- return save_value(db, &rollback->name, &rollback->value); ++ if (! db->resource->info->revprop_error) ++ return NULL; ++ ++ /* Returning the original revprop change error here will cause this ++ detailed error to get returned to the client in preference to the ++ more generic error created by mod_dav. */ ++ derr = dav_svn__convert_err(db->resource->info->revprop_error, ++ HTTP_INTERNAL_SERVER_ERROR, NULL, ++ db->resource->pool); ++ db->resource->info->revprop_error = NULL; ++ ++ return derr; + } + + only in patch2: unchanged: --- subversion-1.6.12dfsg.orig/debian/patches/cve-2013-1846 +++ subversion-1.6.12dfsg/debian/patches/cve-2013-1846 @@ -0,0 +1,66 @@ +Author: Ben Reser <bre...@tigris.org> +Subject: Improve the logic in mod_dav_svn's implementation of LOCK + +Subversion's mod_dav_svn Apache HTTPD server module will crash in some +circumstances when a LOCK request is made against activity URL or +non-existent URL. The vulnerability can be triggered by doing a LOCK +request against an activity URL. +The vulnerability can also be triggered by doing a LOCK request against +a URL for a path that does not exist in the repository or an invalid +activity URL where authentication is not required for the LOCK +method. + +Origin: upstream, commit:r1455352 +Bug-CVE: http://subversion.apache.org/security/CVE-2013-1846-advisory.txt +Bug-CVE: http://subversion.apache.org/security/CVE-2013-1847-advisory.txt +Bug-Debian: http://bugs.debian.org/704940 +Last-Update: 2013-04-16 +Applied-Upstream: commit:r1455352 + +--- a/subversion/mod_dav_svn/lock.c ++++ b/subversion/mod_dav_svn/lock.c +@@ -631,6 +631,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_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_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. */ +@@ -653,7 +666,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, +@@ -717,14 +729,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,
signature.asc
Description: Digital signature