From: Giovanni Bechis Date: Tue, 6 Jun 2023 22:02:37 +0000 (+0000) Subject: mod_ext_filter: check exit status of filter processes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e466de0c0ca858be2d5bc1ebb446ef4b4dd0a4e6;p=thirdparty%2Fapache%2Fhttpd.git mod_ext_filter: check exit status of filter processes Whenever a filter process returns a non-zero exit status, or is killed by a signal, return a HTTP 500 error, and log the reason. Ran top-level make update-log-msg-tags to update APLOGNO numbers. Submitted by: Dimitry Andric Github: closes #296 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1910267 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 1ba80e8f118..22138604e1b 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -10451 +10455 diff --git a/modules/filters/mod_ext_filter.c b/modules/filters/mod_ext_filter.c index cb987c3aa5d..3944847c8de 100644 --- a/modules/filters/mod_ext_filter.c +++ b/modules/filters/mod_ext_filter.c @@ -726,6 +726,40 @@ static apr_status_t pass_data_to_filter(ap_filter_t *f, const char *data, return rv; } +/* check_filter_process_on_eos(): + * + * if we hit end-of-stream, check the exit status of the filter process, and log + * an appropriate message if it failed + */ +static apr_status_t check_filter_process_on_eos(ef_ctx_t *ctx, request_rec *r) +{ + if (ctx->hit_eos) { + int exitcode; + apr_exit_why_e exitwhy; + apr_status_t waitret = apr_proc_wait(ctx->proc, &exitcode, &exitwhy, + APR_WAIT); + if (waitret != APR_CHILD_DONE) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, waitret, r, APLOGNO(10451) + "apr_proc_wait() failed, uri=%s", r->uri); + return waitret; + } + else if (exitwhy != APR_PROC_EXIT) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(10452) + "child process %s killed by signal %d, uri=%s", + ctx->filter->command, exitcode, r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + else if (exitcode != 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(10453) + "child process %s exited with non-zero status %d, " + "uri=%s", ctx->filter->command, exitcode, r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + return APR_SUCCESS; +} + /* ef_unified_filter: * * runs the bucket brigade bb through the filter and puts the result into @@ -880,6 +914,11 @@ static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01468) "ef_unified_filter() failed"); + return rv; + } + + if ((rv = check_filter_process_on_eos(ctx, r)) != APR_SUCCESS) { + return rv; } if ((rv = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { @@ -939,7 +978,13 @@ static apr_status_t ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb, } rv = ef_unified_filter(f, bb); - return rv; + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(10454) + "ef_unified_filter() failed"); + return rv; + } + + return check_filter_process_on_eos(ctx, f->r); } AP_DECLARE_MODULE(ext_filter) =