当前位置: 首页 > 服务与支持 > 产品升级公告 > 安全漏洞公告

服务与支持Support

Apache Subversion mod_dav_svn远程拒绝服务漏洞

     发表日期:2015-04-02 10:26:00

Apache Subversion mod_dav_svn远程拒绝服务漏洞(CVE-2015-0248)
CVE-ID:CVE-2015-0248
发布日期:2015-04-01
更新日期:2015-04-01
受影响系统:
Apache Group Subversion 1.8.0-1.8.11
Apache Group Subversion 1.6.0-1.7.19
详细信息:
 
Subversion是一款开源多用户版本控制系统,支持非ASCII文本和二进制数据。
 
 
 
Subversion mod_dav_svn及svnserve服务器处理待评估的某些具特殊参数的请求时,会触发断言。断言会造成svnserve进程或进程代管mod_dav_svn模块(Apache)异常中止。这可导致拒绝服务。
 
 
来源:
Evgeny Kotkov
参考信息:
http://subversion.apache.org/security/CVE-2015-0248-advisory.txt
解决办法:
厂商补丁:
 
Apache Group
------------
Apache Group已经为此发布了一个安全公告(CVE-2015-0248-advisory)以及相应补丁:
 
CVE-2015-0248-advisory:Subversion mod_dav_svn and svnserve are vulnerable to a remotely triggerable   assertion DoS vulnerability for certain requests with dynamically evaluated   revision numbers.
 
链接:http://subversion.apache.org/security/CVE-2015-0248-advisory.txt
 
 
 
补丁:
 
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. */
 
 
 
]]]
 
 
 
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. */
 
 
 
]]]