From: Stefan Fritsch Date: Sun, 4 Oct 2009 08:08:50 +0000 (+0000) Subject: Make sure to not destroy bucket brigades that have been created by earlier X-Git-Tag: 2.3.3~218 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=922454bb69454004ac4f4fc7ba0d01f07477783a;p=thirdparty%2Fapache%2Fhttpd.git Make sure to not destroy bucket brigades that have been created by earlier filters. Otherwise the pool cleanups would be removed causing potential memory leaks later on. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@821477 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 38c3f92a1ad..3984251f554 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,10 @@ Changes with Apache 2.3.3 mod_proxy_ftp: NULL pointer dereference on error paths. [Stefan Fritsch , Joe Orton] + *) core: Fix potential memory leaks by making sure to not destroy + bucket brigades that have been created by earlier filters. + [Stefan Fritsch] + *) core, mod_deflate, mod_sed: Reduce memory usage by reusing bucket brigades in several places. [Stefan Fritsch] diff --git a/modules/http/byterange_filter.c b/modules/http/byterange_filter.c index a79b7f7d6de..92048ab75d7 100644 --- a/modules/http/byterange_filter.c +++ b/modules/http/byterange_filter.c @@ -307,7 +307,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, APR_BRIGADE_INSERT_TAIL(bsend, e); /* we're done with the original content - all of our data is in bsend. */ - apr_brigade_destroy(bb); + apr_brigade_cleanup(bb); /* send our multipart output */ return ap_pass_brigade(f->next, bsend); diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 3e96cb9de1d..01ced249448 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -1112,7 +1112,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx)); } else if (ctx->headers_sent) { - apr_brigade_destroy(b); + apr_brigade_cleanup(b); return OK; } } @@ -1283,7 +1283,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, ap_pass_brigade(f->next, b2); if (r->header_only) { - apr_brigade_destroy(b); + apr_brigade_cleanup(b); ctx->headers_sent = 1; return OK; } diff --git a/server/core_filters.c b/server/core_filters.c index f0737651414..4ff96d9811e 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -316,7 +316,7 @@ int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, static void setaside_remaining_output(ap_filter_t *f, core_output_filter_ctx_t *ctx, apr_bucket_brigade *bb, - int make_a_copy, conn_rec *c); + conn_rec *c); static apr_status_t send_brigade_nonblocking(apr_socket_t *s, apr_bucket_brigade *bb, @@ -392,19 +392,21 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb) } } + if (new_bb != NULL) { + bb = new_bb; + } + if ((ctx->buffered_bb != NULL) && !APR_BRIGADE_EMPTY(ctx->buffered_bb)) { - bb = ctx->buffered_bb; - ctx->buffered_bb = NULL; if (new_bb != NULL) { - APR_BRIGADE_CONCAT(bb, new_bb); + APR_BRIGADE_PREPEND(bb, ctx->buffered_bb); + } + else { + bb = ctx->buffered_bb; } c->data_in_output_filters = 0; } - else if (new_bb != NULL) { - bb = new_bb; - } - else { + else if (new_bb == NULL) { return APR_SUCCESS; } @@ -444,7 +446,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb) /* The client has aborted the connection */ c->aborted = 1; } - setaside_remaining_output(f, ctx, bb, 0, c); + setaside_remaining_output(f, ctx, bb, c); return rv; } @@ -508,14 +510,14 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb) } } - setaside_remaining_output(f, ctx, bb, 1, c); + setaside_remaining_output(f, ctx, bb, c); return APR_SUCCESS; } static void setaside_remaining_output(ap_filter_t *f, core_output_filter_ctx_t *ctx, apr_bucket_brigade *bb, - int make_a_copy, conn_rec *c) + conn_rec *c) { if (bb == NULL) { return; @@ -523,20 +525,14 @@ static void setaside_remaining_output(ap_filter_t *f, remove_empty_buckets(bb); if (!APR_BRIGADE_EMPTY(bb)) { c->data_in_output_filters = 1; - if (make_a_copy) { + if (bb != ctx->buffered_bb) { /* XXX should this use a separate deferred write pool, like * the original ap_core_output_filter? */ ap_save_brigade(f, &(ctx->buffered_bb), &bb, c->pool); - apr_brigade_destroy(bb); - } - else { - ctx->buffered_bb = bb; + apr_brigade_cleanup(bb); } } - else { - apr_brigade_destroy(bb); - } } #ifndef APR_MAX_IOVEC_SIZE