Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 255 additions & 0 deletions SPECS/subversion/CVE-2024-46901-advisory.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
mod_dav_svn denial-of-service via control characters in paths

Summary:
========

It has been discovered that the patch for CVE-2013-1968 was incomplete
and unintentionally left mod_dav_svn vulnerable to control characters
in filenames.

If a path or a revision-property which contains control characters is
committed to a repository then SVN operations served by mod_dav_svn
can be disrupted.

Known vulnerable:
=================

Subversion mod_dav_svn servers through 1.14.4 (inclusive).

Known fixed:
============

Servers running Subversion 1.14.5

Details:
========

If a path which contains control characters is committed to a repository
then SVN operations served by mod_dav_svn can be disrupted by encoding
errors raised from the XML library.

This leads to disruption for users accessing the repository via HTTP.
Affected repositories can be repaired (see "Recommendations" below).
However, restoring proper operation might take some time because a
full dump/load cycle may be required.

Local repositories and svnserve repository servers (accessed via a
file://, svn://, or svn+ssh:// URL) are not affected. In these cases,
control characters have been rejected since CVE-2013-1968 was patched
in Subversion 1.6.21 and Subversion 1.7.9.

Known symptoms of the problem include:

1) 'svn checkout', 'svnsync', and other operations that attempt to
read the affected revision may produce errors like:

svn: E175009: The XML response contains invalid XML
svn: E130003: Malformed XML: not well-formed (invalid token)

2) Attempts to browse affected files or directories via the web
interface will cause the server to return:

500 Internal Server Error

Apache Subversion clients have always rejected filenames with control
characters, so control characters cannot be introduced with stock
Subversion clients. They could, however, be triggered by custom
malicious Subversion clients or by third-party client implementations.

Servers updated to Subversion 1.14.5 will reject control characters in
all cases.

Severity:
=========

CVSSv3.1 Base Score: 3.1
CVSSv3.1 Base Vector: CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L

A remote authenticated attacker with commit access may be able to
corrupt repositories on a Subversion server and cause disruption for
other users.

Configurations that allow anonymous write access to the repository
will be vulnerable to this without authentication.

Recommendations:
================

We recommend all users to upgrade their servers to a known fixed
release of Subversion.

Users who are unable to upgrade may apply the patch included below.

New Subversion packages can be found at:
http://subversion.apache.org/packages.html

Repositories affected by this problem can be repaired manually:

Bad revision properties can be repaired by using svn propedit over
the file://, svn:// or svn+ssh:// protocols.

Bad paths which have entered a repository need to be removed from
history with a dump/load cycle, using svnadmin dump --exclude to
filter out the bad paths, and loading the result into a fresh
repository with svnadmin load.

References:
===========

CVE-2024-46901 (Subversion)
CVE-2013-1968 (Subversion)

XML Characters: https://www.w3.org/TR/xml/#charsets

Reported by:
============

HaoZi, WordPress China

Patches:
========

Patch against Subversion 1.14.4:

Link: https://subversion.apache.org/security/CVE-2024-46901-advisory.txt

