Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
apache2.36334
apache2-CVE-2022-22720.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File apache2-CVE-2022-22720.patch of Package apache2.36334
Index: httpd-2.4.51/changes-entries/discard_body.diff =================================================================== --- /dev/null +++ httpd-2.4.51/changes-entries/discard_body.diff @@ -0,0 +1,2 @@ + *) core: Simpler connection close logic if discarding the request body fails. + [Yann Ylavic, Ruediger Pluem] \ No newline at end of file Index: httpd-2.4.51/modules/http/http_filters.c =================================================================== --- httpd-2.4.51.orig/modules/http/http_filters.c +++ httpd-2.4.51/modules/http/http_filters.c @@ -1602,9 +1602,9 @@ AP_DECLARE(int) ap_map_http_request_erro */ AP_DECLARE(int) ap_discard_request_body(request_rec *r) { + int rc = OK; + conn_rec *c = r->connection; apr_bucket_brigade *bb; - int seen_eos; - apr_status_t rv; /* Sometimes we'll get in a state where the input handling has * detected an error where we want to drop the connection, so if @@ -1613,54 +1613,57 @@ AP_DECLARE(int) ap_discard_request_body( * * This function is also a no-op on a subrequest. */ - if (r->main || r->connection->keepalive == AP_CONN_CLOSE || - ap_status_drops_connection(r->status)) { + if (r->main || c->keepalive == AP_CONN_CLOSE) { + return OK; + } + if (ap_status_drops_connection(r->status)) { + c->keepalive = AP_CONN_CLOSE; return OK; } bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - seen_eos = 0; - do { - apr_bucket *bucket; + for (;;) { + apr_status_t rv; rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, APR_BLOCK_READ, HUGE_STRING_LEN); - if (rv != APR_SUCCESS) { - apr_brigade_destroy(bb); - return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); + rc = ap_map_http_request_error(rv, HTTP_BAD_REQUEST); + goto cleanup; } - for (bucket = APR_BRIGADE_FIRST(bb); - bucket != APR_BRIGADE_SENTINEL(bb); - bucket = APR_BUCKET_NEXT(bucket)) - { - const char *data; - apr_size_t len; - - if (APR_BUCKET_IS_EOS(bucket)) { - seen_eos = 1; - break; - } + while (!APR_BRIGADE_EMPTY(bb)) { + apr_bucket *b = APR_BRIGADE_FIRST(bb); - /* These are metadata buckets. */ - if (bucket->length == 0) { - continue; + if (APR_BUCKET_IS_EOS(b)) { + goto cleanup; } - /* We MUST read because in case we have an unknown-length - * bucket or one that morphs, we want to exhaust it. + /* There is no need to read empty or metadata buckets or + * buckets of known length, but we MUST read buckets of + * unknown length in order to exhaust them. */ - rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); - if (rv != APR_SUCCESS) { - apr_brigade_destroy(bb); - return HTTP_BAD_REQUEST; + if (b->length == (apr_size_t)-1) { + apr_size_t len; + const char *data; + + rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + rc = HTTP_BAD_REQUEST; + goto cleanup; + } } + + apr_bucket_delete(b); } - apr_brigade_cleanup(bb); - } while (!seen_eos); + } - return OK; +cleanup: + apr_brigade_cleanup(bb); + if (rc != OK) { + c->keepalive = AP_CONN_CLOSE; + } + return rc; } /* Here we deal with getting the request message body from the client. Index: httpd-2.4.51/server/protocol.c =================================================================== --- httpd-2.4.51.orig/server/protocol.c +++ httpd-2.4.51/server/protocol.c @@ -1692,23 +1692,28 @@ AP_DECLARE(void) ap_set_sub_req_protocol rnew->main = (request_rec *) r; } -static void end_output_stream(request_rec *r) +static void end_output_stream(request_rec *r, int status) { conn_rec *c = r->connection; apr_bucket_brigade *bb; apr_bucket *b; bb = apr_brigade_create(r->pool, c->bucket_alloc); + if (status != OK) { + b = ap_bucket_error_create(status, NULL, r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + } b = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); ap_pass_brigade(r->output_filters, bb); + apr_brigade_cleanup(bb); } AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) { /* tell the filter chain there is no more content coming */ if (!sub->eos_sent) { - end_output_stream(sub); + end_output_stream(sub, OK); } } @@ -1719,11 +1724,11 @@ AP_DECLARE(void) ap_finalize_sub_req_pro */ AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r) { - (void) ap_discard_request_body(r); + int status = ap_discard_request_body(r); /* tell the filter chain there is no more content coming */ if (!r->eos_sent) { - end_output_stream(r); + end_output_stream(r, status); } }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor