File apache2-CVE-2021-31618.patch of Package apache2.27541
--- 2.4.x/modules/http2/h2.h 2020/11/16 12:01:43 1883474
+++ 2.4.x/modules/http2/h2.h 2020/11/16 12:24:12 1883475
@@ -141,8 +141,19 @@ struct h2_request {
unsigned int chunked : 1; /* iff request body needs to be forwarded as chunked */
unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */
apr_off_t raw_bytes; /* RAW network bytes that generated this request - if known. */
+ int http_status; /* Store a possible HTTP status code that gets
+ * defined before creating the dummy HTTP/1.1
+ * request e.g. due to an error already
+ * detected.
+ */
};
+/*
+ * A possible HTTP status code is not defined yet. See the http_status field
+ * in struct h2_request above for further explanation.
+ */
+#define H2_HTTP_STATUS_UNSET (0)
+
typedef struct h2_headers h2_headers;
struct h2_headers {
--- 2.4.x/modules/http2/h2_request.c 2020/11/16 12:01:43 1883474
+++ 2.4.x/modules/http2/h2_request.c 2020/11/16 12:24:12 1883475
@@ -79,11 +79,12 @@ apr_status_t h2_request_rcreate(h2_reque
}
req = apr_pcalloc(pool, sizeof(*req));
- req->method = apr_pstrdup(pool, r->method);
- req->scheme = scheme;
- req->authority = authority;
- req->path = path;
- req->headers = apr_table_make(pool, 10);
+ req->method = apr_pstrdup(pool, r->method);
+ req->scheme = scheme;
+ req->authority = authority;
+ req->path = path;
+ req->headers = apr_table_make(pool, 10);
+ req->http_status = H2_HTTP_STATUS_UNSET;
if (r->server) {
req->serialize = h2_config_rgeti(r, H2_CONF_SER_HEADERS);
}
@@ -327,6 +328,13 @@ request_rec *h2_request_create_rec(const
}
}
+ if (req->http_status != H2_HTTP_STATUS_UNSET) {
+ access_status = req->http_status;
+ r->status = HTTP_OK;
+ /* Be safe and close the connection */
+ c->keepalive = AP_CONN_CLOSE;
+ }
+
/*
* Add the HTTP_IN filter here to ensure that ap_discard_request_body
* called by ap_die and by ap_send_error_response works correctly on
--- 2.4.x/modules/http2/h2_session.c 2020/11/16 12:01:43 1883474
+++ 2.4.x/modules/http2/h2_session.c 2020/11/16 12:24:12 1883475
@@ -311,7 +311,9 @@ static int on_header_cb(nghttp2_session
status = h2_stream_add_header(stream, (const char *)name, namelen,
(const char *)value, valuelen);
- if (status != APR_SUCCESS && !h2_stream_is_ready(stream)) {
+ if (status != APR_SUCCESS
+ && (!stream->rtmp
+ || stream->rtmp->http_status == H2_HTTP_STATUS_UNSET)) {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
return 0;
--- 2.4.x/modules/http2/h2_stream.c 2020/11/16 12:01:43 1883474
+++ 2.4.x/modules/http2/h2_stream.c 2020/11/16 12:24:12 1883475
@@ -639,16 +639,7 @@ void h2_stream_set_request(h2_stream *st
static void set_error_response(h2_stream *stream, int http_status)
{
if (!h2_stream_is_ready(stream)) {
- conn_rec *c = stream->session->c;
- apr_bucket *b;
- h2_headers *response;
-
- response = h2_headers_die(http_status, stream->request, stream->pool);
- prep_output(stream);
- b = apr_bucket_eos_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_HEAD(stream->out_buffer, b);
- b = h2_bucket_headers_create(c->bucket_alloc, response);
- APR_BRIGADE_INSERT_HEAD(stream->out_buffer, b);
+ stream->rtmp->http_status = http_status;
}
}