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. */
]]]