Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package subversion This uploaded backports fixes for 3 recent CVEs. $ debdiff subversion_1.8.10-5.dsc subversion_1.8.10-6.dsc diffstat for subversion_1.8.10-5 subversion_1.8.10-6 debian/patches/CVE-2015-0202 | 474 ++++++++++++++++++++++++++++++++ debian/patches/CVE-2015-0248 | 105 +++++++ debian/patches/CVE-2015-0251 | 62 ++++ subversion-1.8.10/debian/changelog | 11 subversion-1.8.10/debian/patches/series | 3 5 files changed, 655 insertions(+) diff -u subversion-1.8.10/debian/changelog subversion-1.8.10/debian/changelog --- subversion-1.8.10/debian/changelog +++ subversion-1.8.10/debian/changelog @@ -1,3 +1,14 @@ +subversion (1.8.10-6) unstable; urgency=high + + * patches/CVE-2015-0202: Excessive memory use with certain REPORT requests + against mod_dav_svn with FSFS repositories + * patches/CVE-2015-0248: Assertion DoS vulnerability for certain mod_dav_svn + and svnserve requests with dynamically evaluated revision numbers + * patches/CVE-2015-0251: mod_dav_svn allows spoofing svn:author property + values for new revisions + + -- James McCoy <james...@debian.org> Tue, 31 Mar 2015 22:51:18 -0400 + subversion (1.8.10-5) unstable; urgency=medium * patches/CVE-2014-8108: mod_dav_svn DoS vulnerability with invalid virtual diff -u subversion-1.8.10/debian/patches/series subversion-1.8.10/debian/patches/series --- subversion-1.8.10/debian/patches/series +++ subversion-1.8.10/debian/patches/series @@ -21,0 +22,3 @@ +CVE-2015-0251 +CVE-2015-0248 +CVE-2015-0202 only in patch2: unchanged: --- subversion-1.8.10.orig/debian/patches/CVE-2015-0202 +++ subversion-1.8.10/debian/patches/CVE-2015-0202 @@ -0,0 +1,474 @@ +Index: subversion/libsvn_fs_fs/tree.c +=================================================================== +--- a/subversion/libsvn_fs_fs/tree.c (revision 1655679) ++++ b/subversion/libsvn_fs_fs/tree.c (working copy) +@@ -127,7 +127,6 @@ typedef struct fs_txn_root_data_t + static svn_error_t * get_dag(dag_node_t **dag_node_p, + svn_fs_root_t *root, + const char *path, +- svn_boolean_t needs_lock_cache, + apr_pool_t *pool); + + static svn_fs_root_t *make_revision_root(svn_fs_t *fs, svn_revnum_t rev, +@@ -178,34 +177,10 @@ typedef struct cache_entry_t + */ + enum { BUCKET_COUNT = 256 }; + +-/* Each pool that has received a DAG node, will hold at least on lock on +- our cache to ensure that the node remains valid despite being allocated +- in the cache's pool. This is the structure to represent the lock. +- */ +-typedef struct cache_lock_t +-{ +- /* pool holding the lock */ +- apr_pool_t *pool; +- +- /* cache being locked */ +- fs_fs_dag_cache_t *cache; +- +- /* next lock. NULL at EOL */ +- struct cache_lock_t *next; +- +- /* previous lock. NULL at list head. Only then this==cache->first_lock */ +- struct cache_lock_t *prev; +-} cache_lock_t; +- + /* The actual cache structure. All nodes will be allocated in POOL. + When the number of INSERTIONS (i.e. objects created form that pool) + exceeds a certain threshold, the pool will be cleared and the cache + with it. +- +- To ensure that nodes returned from this structure remain valid, the +- cache will get locked for the lifetime of the _receiving_ pools (i.e. +- those in which we would allocate the node if there was no cache.). +- The cache will only be cleared FIRST_LOCK is 0. + */ + struct fs_fs_dag_cache_t + { +@@ -221,47 +196,8 @@ struct fs_fs_dag_cache_t + /* Property lookups etc. have a very high locality (75% re-hit). + Thus, remember the last hit location for optimistic lookup. */ + apr_size_t last_hit; +- +- /* List of receiving pools that are still alive. */ +- cache_lock_t *first_lock; + }; + +-/* Cleanup function to be called when a receiving pool gets cleared. +- Unlocks the cache once. +- */ +-static apr_status_t +-unlock_cache(void *baton_void) +-{ +- cache_lock_t *lock = baton_void; +- +- /* remove lock from chain. Update the head */ +- if (lock->next) +- lock->next->prev = lock->prev; +- if (lock->prev) +- lock->prev->next = lock->next; +- else +- lock->cache->first_lock = lock->next; +- +- return APR_SUCCESS; +-} +- +-/* Cleanup function to be called when the cache itself gets destroyed. +- In that case, we must unregister all unlock requests. +- */ +-static apr_status_t +-unregister_locks(void *baton_void) +-{ +- fs_fs_dag_cache_t *cache = baton_void; +- cache_lock_t *lock; +- +- for (lock = cache->first_lock; lock; lock = lock->next) +- apr_pool_cleanup_kill(lock->pool, +- lock, +- unlock_cache); +- +- return APR_SUCCESS; +-} +- + fs_fs_dag_cache_t* + svn_fs_fs__create_dag_cache(apr_pool_t *pool) + { +@@ -268,59 +204,15 @@ svn_fs_fs__create_dag_cache(apr_pool_t *pool) + fs_fs_dag_cache_t *result = apr_pcalloc(pool, sizeof(*result)); + result->pool = svn_pool_create(pool); + +- apr_pool_cleanup_register(pool, +- result, +- unregister_locks, +- apr_pool_cleanup_null); +- + return result; + } + +-/* Prevent the entries in CACHE from being destroyed, for as long as the +- POOL lives. +- */ +-static void +-lock_cache(fs_fs_dag_cache_t* cache, apr_pool_t *pool) +-{ +- /* we only need to lock / unlock once per pool. Since we will often ask +- for multiple nodes with the same pool, we can reduce the overhead. +- However, if e.g. pools are being used in an alternating pattern, +- we may lock the cache more than once for the same pool (and register +- just as many cleanup actions). +- */ +- cache_lock_t *lock = cache->first_lock; +- +- /* try to find an existing lock for POOL. +- But limit the time spent on chasing pointers. */ +- int limiter = 8; +- while (lock && --limiter) +- if (lock->pool == pool) +- return; +- +- /* create a new lock and put it at the beginning of the lock chain */ +- lock = apr_palloc(pool, sizeof(*lock)); +- lock->cache = cache; +- lock->pool = pool; +- lock->next = cache->first_lock; +- lock->prev = NULL; +- +- if (cache->first_lock) +- cache->first_lock->prev = lock; +- cache->first_lock = lock; +- +- /* instruct POOL to remove the look upon cleanup */ +- apr_pool_cleanup_register(pool, +- lock, +- unlock_cache, +- apr_pool_cleanup_null); +-} +- + /* Clears the CACHE at regular intervals (destroying all cached nodes) + */ + static void + auto_clear_dag_cache(fs_fs_dag_cache_t* cache) + { +- if (cache->first_lock == NULL && cache->insertions > BUCKET_COUNT) ++ if (cache->insertions > BUCKET_COUNT) + { + svn_pool_clear(cache->pool); + +@@ -433,18 +325,12 @@ locate_cache(svn_cache__t **cache, + } + } + +-/* Return NODE for PATH from ROOT's node cache, or NULL if the node +- isn't cached; read it from the FS. *NODE remains valid until either +- POOL or the FS gets cleared or destroyed (whichever comes first). +- +- Since locking can be expensive and POOL may be long-living, for +- nodes that will not need to survive the next call to this function, +- set NEEDS_LOCK_CACHE to FALSE. */ ++/* Return NODE_P for PATH from ROOT's node cache, or NULL if the node ++ isn't cached; read it from the FS. *NODE_P is allocated in POOL. */ + static svn_error_t * + dag_node_cache_get(dag_node_t **node_p, + svn_fs_root_t *root, + const char *path, +- svn_boolean_t needs_lock_cache, + apr_pool_t *pool) + { + svn_boolean_t found; +@@ -466,25 +352,23 @@ dag_node_cache_get(dag_node_t **node_p, + if (bucket->node == NULL) + { + locate_cache(&cache, &key, root, path, pool); +- SVN_ERR(svn_cache__get((void **)&node, &found, cache, key, +- ffd->dag_node_cache->pool)); ++ SVN_ERR(svn_cache__get((void **)&node, &found, cache, key, pool)); + if (found && node) + { + /* Patch up the FS, since this might have come from an old FS + * object. */ + svn_fs_fs__dag_set_fs(node, root->fs); +- bucket->node = node; ++ ++ /* Retain the DAG node in L1 cache. */ ++ bucket->node = svn_fs_fs__dag_dup(node, ++ ffd->dag_node_cache->pool); + } + } + else + { +- node = bucket->node; ++ /* Copy the node from L1 cache into the passed-in POOL. */ ++ node = svn_fs_fs__dag_dup(bucket->node, pool); + } +- +- /* if we found a node, make sure it remains valid at least as long +- as it would when allocated in POOL. */ +- if (node && needs_lock_cache) +- lock_cache(ffd->dag_node_cache, pool); + } + else + { +@@ -822,7 +706,7 @@ get_copy_inheritance(copy_id_inherit_t *inherit_p, + SVN_ERR(svn_fs_fs__dag_get_copyroot(©root_rev, ©root_path, + child->node)); + SVN_ERR(svn_fs_fs__revision_root(©root_root, fs, copyroot_rev, pool)); +- SVN_ERR(get_dag(©root_node, copyroot_root, copyroot_path, FALSE, pool)); ++ SVN_ERR(get_dag(©root_node, copyroot_root, copyroot_path, pool)); + copyroot_id = svn_fs_fs__dag_get_id(copyroot_node); + + if (svn_fs_fs__id_compare(copyroot_id, child_id) == -1) +@@ -938,7 +822,7 @@ open_path(parent_path_t **parent_path_p, + { + directory = svn_dirent_dirname(path, pool); + if (directory[1] != 0) /* root nodes are covered anyway */ +- SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool)); ++ SVN_ERR(dag_node_cache_get(&here, root, directory, pool)); + } + + /* did the shortcut work? */ +@@ -998,8 +882,8 @@ open_path(parent_path_t **parent_path_p, + element if we already know the lookup to fail for the + complete path. */ + if (next || !(flags & open_path_uncached)) +- SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far, +- TRUE, pool)); ++ SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far, pool)); ++ + if (cached_node) + child = cached_node; + else +@@ -1136,8 +1020,7 @@ make_path_mutable(svn_fs_root_t *root, + parent_path->node)); + SVN_ERR(svn_fs_fs__revision_root(©root_root, root->fs, + copyroot_rev, pool)); +- SVN_ERR(get_dag(©root_node, copyroot_root, copyroot_path, +- FALSE, pool)); ++ SVN_ERR(get_dag(©root_node, copyroot_root, copyroot_path, pool)); + + child_id = svn_fs_fs__dag_get_id(parent_path->node); + copyroot_id = svn_fs_fs__dag_get_id(copyroot_node); +@@ -1174,16 +1057,11 @@ make_path_mutable(svn_fs_root_t *root, + + /* Open the node identified by PATH in ROOT. Set DAG_NODE_P to the + node we find, allocated in POOL. Return the error +- SVN_ERR_FS_NOT_FOUND if this node doesn't exist. +- +- Since locking can be expensive and POOL may be long-living, for +- nodes that will not need to survive the next call to this function, +- set NEEDS_LOCK_CACHE to FALSE. */ ++ SVN_ERR_FS_NOT_FOUND if this node doesn't exist. */ + static svn_error_t * + get_dag(dag_node_t **dag_node_p, + svn_fs_root_t *root, + const char *path, +- svn_boolean_t needs_lock_cache, + apr_pool_t *pool) + { + parent_path_t *parent_path; +@@ -1192,7 +1070,7 @@ get_dag(dag_node_t **dag_node_p, + /* First we look for the DAG in our cache + (if the path may be canonical). */ + if (*path == '/') +- SVN_ERR(dag_node_cache_get(&node, root, path, needs_lock_cache, pool)); ++ SVN_ERR(dag_node_cache_get(&node, root, path, pool)); + + if (! node) + { +@@ -1202,8 +1080,7 @@ get_dag(dag_node_t **dag_node_p, + path = svn_fs__canonicalize_abspath(path, pool); + + /* Try again with the corrected path. */ +- SVN_ERR(dag_node_cache_get(&node, root, path, needs_lock_cache, +- pool)); ++ SVN_ERR(dag_node_cache_get(&node, root, path, pool)); + } + + if (! node) +@@ -1281,7 +1158,7 @@ svn_fs_fs__node_id(const svn_fs_id_t **id_p, + { + dag_node_t *node; + +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + *id_p = svn_fs_fs__id_copy(svn_fs_fs__dag_get_id(node), pool); + } + return SVN_NO_ERROR; +@@ -1296,7 +1173,7 @@ svn_fs_fs__node_created_rev(svn_revnum_t *revision + { + dag_node_t *node; + +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + return svn_fs_fs__dag_get_revision(revision, node, pool); + } + +@@ -1311,7 +1188,7 @@ fs_node_created_path(const char **created_path, + { + dag_node_t *node; + +- SVN_ERR(get_dag(&node, root, path, TRUE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + *created_path = svn_fs_fs__dag_get_created_path(node); + + return SVN_NO_ERROR; +@@ -1375,7 +1252,7 @@ fs_node_prop(svn_string_t **value_p, + dag_node_t *node; + apr_hash_t *proplist; + +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + SVN_ERR(svn_fs_fs__dag_get_proplist(&proplist, node, pool)); + *value_p = NULL; + if (proplist) +@@ -1398,7 +1275,7 @@ fs_node_proplist(apr_hash_t **table_p, + apr_hash_t *table; + dag_node_t *node; + +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + SVN_ERR(svn_fs_fs__dag_get_proplist(&table, node, pool)); + *table_p = table ? table : apr_hash_make(pool); + +@@ -1515,8 +1392,8 @@ fs_props_changed(svn_boolean_t *changed_p, + (SVN_ERR_FS_GENERAL, NULL, + _("Cannot compare property value between two different filesystems")); + +- SVN_ERR(get_dag(&node1, root1, path1, TRUE, pool)); +- SVN_ERR(get_dag(&node2, root2, path2, TRUE, pool)); ++ SVN_ERR(get_dag(&node1, root1, path1, pool)); ++ SVN_ERR(get_dag(&node2, root2, path2, pool)); + return svn_fs_fs__dag_things_different(changed_p, NULL, + node1, node2); + } +@@ -1529,7 +1406,7 @@ fs_props_changed(svn_boolean_t *changed_p, + static svn_error_t * + get_root(dag_node_t **node, svn_fs_root_t *root, apr_pool_t *pool) + { +- return get_dag(node, root, "/", TRUE, pool); ++ return get_dag(node, root, "/", pool); + } + + +@@ -2193,7 +2070,7 @@ fs_dir_entries(apr_hash_t **table_p, + dag_node_t *node; + + /* Get the entries for this path in the caller's pool. */ +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + return svn_fs_fs__dag_dir_entries(table_p, node, pool); + } + +@@ -2365,7 +2242,7 @@ copy_helper(svn_fs_root_t *from_root, + _("Copy from mutable tree not currently supported")); + + /* Get the NODE for FROM_PATH in FROM_ROOT.*/ +- SVN_ERR(get_dag(&from_node, from_root, from_path, TRUE, pool)); ++ SVN_ERR(get_dag(&from_node, from_root, from_path, pool)); + + /* Build up the parent path from TO_PATH in TO_ROOT. If the last + component does not exist, it's not that big a deal. We'll just +@@ -2442,7 +2319,7 @@ copy_helper(svn_fs_root_t *from_root, + pool)); + + /* Make a record of this modification in the changes table. */ +- SVN_ERR(get_dag(&new_node, to_root, to_path, TRUE, pool)); ++ SVN_ERR(get_dag(&new_node, to_root, to_path, pool)); + SVN_ERR(add_change(to_root->fs, txn_id, to_path, + svn_fs_fs__dag_get_id(new_node), kind, FALSE, FALSE, + svn_fs_fs__dag_node_kind(from_node), +@@ -2553,7 +2430,7 @@ fs_copied_from(svn_revnum_t *rev_p, + { + /* There is no cached entry, look it up the old-fashioned + way. */ +- SVN_ERR(get_dag(&node, root, path, TRUE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + SVN_ERR(svn_fs_fs__dag_get_copyfrom_rev(©from_rev, node)); + SVN_ERR(svn_fs_fs__dag_get_copyfrom_path(©from_path, node)); + } +@@ -2628,7 +2505,7 @@ fs_file_length(svn_filesize_t *length_p, + dag_node_t *file; + + /* First create a dag_node_t from the root/path pair. */ +- SVN_ERR(get_dag(&file, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&file, root, path, pool)); + + /* Now fetch its length */ + return svn_fs_fs__dag_file_length(length_p, file, pool); +@@ -2647,7 +2524,7 @@ fs_file_checksum(svn_checksum_t **checksum, + { + dag_node_t *file; + +- SVN_ERR(get_dag(&file, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&file, root, path, pool)); + return svn_fs_fs__dag_file_checksum(checksum, file, kind, pool); + } + +@@ -2666,7 +2543,7 @@ fs_file_contents(svn_stream_t **contents, + svn_stream_t *file_stream; + + /* First create a dag_node_t from the root/path pair. */ +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + + /* Then create a readable stream from the dag_node_t. */ + SVN_ERR(svn_fs_fs__dag_get_contents(&file_stream, node, pool)); +@@ -2689,7 +2566,7 @@ fs_try_process_file_contents(svn_boolean_t *succes + apr_pool_t *pool) + { + dag_node_t *node; +- SVN_ERR(get_dag(&node, root, path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, root, path, pool)); + + return svn_fs_fs__dag_try_process_file_contents(success, node, + processor, baton, pool); +@@ -3071,8 +2948,8 @@ fs_contents_changed(svn_boolean_t *changed_p, + (SVN_ERR_FS_GENERAL, NULL, _("'%s' is not a file"), path2); + } + +- SVN_ERR(get_dag(&node1, root1, path1, TRUE, pool)); +- SVN_ERR(get_dag(&node2, root2, path2, TRUE, pool)); ++ SVN_ERR(get_dag(&node1, root1, path1, pool)); ++ SVN_ERR(get_dag(&node2, root2, path2, pool)); + return svn_fs_fs__dag_things_different(NULL, changed_p, + node1, node2); + } +@@ -3092,10 +2969,10 @@ fs_get_file_delta_stream(svn_txdelta_stream_t **st + dag_node_t *source_node, *target_node; + + if (source_root && source_path) +- SVN_ERR(get_dag(&source_node, source_root, source_path, TRUE, pool)); ++ SVN_ERR(get_dag(&source_node, source_root, source_path, pool)); + else + source_node = NULL; +- SVN_ERR(get_dag(&target_node, target_root, target_path, TRUE, pool)); ++ SVN_ERR(get_dag(&target_node, target_root, target_path, pool)); + + /* Create a delta stream that turns the source into the target. */ + return svn_fs_fs__dag_get_file_delta_stream(stream_p, source_node, +@@ -3588,7 +3465,7 @@ history_prev(void *baton, apr_pool_t *pool) + + SVN_ERR(svn_fs_fs__revision_root(©root_root, fs, copyroot_rev, + pool)); +- SVN_ERR(get_dag(&node, copyroot_root, copyroot_path, FALSE, pool)); ++ SVN_ERR(get_dag(&node, copyroot_root, copyroot_path, pool)); + copy_dst = svn_fs_fs__dag_get_created_path(node); + + /* If our current path was the very destination of the copy, +@@ -3785,7 +3662,7 @@ crawl_directory_dag_for_mergeinfo(svn_fs_root_t *r + svn_pool_clear(iterpool); + + kid_path = svn_fspath__join(this_path, dirent->name, iterpool); +- SVN_ERR(get_dag(&kid_dag, root, kid_path, TRUE, iterpool)); ++ SVN_ERR(get_dag(&kid_dag, root, kid_path, iterpool)); + + SVN_ERR(svn_fs_fs__dag_has_mergeinfo(&has_mergeinfo, kid_dag)); + SVN_ERR(svn_fs_fs__dag_has_descendants_with_mergeinfo(&go_down, kid_dag)); +@@ -4031,7 +3908,7 @@ add_descendant_mergeinfo(svn_mergeinfo_catalog_t r + dag_node_t *this_dag; + svn_boolean_t go_down; + +- SVN_ERR(get_dag(&this_dag, root, path, TRUE, scratch_pool)); ++ SVN_ERR(get_dag(&this_dag, root, path, scratch_pool)); + SVN_ERR(svn_fs_fs__dag_has_descendants_with_mergeinfo(&go_down, + this_dag)); + if (go_down) only in patch2: unchanged: --- subversion-1.8.10.orig/debian/patches/CVE-2015-0248 +++ subversion-1.8.10/debian/patches/CVE-2015-0248 @@ -0,0 +1,105 @@ +--- a/subversion/mod_dav_svn/reports/get-location-segments.c ++++ b/subversion/mod_dav_svn/reports/get-location-segments.c +@@ -181,17 +181,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 +@@ -2465,9 +2465,30 @@ + + 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 " +@@ -2475,9 +2496,7 @@ + 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 " +@@ -2485,12 +2504,6 @@ + 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.8.10.orig/debian/patches/CVE-2015-0251 +++ subversion-1.8.10/debian/patches/CVE-2015-0251 @@ -0,0 +1,62 @@ +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) +@@ -163,6 +163,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, +@@ -213,9 +230,8 @@ save_value(dav_db *db, const dav_prop_name *name, + { + if (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 + { +@@ -254,8 +270,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 + { +@@ -560,8 +576,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 unblock subversion/1.8.10-6 -- System Information: Debian Release: 8.0 APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org