[[[
Index: subversion/include/private/svn_repos_private.h
===================================================================
--- subversion/include/private/svn_repos_private.h (revision 1921550)
+++ subversion/include/private/svn_repos_private.h (working copy)
@@ -390,6 +390,14 @@ svn_repos__get_dump_editor(const svn_delta_editor_
const char *update_anchor_relpath,
apr_pool_t *pool);

+/* Validate that the given PATH is a valid pathname that can be stored in
+ * a Subversion repository, according to the name constraints used by the
+ * svn_repos_* layer.
+ */
+svn_error_t *
+svn_repos__validate_new_path(const char *path,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Index: subversion/libsvn_repos/commit.c
===================================================================
--- subversion/libsvn_repos/commit.c (revision 1921550)
+++ subversion/libsvn_repos/commit.c (working copy)
@@ -308,8 +308,7 @@ add_file_or_directory(const char *path,
svn_boolean_t was_copied = FALSE;
const char *full_path, *canonicalized_path;

- /* Reject paths which contain control characters (related to issue #4340). */
- SVN_ERR(svn_path_check_valid(path, pool));
+ SVN_ERR(svn_repos__validate_new_path(path, pool));

SVN_ERR(svn_relpath_canonicalize_safe(&canonicalized_path, NULL, path,
pool, pool));
Index: subversion/libsvn_repos/repos.c
===================================================================
--- subversion/libsvn_repos/repos.c (revision 1921550)
+++ subversion/libsvn_repos/repos.c (working copy)
@@ -2092,3 +2092,13 @@ svn_repos__fs_type(const char **fs_type,
svn_dirent_join(repos_path, SVN_REPOS__DB_DIR, pool),
pool);
}
+
+svn_error_t *
+svn_repos__validate_new_path(const char *path,
+ apr_pool_t *scratch_pool)
+{
+ /* Reject paths which contain control characters (related to issue #4340). */
+ SVN_ERR(svn_path_check_valid(path, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
Index: subversion/mod_dav_svn/lock.c
===================================================================
--- subversion/mod_dav_svn/lock.c (revision 1921550)
+++ subversion/mod_dav_svn/lock.c (working copy)
@@ -36,6 +36,7 @@
#include "svn_pools.h"
#include "svn_props.h"
#include "private/svn_log.h"
+#include "private/svn_repos_private.h"

#include "dav_svn.h"

@@ -717,6 +718,12 @@ append_locks(dav_lockdb *lockdb,

/* Commit a 0-byte file: */

+ if ((serr = svn_repos__validate_new_path(resource->info->repos_path,
+ resource->pool)))
+ return dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+ "Request specifies an invalid path.",
+ resource->pool);
+
if ((serr = dav_svn__get_youngest_rev(&rev, repos, resource->pool)))
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Could not determine youngest revision",
Index: subversion/mod_dav_svn/repos.c
===================================================================
--- subversion/mod_dav_svn/repos.c (revision 1921550)
+++ subversion/mod_dav_svn/repos.c (working copy)
@@ -2928,6 +2928,16 @@ open_stream(const dav_resource *resource,

if (kind == svn_node_none) /* No existing file. */
{
+ serr = svn_repos__validate_new_path(resource->info->repos_path,
+ resource->pool);
+
+ if (serr != NULL)
+ {
+ return dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+ "Request specifies an invalid path.",
+ resource->pool);
+ }
+
serr = svn_fs_make_file(resource->info->root.root,
resource->info->repos_path,
resource->pool);
@@ -4120,6 +4130,14 @@ create_collection(dav_resource *resource)
return err;
}

+ if ((serr = svn_repos__validate_new_path(resource->info->repos_path,
+ resource->pool)) != NULL)
+ {
+ return dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+ "Request specifies an invalid path.",
+ resource->pool);
+ }
+
if ((serr = svn_fs_make_dir(resource->info->root.root,
resource->info->repos_path,
resource->pool)) != NULL)
@@ -4194,6 +4212,12 @@ copy_resource(const dav_resource *src,
return err;
}

+ serr = svn_repos__validate_new_path(dst->info->repos_path, dst->pool);
+ if (serr)
+ return dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+ "Request specifies an invalid path.",
+ dst->pool);
+
src_repos_path = svn_repos_path(src->info->repos->repos, src->pool);
dst_repos_path = svn_repos_path(dst->info->repos->repos, dst->pool);

@@ -4430,6 +4454,12 @@ move_resource(dav_resource *src,
if (err)
return err;

+ serr = svn_repos__validate_new_path(dst->info->repos_path, dst->pool);
+ if (serr)
+ return dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+ "Request specifies an invalid path.",
+ dst->pool);
+
/* Copy the src to the dst. */
serr = svn_fs_copy(src->info->root.root, /* the root object of src rev*/
src->info->repos_path, /* the relative path of src */
]]]
8 changes: 6 additions & 2 deletions SPECS/subversion/subversion.spec
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
Summary: The Apache Subversion control system
Name: subversion
Version: 1.14.3
Release: 1%{?dist}
Release: 2%{?dist}
License: ASL 2.0
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: Utilities/System
URL: https://subversion.apache.org/
Source0: https://archive.apache.org/dist/%{name}/%{name}-%{version}.tar.bz2
Patch0: CVE-2024-46901-advisory.patch
BuildRequires: apr-devel
BuildRequires: apr-util
BuildRequires: apr-util-devel
Expand Down Expand Up @@ -48,7 +49,7 @@ Requires: %{name} = %{version}
Provides Perl (SWIG) support for Subversion version control system.

%prep
%autosetup -p1
%autosetup -p0

%build
export CFLAGS="%{build_cflags} -Wformat"
Expand Down Expand Up @@ -103,6 +104,9 @@ sudo -u test make check && userdel test -r -f
%{_mandir}/man3/SVN*

%changelog
* Fri Mar 07 2025 Kevin Lockwood <v-klockwood@microsoft.com> - 1.14.3-2
- Add patch for CVE-2024-46901

* Fri Feb 23 2024 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 1.14.3-1
- Auto-upgrade to 1.14.3 - Azure Linux 3.0 Upgrades

Expand Down
Loading