Bug 923794 (CVE-2015-0248) - VUL-0: CVE-2015-0248: subversion: mod_dav_svn and svnserve remotely triggerable assertion DoS vulnerability for certain requests with dynamically evaluated revision numbers
Summary: VUL-0: CVE-2015-0248: subversion: mod_dav_svn and svnserve remotely triggerab...
Status: RESOLVED FIXED
Alias: CVE-2015-0248
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents (show other bugs)
Version: unspecified
Hardware: Other Other
: P3 - Medium : Major
Target Milestone: ---
Deadline: 2015-04-07
Assignee: Security Team bot
QA Contact: Security Team bot
URL:
Whiteboard: maint:released:sle11-sp2:61401 maint:...
Keywords:
Depends on:
Blocks:
 
Reported: 2015-03-23 16:09 UTC by Andreas Stieger
Modified: 2017-08-17 14:39 UTC (History)
2 users (show)

See Also:
Found By: Security Response Team
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Comment 3 Swamp Workflow Management 2015-03-23 23:00:43 UTC
bugbot adjusting priority
Comment 4 Swamp Workflow Management 2015-03-24 08:43:18 UTC
An update workflow for this issue was started.
This issue was rated as moderate.
Please submit fixed packages until 2015-04-07.
When done, reassign the bug to security-team@suse.de.
https://swamp.suse.de/webswamp/wf/61279
Comment 6 Andreas Stieger 2015-03-31 12:32:14 UTC
Public via http://subversion.apache.org/security/CVE-2015-0248-advisory.txt


  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: subversion/mod_dav_svn/reports/get-location-segments.c
===================================================================
--- subversion/mod_dav_svn/reports/get-location-segments.c	(revision 1658197)
+++ 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: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c	(revision 1658197)
+++ 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. */
 
]]]

  Patch against 1.8.11:
[[[
Index: subversion/mod_dav_svn/reports/get-location-segments.c
===================================================================
--- subversion/mod_dav_svn/reports/get-location-segments.c	(revision 1658197)
+++ 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: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c	(revision 1658197)
+++ subversion/svnserve/serve.c	(working copy)
@@ -2468,10 +2468,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");
@@ -2478,9 +2499,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 "
@@ -2488,12 +2507,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. */
 
]]]
Comment 7 Bernhard Wiedemann 2015-03-31 13:00:26 UTC
This is an autogenerated message for OBS integration:
This bug (923794) was mentioned in
https://build.opensuse.org/request/show/293791 Factory / subversion
Comment 8 Bernhard Wiedemann 2015-03-31 14:00:22 UTC
This is an autogenerated message for OBS integration:
This bug (923794) was mentioned in
https://build.opensuse.org/request/show/293792 13.2+13.1 / subversion
Comment 10 Tomáš Chvátal 2015-04-03 08:23:42 UTC
All submits sent.
Comment 12 Swamp Workflow Management 2015-04-07 19:05:17 UTC
openSUSE-SU-2015:0672-1: An update that solves three vulnerabilities and has one errata is now available.

Category: security (moderate)
Bug References: 916286,923793,923794,923795
CVE References: CVE-2015-0202,CVE-2015-0248,CVE-2015-0251
Sources used:
openSUSE 13.2 (src):    subversion-1.8.13-2.14.1
openSUSE 13.1 (src):    subversion-1.8.13-2.36.1
Comment 13 Swamp Workflow Management 2015-04-11 04:06:07 UTC
SUSE-SU-2015:0709-1: An update that fixes two vulnerabilities is now available.

Category: security (moderate)
Bug References: 923794,923795
CVE References: CVE-2015-0248,CVE-2015-0251
Sources used:
SUSE Studio Onsite 1.3 (src):    subversion-1.6.17-1.33.1
SUSE Linux Enterprise Software Development Kit 11 SP3 (src):    subversion-1.6.17-1.33.1
Comment 14 Andreas Stieger 2015-04-27 10:43:34 UTC
releasing SLE 12 update
Comment 15 Swamp Workflow Management 2015-04-27 11:07:02 UTC
SUSE-SU-2015:0776-1: An update that fixes three vulnerabilities is now available.

Category: security (moderate)
Bug References: 923793,923794,923795
CVE References: CVE-2015-0202,CVE-2015-0248,CVE-2015-0251
Sources used:
SUSE Linux Enterprise Software Development Kit 12 (src):    subversion-1.8.10-12.1
Comment 16 Swamp Workflow Management 2017-08-17 10:11:59 UTC
SUSE-SU-2017:2200-1: An update that solves 12 vulnerabilities and has 7 fixes is now available.

Category: security (important)
Bug References: 1011552,1026936,1051362,897033,909935,911620,916286,923793,923794,923795,939514,939517,942819,958300,969159,976849,976850,977424,983938
CVE References: CVE-2014-3580,CVE-2014-8108,CVE-2015-0202,CVE-2015-0248,CVE-2015-0251,CVE-2015-3184,CVE-2015-3187,CVE-2015-5343,CVE-2016-2167,CVE-2016-2168,CVE-2016-8734,CVE-2017-9800
Sources used:
SUSE Linux Enterprise Software Development Kit 12-SP3 (src):    subversion-1.8.19-25.3.1
SUSE Linux Enterprise Software Development Kit 12-SP2 (src):    subversion-1.8.19-25.3.1