From: Greg Ames Date: Mon, 11 Nov 2002 19:57:58 +0000 (+0000) Subject: prevent seg faults when running with Electric Fence. X-Git-Tag: 2.0.44~85 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=25fa263af3e858632b07ce6572415df79065fe2c;p=apache prevent seg faults when running with Electric Fence. The "more" brigade (created by apr_brigade_split after seeing a FLUSH bucket) was in the deferred_write_pool. d_w_p is cleared, "more" is copied into b, then the while loop test for APR_BRIGADE_EMPTY(b) blows up. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97484 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/core.c b/server/core.c index c87ecefc15..0738c098b6 100644 --- a/server/core.c +++ b/server/core.c @@ -3665,6 +3665,7 @@ static APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *logio_add_bytes_out; static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) { apr_status_t rv; + apr_bucket_brigade *more; /* definition moved to foil a gdb bug */ conn_rec *c = f->c; core_net_rec *net = f->ctx; core_output_filter_ctx_t *ctx = net->out_ctx; @@ -3690,7 +3691,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) apr_bucket *e; /* tail of brigade if we need another pass */ - apr_bucket_brigade *more = NULL; + more = NULL; /* one group of iovecs per pass over the brigade */ apr_size_t nvec = 0; @@ -4003,6 +4004,27 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) * created the resource */ if (ctx->deferred_write_pool) { + if (more) { + if (APR_BRIGADE_EMPTY(more)) { + /* the usual case - prevent the next loop iteration + * from referencing a brigade which lives in a + * cleared pool + */ + more = NULL; + } + else { + /* change the lifetime of "more" to the connection's + * lifetime + * + * XXX a shorter lifetime would be better for long-running + * keep-alive connections...might be able to use the + * input brigade's pool + */ + apr_bucket_brigade *tmp_more = more; + more = NULL; + ap_save_brigade(f, &more, &tmp_more, c->pool); + } + } apr_pool_clear(ctx->deferred_write_pool); } if (rv != APR_SUCCESS) {