Skip to content

Commit 8862b27

Browse files
committed
fix(filtering): avoid segfault in body filtering
In some cases apache2 drop the request before the body has finish to filter, in those case our context cleanup would drop the filter while it's used resulting in a segfault. Also we create the body filter as soon as possible so it will be available even if the request is drop from apache. Made also some ajustements in case the filtering does not work to correctly free up created buffer, this should result in less memory leaks (or event not) in case of errors during the filtering.
1 parent dddd517 commit 8862b27

File tree

2 files changed

+17
-24
lines changed

2 files changed

+17
-24
lines changed

Diff for: src/mod_redirectionio.c

+17-19
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,15 @@ static apr_status_t redirectionio_filter_header_filtering(ap_filter_t *f, apr_bu
252252
redirectionio_protocol_send_filter_headers(ctx, f->r);
253253
ap_remove_output_filter(f);
254254

255+
if (ctx->body_filter == NULL) {
256+
ctx->body_filter = (struct REDIRECTIONIO_FilterBodyAction *)redirectionio_action_body_filter_create(ctx->action, ctx->backend_response_status_code, ctx->response_headers);
257+
258+
// Force chunked encoding
259+
if (ctx->body_filter != NULL) {
260+
apr_table_unset(f->r->headers_out, "Content-Length");
261+
}
262+
}
263+
255264
return ap_pass_brigade(f->next, bb);
256265
}
257266

@@ -267,21 +276,10 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
267276
return ap_pass_brigade(f->next, bb);
268277
}
269278

270-
if (ctx->action == NULL) {
271-
return ap_pass_brigade(f->next, bb);
272-
}
273-
274279
if (ctx->body_filter == NULL) {
275-
ctx->body_filter = (struct REDIRECTIONIO_FilterBodyAction *)redirectionio_action_body_filter_create(ctx->action, ctx->backend_response_status_code, ctx->response_headers);
280+
ap_remove_output_filter(f);
276281

277-
if (ctx->body_filter == NULL) {
278-
ap_remove_output_filter(f);
279-
280-
return ap_pass_brigade(f->next, bb);
281-
}
282-
283-
// Force chunked encoding
284-
apr_table_unset(f->r->headers_out, "Content-Length");
282+
return ap_pass_brigade(f->next, bb);
285283
}
286284

287285
if (APR_BRIGADE_EMPTY(bb)) {
@@ -316,7 +314,10 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
316314
b_new = apr_bucket_transient_create((const char *)output.data, output.len, f->r->connection->bucket_alloc);
317315

318316
if (b_new == NULL) {
317+
redirectionio_action_body_filter_drop(ctx->body_filter);
318+
ctx->body_filter = NULL;
319319
ap_remove_output_filter(f);
320+
free(output.data);
320321

321322
return ap_pass_brigade(f->next, bb);
322323
}
@@ -328,13 +329,15 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
328329

329330
if (APR_BUCKET_IS_EOS(b)) {
330331
output = redirectionio_action_body_filter_close(ctx->body_filter);
332+
ctx->body_filter = NULL;
333+
ap_remove_output_filter(f);
331334

332335
if (output.len > 0) {
333336
// Create a new one
334337
b_new = apr_bucket_transient_create((const char *)output.data, output.len, f->r->connection->bucket_alloc);
335338

336339
if (b_new == NULL) {
337-
ap_remove_output_filter(f);
340+
free(output.data);
338341

339342
return ap_pass_brigade(f->next, bb);
340343
}
@@ -347,16 +350,11 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
347350
b_new = apr_bucket_eos_create(f->r->connection->bucket_alloc);
348351

349352
if (b_new == NULL) {
350-
ap_remove_output_filter(f);
351-
352353
return ap_pass_brigade(f->next, bb);
353354
}
354355

355356
APR_BRIGADE_INSERT_TAIL(bb_new, b_new);
356357

357-
// Remove filter
358-
ap_remove_output_filter(f);
359-
360358
// Break
361359
break;
362360
}

Diff for: src/redirectionio_protocol.c

-5
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,5 @@ apr_status_t redirectionio_context_cleanup(void *context) {
464464
ctx->response_headers = NULL;
465465
}
466466

467-
if (ctx->body_filter != NULL) {
468-
redirectionio_action_body_filter_drop(ctx->body_filter);
469-
ctx->body_filter = NULL;
470-
}
471-
472467
return APR_SUCCESS;
473468
}

0 commit comments

Comments
 (0)