You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ko...@apache.org on 2016/10/10 09:40:06 UTC
svn commit: r1764040 - in /httpd/httpd/trunk/modules/dav/main: mod_dav.c
mod_dav.h
Author: kotkov
Date: Mon Oct 10 09:40:06 2016
New Revision: 1764040
URL: http://svn.apache.org/viewvc?rev=1764040&view=rev
Log:
mod_dav: Fix a potential cause of unbounded memory usage or incorrect
behavior in a routine that sends <DAV:response>'s to the output filters.
The dav_send_one_response() function accepts the current head of the output
filter list as an argument, but the actual head can change between calls to
ap_pass_brigade(). This can happen with self-removing filters, e.g., with
the filter from mod_headers or mod_deflate. Consequently, executing an
already removed filter can either cause unwanted memory usage or incorrect
behavior.
This patch changes the signature of the existing mod_dav's public API,
dav_send_one_response(), because this API is not yet a part of any 2.4.x
release.
* modules/dav/main/mod_dav.c
(dav_send_one_response): Accept a request_rec instead of an ap_filter_t.
Write the response to r->output_filters.
(dav_send_multistatus, dav_stream_response): Update these calling sites
of dav_send_one_response().
* modules/dav/main/mod_dav.h
(dav_send_one_response): Adjust definition.
Modified:
httpd/httpd/trunk/modules/dav/main/mod_dav.c
httpd/httpd/trunk/modules/dav/main/mod_dav.h
Modified: httpd/httpd/trunk/modules/dav/main/mod_dav.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/dav/main/mod_dav.c?rev=1764040&r1=1764039&r2=1764040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/dav/main/mod_dav.c (original)
+++ httpd/httpd/trunk/modules/dav/main/mod_dav.c Mon Oct 10 09:40:06 2016
@@ -438,30 +438,31 @@ static const char *dav_xml_escape_uri(ap
/* Write a complete RESPONSE object out as a <DAV:repsonse> xml
element. Data is sent into brigade BB, which is auto-flushed into
- OUTPUT filter stack. Use POOL for any temporary allocations.
+ the output filter stack for request R. Use POOL for any temporary
+ allocations.
[Presumably the <multistatus> tag has already been written; this
routine is shared by dav_send_multistatus and dav_stream_response.]
*/
DAV_DECLARE(void) dav_send_one_response(dav_response *response,
apr_bucket_brigade *bb,
- ap_filter_t *output,
+ request_rec *r,
apr_pool_t *pool)
{
apr_text *t = NULL;
if (response->propresult.xmlns == NULL) {
- ap_fputs(output, bb, "<D:response>");
+ ap_fputs(r->output_filters, bb, "<D:response>");
}
else {
- ap_fputs(output, bb, "<D:response");
+ ap_fputs(r->output_filters, bb, "<D:response");
for (t = response->propresult.xmlns; t; t = t->next) {
- ap_fputs(output, bb, t->text);
+ ap_fputs(r->output_filters, bb, t->text);
}
- ap_fputc(output, bb, '>');
+ ap_fputc(r->output_filters, bb, '>');
}
- ap_fputstrs(output, bb,
+ ap_fputstrs(r->output_filters, bb,
DEBUG_CR "<D:href>",
dav_xml_escape_uri(pool, response->href),
"</D:href>" DEBUG_CR,
@@ -472,7 +473,7 @@ DAV_DECLARE(void) dav_send_one_response(
* default to 500 Internal Server Error if first->status
* is not a known (or valid) status code.
*/
- ap_fputstrs(output, bb,
+ ap_fputstrs(r->output_filters, bb,
"<D:status>HTTP/1.1 ",
ap_get_status_line(response->status),
"</D:status>" DEBUG_CR,
@@ -481,7 +482,7 @@ DAV_DECLARE(void) dav_send_one_response(
else {
/* assume this includes <propstat> and is quoted properly */
for (t = response->propresult.propstats; t; t = t->next) {
- ap_fputs(output, bb, t->text);
+ ap_fputs(r->output_filters, bb, t->text);
}
}
@@ -490,14 +491,14 @@ DAV_DECLARE(void) dav_send_one_response(
* We supply the description, so we know it doesn't have to
* have any escaping/encoding applied to it.
*/
- ap_fputstrs(output, bb,
+ ap_fputstrs(r->output_filters, bb,
"<D:responsedescription>",
response->desc,
"</D:responsedescription>" DEBUG_CR,
NULL);
}
- ap_fputs(output, bb, "</D:response>" DEBUG_CR);
+ ap_fputs(r->output_filters, bb, "</D:response>" DEBUG_CR);
}
@@ -559,7 +560,7 @@ DAV_DECLARE(void) dav_send_multistatus(r
for (; first != NULL; first = first->next) {
apr_pool_clear(subpool);
- dav_send_one_response(first, bb, r->output_filters, subpool);
+ dav_send_one_response(first, bb, r, subpool);
}
apr_pool_destroy(subpool);
@@ -1189,7 +1190,7 @@ static void dav_stream_response(dav_walk
resp.propresult = *propstats;
}
- dav_send_one_response(&resp, ctx->bb, ctx->r->output_filters, pool);
+ dav_send_one_response(&resp, ctx->bb, ctx->r, pool);
}
Modified: httpd/httpd/trunk/modules/dav/main/mod_dav.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/dav/main/mod_dav.h?rev=1764040&r1=1764039&r2=1764040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/dav/main/mod_dav.h (original)
+++ httpd/httpd/trunk/modules/dav/main/mod_dav.h Mon Oct 10 09:40:06 2016
@@ -546,14 +546,15 @@ typedef enum {
/* Write a complete RESPONSE object out as a <DAV:response> xml
* element. Data is sent into brigade BB, which is auto-flushed into
- * OUTPUT filter stack. Use POOL for any temporary allocations.
+ * the output filter stack for request R. Use POOL for any temporary
+ * allocations.
*
* [Presumably the <multistatus> tag has already been written; this
* routine is shared by dav_send_multistatus and dav_stream_response.]
*/
DAV_DECLARE(void) dav_send_one_response(dav_response *response,
apr_bucket_brigade *bb,
- ap_filter_t *output,
+ request_rec *r,
apr_pool_t *pool);
/* Factorized helper function: prep request_rec R for a multistatus