diff --git a/README.debrand b/README.debrand
deleted file mode 100644
index 01c46d2..0000000
--- a/README.debrand
+++ /dev/null
@@ -1,2 +0,0 @@
-Warning: This package was configured for automatic debranding, but the changes
-failed to apply.
diff --git a/SOURCES/httpd-2.4.37-CVE-2020-13950.patch b/SOURCES/httpd-2.4.37-CVE-2020-13950.patch
new file mode 100644
index 0000000..419a635
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2020-13950.patch
@@ -0,0 +1,12 @@
+diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
+index 5786ea8..7da9bde 100644
+--- a/modules/proxy/mod_proxy_http.c
++++ b/modules/proxy/mod_proxy_http.c
+@@ -637,7 +637,6 @@ static int ap_proxy_http_prefetch(proxy_http_req_t *req,
+ "chunked body with Content-Length (C-L ignored)",
+ c->client_ip, c->remote_host ? c->remote_host: "");
+ req->old_cl_val = NULL;
+- origin->keepalive = AP_CONN_CLOSE;
+ p_conn->close = 1;
+ }
+
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-22719.patch b/SOURCES/httpd-2.4.37-CVE-2022-22719.patch
new file mode 100644
index 0000000..006cae3
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-22719.patch
@@ -0,0 +1,70 @@
+--- a/modules/lua/lua_request.c 2022/03/07 14:48:54 1898693
++++ b/modules/lua/lua_request.c 2022/03/07 14:51:19 1898694
+@@ -235,14 +235,16 @@
+ {
+ int rc = OK;
+
++ *rbuf = NULL;
++ *size = 0;
++
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
+ return (rc);
+ }
+ if (ap_should_client_block(r)) {
+
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+- char argsbuffer[HUGE_STRING_LEN];
+- apr_off_t rsize, len_read, rpos = 0;
++ apr_off_t len_read, rpos = 0;
+ apr_off_t length = r->remaining;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+@@ -250,18 +252,18 @@
+ return APR_EINCOMPLETE; /* Only room for incomplete data chunk :( */
+ }
+ *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1));
+- *size = length;
+- while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) {
+- if ((rpos + len_read) > length) {
+- rsize = length - rpos;
+- }
+- else {
+- rsize = len_read;
+- }
+-
+- memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize);
+- rpos += rsize;
++ while ((rpos < length)
++ && (len_read = ap_get_client_block(r, (char *) *rbuf + rpos,
++ length - rpos)) > 0) {
++ rpos += len_read;
+ }
++ if (len_read < 0) {
++ return APR_EINCOMPLETE;
++ }
++ *size = rpos;
++ }
++ else {
++ rc = DONE;
+ }
+
+ return (rc);
+@@ -278,6 +280,8 @@
+ {
+ apr_status_t rc = OK;
+
++ *size = 0;
++
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
+ return rc;
+ if (ap_should_client_block(r)) {
+@@ -303,6 +307,9 @@
+ rpos += rsize;
+ }
+ }
++ else {
++ rc = DONE;
++ }
+
+ return rc;
+ }
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-22720.patch b/SOURCES/httpd-2.4.37-CVE-2022-22720.patch
new file mode 100644
index 0000000..e4abca2
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-22720.patch
@@ -0,0 +1,154 @@
+diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
+index 9828cdf..6bedcac 100644
+--- a/modules/http/http_filters.c
++++ b/modules/http/http_filters.c
+@@ -1605,9 +1605,9 @@ AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status)
+ */
+ 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
+@@ -1616,54 +1616,57 @@ AP_DECLARE(int) ap_discard_request_body(request_rec *r)
+ *
+ * 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;
++ while (!APR_BRIGADE_EMPTY(bb)) {
++ apr_bucket *b = APR_BRIGADE_FIRST(bb);
+
+- if (APR_BUCKET_IS_EOS(bucket)) {
+- seen_eos = 1;
+- break;
++ if (APR_BUCKET_IS_EOS(b)) {
++ goto cleanup;
+ }
+
+- /* These are metadata buckets. */
+- if (bucket->length == 0) {
+- continue;
+- }
+-
+- /* 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 (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) {
+- apr_brigade_destroy(bb);
+- return HTTP_BAD_REQUEST;
++ rc = HTTP_BAD_REQUEST;
++ goto cleanup;
+ }
+ }
+- apr_brigade_cleanup(bb);
+- } while (!seen_eos);
+
+- return OK;
++ apr_bucket_delete(b);
++ }
++ }
++
++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.
+diff --git a/server/protocol.c b/server/protocol.c
+index a2aa081..a554970 100644
+--- a/server/protocol.c
++++ b/server/protocol.c
+@@ -1666,23 +1666,29 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew,
+ 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);
+ }
+ }
+
+@@ -1693,11 +1699,11 @@ AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub)
+ */
+ 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);
+ }
+ }
+
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-22721.patch b/SOURCES/httpd-2.4.37-CVE-2022-22721.patch
new file mode 100644
index 0000000..3985adb
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-22721.patch
@@ -0,0 +1,103 @@
+diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en
+index 20d1e5a..e1ec8d0 100644
+--- a/docs/manual/mod/core.html.en
++++ b/docs/manual/mod/core.html.en
+@@ -2935,12 +2935,19 @@ from the client
+
Status: | Core |
+ Module: | core |
+
+- Limit (in bytes) on maximum size of an XML-based request
+- body. A value of 0
will disable any checking.
++ Limit (in bytes) on the maximum size of an XML-based request
++ body. A value of 0
will apply a hard limit (depending on
++ 32bit vs 64bit system) allowing for XML escaping within the bounds of
++ the system addressable memory, but it exists for compatibility only
++ and is not recommended since it does not account for memory consumed
++ elsewhere or concurrent requests, which might result in an overall
++ system out-of-memory.
++
+
+ Example:
+
+- LimitXMLRequestBody 0
++ # Limit of 1 MiB
++ LimitXMLRequestBody 1073741824
+
+
+
+diff --git a/server/core.c b/server/core.c
+index e32613d..8abfa65 100644
+--- a/server/core.c
++++ b/server/core.c
+@@ -70,6 +70,8 @@
+ /* LimitXMLRequestBody handling */
+ #define AP_LIMIT_UNSET ((long) -1)
+ #define AP_DEFAULT_LIMIT_XML_BODY ((apr_size_t)1000000)
++/* Hard limit for ap_escape_html2() */
++#define AP_MAX_LIMIT_XML_BODY ((apr_size_t)(APR_SIZE_MAX / 6 - 1))
+
+ #define AP_MIN_SENDFILE_BYTES (256)
+
+@@ -3689,6 +3691,11 @@ static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_,
+ if (conf->limit_xml_body < 0)
+ return "LimitXMLRequestBody requires a non-negative integer.";
+
++ /* zero is AP_MAX_LIMIT_XML_BODY (implicitly) */
++ if ((apr_size_t)conf->limit_xml_body > AP_MAX_LIMIT_XML_BODY)
++ return apr_psprintf(cmd->pool, "LimitXMLRequestBody must not exceed "
++ "%" APR_SIZE_T_FMT, AP_MAX_LIMIT_XML_BODY);
++
+ return NULL;
+ }
+
+@@ -3777,6 +3784,8 @@ AP_DECLARE(apr_size_t) ap_get_limit_xml_body(const request_rec *r)
+ conf = ap_get_core_module_config(r->per_dir_config);
+ if (conf->limit_xml_body == AP_LIMIT_UNSET)
+ return AP_DEFAULT_LIMIT_XML_BODY;
++ if (conf->limit_xml_body == 0)
++ return AP_MAX_LIMIT_XML_BODY;
+
+ return (apr_size_t)conf->limit_xml_body;
+ }
+diff --git a/server/util.c b/server/util.c
+index 2a5dd04..eefdafa 100644
+--- a/server/util.c
++++ b/server/util.c
+@@ -2037,11 +2037,14 @@ AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *buffer)
+
+ AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc)
+ {
+- int i, j;
++ apr_size_t i, j;
+ char *x;
+
+ /* first, count the number of extra characters */
+- for (i = 0, j = 0; s[i] != '\0'; i++)
++ for (i = 0, j = 0; s[i] != '\0'; i++) {
++ if (i + j > APR_SIZE_MAX - 6) {
++ abort();
++ }
+ if (s[i] == '<' || s[i] == '>')
+ j += 3;
+ else if (s[i] == '&')
+@@ -2050,6 +2053,7 @@ AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc)
+ j += 5;
+ else if (toasc && !apr_isascii(s[i]))
+ j += 5;
++ }
+
+ if (j == 0)
+ return apr_pstrmemdup(p, s, i);
+diff --git a/server/util_xml.c b/server/util_xml.c
+index 4845194..22806fa 100644
+--- a/server/util_xml.c
++++ b/server/util_xml.c
+@@ -85,7 +85,7 @@ AP_DECLARE(int) ap_xml_parse_input(request_rec * r, apr_xml_doc **pdoc)
+ }
+
+ total_read += len;
+- if (limit_xml_body && total_read > limit_xml_body) {
++ if (total_read > limit_xml_body) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00539)
+ "XML request body is larger than the configured "
+ "limit of %lu", (unsigned long)limit_xml_body);
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-23943.patch b/SOURCES/httpd-2.4.37-CVE-2022-23943.patch
new file mode 100644
index 0000000..0383d2f
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-23943.patch
@@ -0,0 +1,377 @@
+diff --git a/modules/filters/libsed.h b/modules/filters/libsed.h
+index 76cbc0c..0256b1e 100644
+--- a/modules/filters/libsed.h
++++ b/modules/filters/libsed.h
+@@ -60,7 +60,7 @@ struct sed_label_s {
+ };
+
+ typedef apr_status_t (sed_err_fn_t)(void *data, const char *error);
+-typedef apr_status_t (sed_write_fn_t)(void *ctx, char *buf, int sz);
++typedef apr_status_t (sed_write_fn_t)(void *ctx, char *buf, apr_size_t sz);
+
+ typedef struct sed_commands_s sed_commands_t;
+ #define NWFILES 11 /* 10 plus one for standard output */
+@@ -69,7 +69,7 @@ struct sed_commands_s {
+ sed_err_fn_t *errfn;
+ void *data;
+
+- unsigned lsize;
++ apr_size_t lsize;
+ char *linebuf;
+ char *lbend;
+ const char *saveq;
+@@ -116,15 +116,15 @@ struct sed_eval_s {
+ apr_int64_t lnum;
+ void *fout;
+
+- unsigned lsize;
++ apr_size_t lsize;
+ char *linebuf;
+ char *lspend;
+
+- unsigned hsize;
++ apr_size_t hsize;
+ char *holdbuf;
+ char *hspend;
+
+- unsigned gsize;
++ apr_size_t gsize;
+ char *genbuf;
+ char *lcomend;
+
+@@ -160,7 +160,7 @@ apr_status_t sed_init_eval(sed_eval_t *eval, sed_commands_t *commands,
+ sed_err_fn_t *errfn, void *data,
+ sed_write_fn_t *writefn, apr_pool_t *p);
+ apr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data);
+-apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void *fout);
++apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout);
+ apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout);
+ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *f);
+ void sed_destroy_eval(sed_eval_t *eval);
+diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c
+index 346c210..8595e41 100644
+--- a/modules/filters/mod_sed.c
++++ b/modules/filters/mod_sed.c
+@@ -51,7 +51,7 @@ typedef struct sed_filter_ctxt
+ apr_bucket_brigade *bbinp;
+ char *outbuf;
+ char *curoutbuf;
+- int bufsize;
++ apr_size_t bufsize;
+ apr_pool_t *tpool;
+ int numbuckets;
+ } sed_filter_ctxt;
+@@ -100,7 +100,7 @@ static void alloc_outbuf(sed_filter_ctxt* ctx)
+ /* append_bucket
+ * Allocate a new bucket from buf and sz and append to ctx->bb
+ */
+-static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, int sz)
++static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, apr_size_t sz)
+ {
+ apr_status_t status = APR_SUCCESS;
+ apr_bucket *b;
+@@ -133,7 +133,7 @@ static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, int sz)
+ */
+ static apr_status_t flush_output_buffer(sed_filter_ctxt *ctx)
+ {
+- int size = ctx->curoutbuf - ctx->outbuf;
++ apr_size_t size = ctx->curoutbuf - ctx->outbuf;
+ char *out;
+ apr_status_t status = APR_SUCCESS;
+ if ((ctx->outbuf == NULL) || (size <=0))
+@@ -147,12 +147,12 @@ static apr_status_t flush_output_buffer(sed_filter_ctxt *ctx)
+ /* This is a call back function. When libsed wants to generate the output,
+ * this function will be invoked.
+ */
+-static apr_status_t sed_write_output(void *dummy, char *buf, int sz)
++static apr_status_t sed_write_output(void *dummy, char *buf, apr_size_t sz)
+ {
+ /* dummy is basically filter context. Context is passed during invocation
+ * of sed_eval_buffer
+ */
+- int remainbytes = 0;
++ apr_size_t remainbytes = 0;
+ apr_status_t status = APR_SUCCESS;
+ sed_filter_ctxt *ctx = (sed_filter_ctxt *) dummy;
+ if (ctx->outbuf == NULL) {
+@@ -168,21 +168,29 @@ static apr_status_t sed_write_output(void *dummy, char *buf, int sz)
+ }
+ /* buffer is now full */
+ status = append_bucket(ctx, ctx->outbuf, ctx->bufsize);
+- /* old buffer is now used so allocate new buffer */
+- alloc_outbuf(ctx);
+- /* if size is bigger than the allocated buffer directly add to output
+- * brigade */
+- if ((status == APR_SUCCESS) && (sz >= ctx->bufsize)) {
+- char* newbuf = apr_pmemdup(ctx->tpool, buf, sz);
+- status = append_bucket(ctx, newbuf, sz);
+- /* pool might get clear after append_bucket */
+- if (ctx->outbuf == NULL) {
++ if (status == APR_SUCCESS) {
++ /* if size is bigger than the allocated buffer directly add to output
++ * brigade */
++ if (sz >= ctx->bufsize) {
++ char* newbuf = apr_pmemdup(ctx->tpool, buf, sz);
++ status = append_bucket(ctx, newbuf, sz);
++ if (status == APR_SUCCESS) {
++ /* old buffer is now used so allocate new buffer */
++ alloc_outbuf(ctx);
++ }
++ else {
++ clear_ctxpool(ctx);
++ }
++ }
++ else {
++ /* old buffer is now used so allocate new buffer */
+ alloc_outbuf(ctx);
++ memcpy(ctx->curoutbuf, buf, sz);
++ ctx->curoutbuf += sz;
+ }
+ }
+ else {
+- memcpy(ctx->curoutbuf, buf, sz);
+- ctx->curoutbuf += sz;
++ clear_ctxpool(ctx);
+ }
+ }
+ else {
+diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c
+index be03506..67a8d06 100644
+--- a/modules/filters/sed1.c
++++ b/modules/filters/sed1.c
+@@ -71,7 +71,7 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
+ static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2);
+ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ step_vars_storage *step_vars);
+-static apr_status_t wline(sed_eval_t *eval, char *buf, int sz);
++static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz);
+ static apr_status_t arout(sed_eval_t *eval);
+
+ static void eval_errf(sed_eval_t *eval, const char *fmt, ...)
+@@ -92,11 +92,11 @@ static void eval_errf(sed_eval_t *eval, const char *fmt, ...)
+ * grow_buffer
+ */
+ static void grow_buffer(apr_pool_t *pool, char **buffer,
+- char **spend, unsigned int *cursize,
+- unsigned int newsize)
++ char **spend, apr_size_t *cursize,
++ apr_size_t newsize)
+ {
+ char* newbuffer = NULL;
+- int spendsize = 0;
++ apr_size_t spendsize = 0;
+ if (*cursize >= newsize)
+ return;
+ /* Avoid number of times realloc is called. It could cause huge memory
+@@ -124,7 +124,7 @@ static void grow_buffer(apr_pool_t *pool, char **buffer,
+ /*
+ * grow_line_buffer
+ */
+-static void grow_line_buffer(sed_eval_t *eval, int newsize)
++static void grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
+ {
+ grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
+ &eval->lsize, newsize);
+@@ -133,7 +133,7 @@ static void grow_line_buffer(sed_eval_t *eval, int newsize)
+ /*
+ * grow_hold_buffer
+ */
+-static void grow_hold_buffer(sed_eval_t *eval, int newsize)
++static void grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
+ {
+ grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
+ &eval->hsize, newsize);
+@@ -142,7 +142,7 @@ static void grow_hold_buffer(sed_eval_t *eval, int newsize)
+ /*
+ * grow_gen_buffer
+ */
+-static void grow_gen_buffer(sed_eval_t *eval, int newsize,
++static void grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize,
+ char **gspend)
+ {
+ if (gspend == NULL) {
+@@ -156,9 +156,9 @@ static void grow_gen_buffer(sed_eval_t *eval, int newsize,
+ /*
+ * appendmem_to_linebuf
+ */
+-static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, int len)
++static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len)
+ {
+- unsigned int reqsize = (eval->lspend - eval->linebuf) + len;
++ apr_size_t reqsize = (eval->lspend - eval->linebuf) + len;
+ if (eval->lsize < reqsize) {
+ grow_line_buffer(eval, reqsize);
+ }
+@@ -169,21 +169,36 @@ static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, int len)
+ /*
+ * append_to_linebuf
+ */
+-static void append_to_linebuf(sed_eval_t *eval, const char* sz)
++static void append_to_linebuf(sed_eval_t *eval, const char* sz,
++ step_vars_storage *step_vars)
+ {
+- int len = strlen(sz);
++ apr_size_t len = strlen(sz);
++ char *old_linebuf = eval->linebuf;
+ /* Copy string including null character */
+ appendmem_to_linebuf(eval, sz, len + 1);
+ --eval->lspend; /* lspend will now point to NULL character */
++ /* Sync step_vars after a possible linebuf expansion */
++ if (step_vars && old_linebuf != eval->linebuf) {
++ if (step_vars->loc1) {
++ step_vars->loc1 = step_vars->loc1 - old_linebuf + eval->linebuf;
++ }
++ if (step_vars->loc2) {
++ step_vars->loc2 = step_vars->loc2 - old_linebuf + eval->linebuf;
++ }
++ if (step_vars->locs) {
++ step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf;
++ }
++ }
+ }
+
+ /*
+ * copy_to_linebuf
+ */
+-static void copy_to_linebuf(sed_eval_t *eval, const char* sz)
++static void copy_to_linebuf(sed_eval_t *eval, const char* sz,
++ step_vars_storage *step_vars)
+ {
+ eval->lspend = eval->linebuf;
+- append_to_linebuf(eval, sz);
++ append_to_linebuf(eval, sz, step_vars);
+ }
+
+ /*
+@@ -191,8 +206,8 @@ static void copy_to_linebuf(sed_eval_t *eval, const char* sz)
+ */
+ static void append_to_holdbuf(sed_eval_t *eval, const char* sz)
+ {
+- int len = strlen(sz);
+- unsigned int reqsize = (eval->hspend - eval->holdbuf) + len + 1;
++ apr_size_t len = strlen(sz);
++ apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1;
+ if (eval->hsize <= reqsize) {
+ grow_hold_buffer(eval, reqsize);
+ }
+@@ -215,8 +230,8 @@ static void copy_to_holdbuf(sed_eval_t *eval, const char* sz)
+ */
+ static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
+ {
+- int len = strlen(sz);
+- unsigned int reqsize = (*gspend - eval->genbuf) + len + 1;
++ apr_size_t len = strlen(sz);
++ apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1;
+ if (eval->gsize < reqsize) {
+ grow_gen_buffer(eval, reqsize, gspend);
+ }
+@@ -230,8 +245,8 @@ static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
+ */
+ static void copy_to_genbuf(sed_eval_t *eval, const char* sz)
+ {
+- int len = strlen(sz);
+- unsigned int reqsize = len + 1;
++ apr_size_t len = strlen(sz);
++ apr_size_t reqsize = len + 1;
+ if (eval->gsize < reqsize) {
+ grow_gen_buffer(eval, reqsize, NULL);
+ }
+@@ -353,7 +368,7 @@ apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout)
+ /*
+ * sed_eval_buffer
+ */
+-apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void *fout)
++apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout)
+ {
+ apr_status_t rv;
+
+@@ -383,7 +398,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void
+
+ while (bufsz) {
+ char *n;
+- int llen;
++ apr_size_t llen;
+
+ n = memchr(buf, '\n', bufsz);
+ if (n == NULL)
+@@ -442,7 +457,7 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
+ * buffer is not a newline.
+ */
+ /* Assure space for NULL */
+- append_to_linebuf(eval, "");
++ append_to_linebuf(eval, "", NULL);
+ }
+
+ *eval->lspend = '\0';
+@@ -666,7 +681,7 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
+ lp = step_vars->loc2;
+ step_vars->loc2 = sp - eval->genbuf + eval->linebuf;
+ append_to_genbuf(eval, lp, &sp);
+- copy_to_linebuf(eval, eval->genbuf);
++ copy_to_linebuf(eval, eval->genbuf, step_vars);
+ return rv;
+ }
+
+@@ -676,8 +691,8 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
+ static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2)
+ {
+ char *sp = asp;
+- int n = al2 - al1;
+- unsigned int reqsize = (sp - eval->genbuf) + n + 1;
++ apr_size_t n = al2 - al1;
++ apr_size_t reqsize = (sp - eval->genbuf) + n + 1;
+
+ if (eval->gsize < reqsize) {
+ grow_gen_buffer(eval, reqsize, &sp);
+@@ -735,7 +750,7 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ }
+
+ p1++;
+- copy_to_linebuf(eval, p1);
++ copy_to_linebuf(eval, p1, step_vars);
+ eval->jflag++;
+ break;
+
+@@ -745,12 +760,12 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ break;
+
+ case GCOM:
+- copy_to_linebuf(eval, eval->holdbuf);
++ copy_to_linebuf(eval, eval->holdbuf, step_vars);
+ break;
+
+ case CGCOM:
+- append_to_linebuf(eval, "\n");
+- append_to_linebuf(eval, eval->holdbuf);
++ append_to_linebuf(eval, "\n", step_vars);
++ append_to_linebuf(eval, eval->holdbuf, step_vars);
+ break;
+
+ case HCOM:
+@@ -881,7 +896,7 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+- append_to_linebuf(eval, "\n");
++ append_to_linebuf(eval, "\n", step_vars);
+ eval->pending = ipc->next;
+ break;
+
+@@ -956,7 +971,7 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+
+ case XCOM:
+ copy_to_genbuf(eval, eval->linebuf);
+- copy_to_linebuf(eval, eval->holdbuf);
++ copy_to_linebuf(eval, eval->holdbuf, step_vars);
+ copy_to_holdbuf(eval, eval->genbuf);
+ break;
+
+@@ -1013,7 +1028,7 @@ static apr_status_t arout(sed_eval_t *eval)
+ /*
+ * wline
+ */
+-static apr_status_t wline(sed_eval_t *eval, char *buf, int sz)
++static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz)
+ {
+ apr_status_t rv = APR_SUCCESS;
+ rv = eval->writefn(eval->fout, buf, sz);
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-26377.patch b/SOURCES/httpd-2.4.37-CVE-2022-26377.patch
new file mode 100644
index 0000000..d954758
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-26377.patch
@@ -0,0 +1,26 @@
+diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
+index 6faabea..058b03f 100644
+--- a/modules/proxy/mod_proxy_ajp.c
++++ b/modules/proxy/mod_proxy_ajp.c
+@@ -249,9 +249,18 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
+ /* read the first bloc of data */
+ input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
+ tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
+- if (tenc && (strcasecmp(tenc, "chunked") == 0)) {
+- /* The AJP protocol does not want body data yet */
+- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) "request is chunked");
++ if (tenc) {
++ if (ap_cstr_casecmp(tenc, "chunked") == 0) {
++ /* The AJP protocol does not want body data yet */
++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870)
++ "request is chunked");
++ }
++ else {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396)
++ "%s Transfer-Encoding is not supported",
++ tenc);
++ return HTTP_INTERNAL_SERVER_ERROR;
++ }
+ } else {
+ /* Get client provided Content-Length header */
+ content_length = get_content_length(r);
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-28614.patch b/SOURCES/httpd-2.4.37-CVE-2022-28614.patch
new file mode 100644
index 0000000..3860dbe
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-28614.patch
@@ -0,0 +1,47 @@
+diff --git a/include/http_protocol.h b/include/http_protocol.h
+index e1572dc..8ed77ac 100644
+--- a/include/http_protocol.h
++++ b/include/http_protocol.h
+@@ -439,7 +439,27 @@ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r);
+ */
+ static APR_INLINE int ap_rputs(const char *str, request_rec *r)
+ {
+- return ap_rwrite(str, (int)strlen(str), r);
++ apr_size_t len;
++
++ len = strlen(str);
++
++ for (;;) {
++ if (len <= INT_MAX) {
++ return ap_rwrite(str, (int)len, r);
++ }
++ else {
++ int rc;
++
++ rc = ap_rwrite(str, INT_MAX, r);
++ if (rc < 0) {
++ return rc;
++ }
++ else {
++ str += INT_MAX;
++ len -= INT_MAX;
++ }
++ }
++ }
+ }
+
+ /**
+diff --git a/server/protocol.c b/server/protocol.c
+index a554970..ea461a2 100644
+--- a/server/protocol.c
++++ b/server/protocol.c
+@@ -2107,6 +2107,9 @@ AP_DECLARE(int) ap_rputc(int c, request_rec *r)
+
+ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
+ {
++ if (nbyte < 0)
++ return -1;
++
+ if (r->connection->aborted)
+ return -1;
+
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-28615.patch b/SOURCES/httpd-2.4.37-CVE-2022-28615.patch
new file mode 100644
index 0000000..575f4a3
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-28615.patch
@@ -0,0 +1,22 @@
+diff --git a/server/util.c b/server/util.c
+index eefdafa..45051b7 100644
+--- a/server/util.c
++++ b/server/util.c
+@@ -186,7 +186,7 @@ AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt,
+ */
+ AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
+ {
+- int x, y;
++ apr_size_t x, y;
+
+ for (x = 0, y = 0; expected[y]; ++y, ++x) {
+ if ((!str[x]) && (expected[y] != '*'))
+@@ -210,7 +210,7 @@ AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
+
+ AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected)
+ {
+- int x, y;
++ apr_size_t x, y;
+
+ for (x = 0, y = 0; expected[y]; ++y, ++x) {
+ if (!str[x] && expected[y] != '*')
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-29404.patch b/SOURCES/httpd-2.4.37-CVE-2022-29404.patch
new file mode 100644
index 0000000..3d706be
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-29404.patch
@@ -0,0 +1,126 @@
+diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en
+index e1ec8d0..833fa7b 100644
+--- a/docs/manual/mod/core.html.en
++++ b/docs/manual/mod/core.html.en
+@@ -2748,16 +2748,16 @@ subrequests
+ Description: | Restricts the total size of the HTTP request body sent
+ from the client |
+ Syntax: | LimitRequestBody bytes |
+-Default: | LimitRequestBody 0 |
++Default: | LimitRequestBody 1073741824 |
+ Context: | server config, virtual host, directory, .htaccess |
+ Override: | All |
+ Status: | Core |
+ Module: | core |
++Compatibility: | In Apache HTTP Server 2.4.53 and earlier, the default value
++ was 0 (unlimited) |
+
+- This directive specifies the number of bytes from 0
+- (meaning unlimited) to 2147483647 (2GB) that are allowed in a
+- request body. See the note below for the limited applicability
+- to proxy requests.
++ This directive specifies the number of bytes
++ that are allowed in a request body. A value of 0 means unlimited.
+
+ The LimitRequestBody
directive allows
+ the user to set a limit on the allowed size of an HTTP request
+@@ -2783,12 +2783,6 @@ from the client
+
+
LimitRequestBody 102400
+
+-
+- For a full description of how this directive is interpreted by
+- proxy requests, see the mod_proxy
documentation.
+-
+-
+-
+
+
+
+diff --git a/docs/manual/mod/mod_proxy.html.en b/docs/manual/mod/mod_proxy.html.en
+index 2cc6ace..c9e4634 100644
+--- a/docs/manual/mod/mod_proxy.html.en
++++ b/docs/manual/mod/mod_proxy.html.en
+@@ -459,9 +459,6 @@ ProxyPass "/examples" "http://backend.example.com/examples" timeout=10
+ Content-Length header, but the server is configured to filter incoming
+ request bodies.
+
+-
LimitRequestBody
only applies to
+- request bodies that the server will spool to disk
+-
+
+
+
+diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
+index 6bedcac..393343a 100644
+--- a/modules/http/http_filters.c
++++ b/modules/http/http_filters.c
+@@ -1710,6 +1710,7 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
+ {
+ const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
+ const char *lenp = apr_table_get(r->headers_in, "Content-Length");
++ apr_off_t limit_req_body = ap_get_limit_req_body(r);
+
+ r->read_body = read_policy;
+ r->read_chunked = 0;
+@@ -1748,6 +1749,11 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+
++ if (limit_req_body > 0 && (r->remaining > limit_req_body)) {
++ /* will be logged when the body is discarded */
++ return HTTP_REQUEST_ENTITY_TOO_LARGE;
++ }
++
+ #ifdef AP_DEBUG
+ {
+ /* Make sure ap_getline() didn't leave any droppings. */
+diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
+index 7da9bde..1b7bb81 100644
+--- a/modules/proxy/mod_proxy_http.c
++++ b/modules/proxy/mod_proxy_http.c
+@@ -439,13 +439,10 @@ static int spool_reqbody_cl(proxy_http_req_t *req, apr_off_t *bytes_spooled)
+ apr_bucket *e;
+ apr_off_t bytes, fsize = 0;
+ apr_file_t *tmpfile = NULL;
+- apr_off_t limit;
+
+ body_brigade = apr_brigade_create(p, bucket_alloc);
+ *bytes_spooled = 0;
+
+- limit = ap_get_limit_req_body(r);
+-
+ do {
+ if (APR_BRIGADE_EMPTY(input_brigade)) {
+ rv = stream_reqbody_read(req, input_brigade, 0);
+@@ -462,17 +459,6 @@ static int spool_reqbody_cl(proxy_http_req_t *req, apr_off_t *bytes_spooled)
+ apr_brigade_length(input_brigade, 1, &bytes);
+
+ if (*bytes_spooled + bytes > MAX_MEM_SPOOL) {
+- /*
+- * LimitRequestBody does not affect Proxy requests (Should it?).
+- * Let it take effect if we decide to store the body in a
+- * temporary file on disk.
+- */
+- if (limit && (*bytes_spooled + bytes > limit)) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01088)
+- "Request body is larger than the configured "
+- "limit of %" APR_OFF_T_FMT, limit);
+- return HTTP_REQUEST_ENTITY_TOO_LARGE;
+- }
+ /* can't spool any more in memory; write latest brigade to disk */
+ if (tmpfile == NULL) {
+ const char *temp_dir;
+diff --git a/server/core.c b/server/core.c
+index 09664fc..084e243 100644
+--- a/server/core.c
++++ b/server/core.c
+@@ -65,7 +65,7 @@
+
+ /* LimitRequestBody handling */
+ #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
+-#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0)
++#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */
+
+ /* LimitXMLRequestBody handling */
+ #define AP_LIMIT_UNSET ((long) -1)
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-30522.patch b/SOURCES/httpd-2.4.37-CVE-2022-30522.patch
new file mode 100644
index 0000000..92cffdc
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-30522.patch
@@ -0,0 +1,541 @@
+diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c
+index 8595e41..9b99a6b 100644
+--- a/modules/filters/mod_sed.c
++++ b/modules/filters/mod_sed.c
+@@ -59,7 +59,7 @@ typedef struct sed_filter_ctxt
+ module AP_MODULE_DECLARE_DATA sed_module;
+
+ /* This function will be call back from libsed functions if there is any error
+- * happend during execution of sed scripts
++ * happened during execution of sed scripts
+ */
+ static apr_status_t log_sed_errf(void *data, const char *error)
+ {
+@@ -276,7 +276,7 @@ static apr_status_t sed_response_filter(ap_filter_t *f,
+ apr_bucket_brigade *bb)
+ {
+ apr_bucket *b;
+- apr_status_t status;
++ apr_status_t status = APR_SUCCESS;
+ sed_config *cfg = ap_get_module_config(f->r->per_dir_config,
+ &sed_module);
+ sed_filter_ctxt *ctx = f->ctx;
+@@ -301,9 +301,9 @@ static apr_status_t sed_response_filter(ap_filter_t *f,
+ return status;
+ ctx = f->ctx;
+ apr_table_unset(f->r->headers_out, "Content-Length");
+- }
+
+- ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
++ ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
++ }
+
+ /* Here is the main logic. Iterate through all the buckets, read the
+ * content of the bucket, call sed_eval_buffer on the data.
+@@ -325,63 +325,52 @@ static apr_status_t sed_response_filter(ap_filter_t *f,
+ * in sed's internal buffer which can't be flushed until new line
+ * character is arrived.
+ */
+- for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb);) {
+- const char *buf = NULL;
+- apr_size_t bytes = 0;
++ while (!APR_BRIGADE_EMPTY(bb)) {
++ b = APR_BRIGADE_FIRST(bb);
+ if (APR_BUCKET_IS_EOS(b)) {
+- apr_bucket *b1 = APR_BUCKET_NEXT(b);
+ /* Now clean up the internal sed buffer */
+ sed_finalize_eval(&ctx->eval, ctx);
+ status = flush_output_buffer(ctx);
+ if (status != APR_SUCCESS) {
+- clear_ctxpool(ctx);
+- return status;
++ break;
+ }
++ /* Move the eos bucket to ctx->bb brigade */
+ APR_BUCKET_REMOVE(b);
+- /* Insert the eos bucket to ctx->bb brigade */
+ APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
+- b = b1;
+ }
+ else if (APR_BUCKET_IS_FLUSH(b)) {
+- apr_bucket *b1 = APR_BUCKET_NEXT(b);
+- APR_BUCKET_REMOVE(b);
+ status = flush_output_buffer(ctx);
+ if (status != APR_SUCCESS) {
+- clear_ctxpool(ctx);
+- return status;
++ break;
+ }
++ /* Move the flush bucket to ctx->bb brigade */
++ APR_BUCKET_REMOVE(b);
+ APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
+- b = b1;
+- }
+- else if (APR_BUCKET_IS_METADATA(b)) {
+- b = APR_BUCKET_NEXT(b);
+ }
+- else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
+- == APR_SUCCESS) {
+- apr_bucket *b1 = APR_BUCKET_NEXT(b);
+- status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
+- if (status != APR_SUCCESS) {
+- clear_ctxpool(ctx);
+- return status;
++ else {
++ if (!APR_BUCKET_IS_METADATA(b)) {
++ const char *buf = NULL;
++ apr_size_t bytes = 0;
++
++ status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ);
++ if (status == APR_SUCCESS) {
++ status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
++ }
++ if (status != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10394) "error evaluating sed on output");
++ break;
++ }
+ }
+- APR_BUCKET_REMOVE(b);
+ apr_bucket_delete(b);
+- b = b1;
+- }
+- else {
+- apr_bucket *b1 = APR_BUCKET_NEXT(b);
+- APR_BUCKET_REMOVE(b);
+- b = b1;
+ }
+ }
+- apr_brigade_cleanup(bb);
+- status = flush_output_buffer(ctx);
+- if (status != APR_SUCCESS) {
+- clear_ctxpool(ctx);
+- return status;
++ if (status == APR_SUCCESS) {
++ status = flush_output_buffer(ctx);
+ }
+ if (!APR_BRIGADE_EMPTY(ctx->bb)) {
+- status = ap_pass_brigade(f->next, ctx->bb);
++ if (status == APR_SUCCESS) {
++ status = ap_pass_brigade(f->next, ctx->bb);
++ }
+ apr_brigade_cleanup(ctx->bb);
+ }
+ clear_ctxpool(ctx);
+@@ -432,7 +421,7 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
+ * the buckets in bbinp and read the data from buckets and invoke
+ * sed_eval_buffer on the data. libsed will generate its output using
+ * sed_write_output which will add data in ctx->bb. Do it until it have
+- * atleast one bucket in ctx->bb. At the end of data eos bucket
++ * at least one bucket in ctx->bb. At the end of data eos bucket
+ * should be there.
+ *
+ * Once eos bucket is seen, then invoke sed_finalize_eval to clear the
+@@ -474,8 +463,10 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
+ if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
+ == APR_SUCCESS) {
+ status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
+- if (status != APR_SUCCESS)
++ if (status != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10395) "error evaluating sed on input");
+ return status;
++ }
+ flush_output_buffer(ctx);
+ }
+ }
+diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c
+index 67a8d06..047f49b 100644
+--- a/modules/filters/sed1.c
++++ b/modules/filters/sed1.c
+@@ -87,18 +87,20 @@ static void eval_errf(sed_eval_t *eval, const char *fmt, ...)
+ }
+
+ #define INIT_BUF_SIZE 1024
++#define MAX_BUF_SIZE 1024*8192
+
+ /*
+ * grow_buffer
+ */
+-static void grow_buffer(apr_pool_t *pool, char **buffer,
++static apr_status_t grow_buffer(apr_pool_t *pool, char **buffer,
+ char **spend, apr_size_t *cursize,
+ apr_size_t newsize)
+ {
+ char* newbuffer = NULL;
+ apr_size_t spendsize = 0;
+- if (*cursize >= newsize)
+- return;
++ if (*cursize >= newsize) {
++ return APR_SUCCESS;
++ }
+ /* Avoid number of times realloc is called. It could cause huge memory
+ * requirement if line size is huge e.g 2 MB */
+ if (newsize < *cursize * 2) {
+@@ -107,6 +109,9 @@ static void grow_buffer(apr_pool_t *pool, char **buffer,
+
+ /* Align it to 4 KB boundary */
+ newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) - 1);
++ if (newsize > MAX_BUF_SIZE) {
++ return APR_ENOMEM;
++ }
+ newbuffer = apr_pcalloc(pool, newsize);
+ if (*spend && *buffer && (*cursize > 0)) {
+ spendsize = *spend - *buffer;
+@@ -119,63 +124,77 @@ static void grow_buffer(apr_pool_t *pool, char **buffer,
+ if (spend != buffer) {
+ *spend = *buffer + spendsize;
+ }
++ return APR_SUCCESS;
+ }
+
+ /*
+ * grow_line_buffer
+ */
+-static void grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
++static apr_status_t grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
+ {
+- grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
++ return grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
+ &eval->lsize, newsize);
+ }
+
+ /*
+ * grow_hold_buffer
+ */
+-static void grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
++static apr_status_t grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
+ {
+- grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
++ return grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
+ &eval->hsize, newsize);
+ }
+
+ /*
+ * grow_gen_buffer
+ */
+-static void grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize,
++static apr_status_t grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize,
+ char **gspend)
+ {
++ apr_status_t rc = 0;
+ if (gspend == NULL) {
+ gspend = &eval->genbuf;
+ }
+- grow_buffer(eval->pool, &eval->genbuf, gspend,
+- &eval->gsize, newsize);
+- eval->lcomend = &eval->genbuf[71];
++ rc = grow_buffer(eval->pool, &eval->genbuf, gspend,
++ &eval->gsize, newsize);
++ if (rc == APR_SUCCESS) {
++ eval->lcomend = &eval->genbuf[71];
++ }
++ return rc;
+ }
+
+ /*
+ * appendmem_to_linebuf
+ */
+-static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len)
++static apr_status_t appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len)
+ {
++ apr_status_t rc = 0;
+ apr_size_t reqsize = (eval->lspend - eval->linebuf) + len;
+ if (eval->lsize < reqsize) {
+- grow_line_buffer(eval, reqsize);
++ rc = grow_line_buffer(eval, reqsize);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ }
+ memcpy(eval->lspend, sz, len);
+ eval->lspend += len;
++ return APR_SUCCESS;
+ }
+
+ /*
+ * append_to_linebuf
+ */
+-static void append_to_linebuf(sed_eval_t *eval, const char* sz,
++static apr_status_t append_to_linebuf(sed_eval_t *eval, const char* sz,
+ step_vars_storage *step_vars)
+ {
+ apr_size_t len = strlen(sz);
+ char *old_linebuf = eval->linebuf;
++ apr_status_t rc = 0;
+ /* Copy string including null character */
+- appendmem_to_linebuf(eval, sz, len + 1);
++ rc = appendmem_to_linebuf(eval, sz, len + 1);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ --eval->lspend; /* lspend will now point to NULL character */
+ /* Sync step_vars after a possible linebuf expansion */
+ if (step_vars && old_linebuf != eval->linebuf) {
+@@ -189,68 +208,84 @@ static void append_to_linebuf(sed_eval_t *eval, const char* sz,
+ step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf;
+ }
+ }
++ return APR_SUCCESS;
+ }
+
+ /*
+ * copy_to_linebuf
+ */
+-static void copy_to_linebuf(sed_eval_t *eval, const char* sz,
++static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char* sz,
+ step_vars_storage *step_vars)
+ {
+ eval->lspend = eval->linebuf;
+- append_to_linebuf(eval, sz, step_vars);
++ return append_to_linebuf(eval, sz, step_vars);
+ }
+
+ /*
+ * append_to_holdbuf
+ */
+-static void append_to_holdbuf(sed_eval_t *eval, const char* sz)
++static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char* sz)
+ {
+ apr_size_t len = strlen(sz);
+ apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1;
++ apr_status_t rc = 0;
+ if (eval->hsize <= reqsize) {
+- grow_hold_buffer(eval, reqsize);
++ rc = grow_hold_buffer(eval, reqsize);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ }
+ memcpy(eval->hspend, sz, len + 1);
+ /* hspend will now point to NULL character */
+ eval->hspend += len;
++ return APR_SUCCESS;
+ }
+
+ /*
+ * copy_to_holdbuf
+ */
+-static void copy_to_holdbuf(sed_eval_t *eval, const char* sz)
++static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char* sz)
+ {
+ eval->hspend = eval->holdbuf;
+- append_to_holdbuf(eval, sz);
++ return append_to_holdbuf(eval, sz);
+ }
+
+ /*
+ * append_to_genbuf
+ */
+-static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
++static apr_status_t append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
+ {
+ apr_size_t len = strlen(sz);
+ apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1;
++ apr_status_t rc = 0;
+ if (eval->gsize < reqsize) {
+- grow_gen_buffer(eval, reqsize, gspend);
++ rc = grow_gen_buffer(eval, reqsize, gspend);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ }
+ memcpy(*gspend, sz, len + 1);
+ /* *gspend will now point to NULL character */
+ *gspend += len;
++ return APR_SUCCESS;
+ }
+
+ /*
+ * copy_to_genbuf
+ */
+-static void copy_to_genbuf(sed_eval_t *eval, const char* sz)
++static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char* sz)
+ {
+ apr_size_t len = strlen(sz);
+ apr_size_t reqsize = len + 1;
++ apr_status_t rc = APR_SUCCESS;;
+ if (eval->gsize < reqsize) {
+- grow_gen_buffer(eval, reqsize, NULL);
++ rc = grow_gen_buffer(eval, reqsize, NULL);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ }
+ memcpy(eval->genbuf, sz, len + 1);
++ return rc;
+ }
+
+ /*
+@@ -397,6 +432,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz
+ }
+
+ while (bufsz) {
++ apr_status_t rc = 0;
+ char *n;
+ apr_size_t llen;
+
+@@ -411,7 +447,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz
+ break;
+ }
+
+- appendmem_to_linebuf(eval, buf, llen + 1);
++ rc = appendmem_to_linebuf(eval, buf, llen + 1);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ --eval->lspend;
+ /* replace new line character with NULL */
+ *eval->lspend = '\0';
+@@ -426,7 +465,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz
+
+ /* Save the leftovers for later */
+ if (bufsz) {
+- appendmem_to_linebuf(eval, buf, bufsz);
++ apr_status_t rc = appendmem_to_linebuf(eval, buf, bufsz);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ }
+
+ return APR_SUCCESS;
+@@ -448,6 +490,7 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
+ /* Process leftovers */
+ if (eval->lspend > eval->linebuf) {
+ apr_status_t rv;
++ apr_status_t rc = 0;
+
+ if (eval->lreadyflag) {
+ eval->lreadyflag = 0;
+@@ -457,7 +500,10 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
+ * buffer is not a newline.
+ */
+ /* Assure space for NULL */
+- append_to_linebuf(eval, "", NULL);
++ rc = append_to_linebuf(eval, "", NULL);
++ if (rc != APR_SUCCESS) {
++ return rc;
++ }
+ }
+
+ *eval->lspend = '\0';
+@@ -655,11 +701,15 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
+ sp = eval->genbuf;
+ rp = rhsbuf;
+ sp = place(eval, sp, lp, step_vars->loc1);
++ if (sp == NULL) {
++ return APR_EGENERAL;
++ }
+ while ((c = *rp++) != 0) {
+ if (c == '&') {
+ sp = place(eval, sp, step_vars->loc1, step_vars->loc2);
+- if (sp == NULL)
++ if (sp == NULL) {
+ return APR_EGENERAL;
++ }
+ }
+ else if (c == '\\') {
+ c = *rp++;
+@@ -675,13 +725,19 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
+ *sp++ = c;
+ if (sp >= eval->genbuf + eval->gsize) {
+ /* expand genbuf and set the sp appropriately */
+- grow_gen_buffer(eval, eval->gsize + 1024, &sp);
++ rv = grow_gen_buffer(eval, eval->gsize + 1024, &sp);
++ if (rv != APR_SUCCESS) {
++ return rv;
++ }
+ }
+ }
+ lp = step_vars->loc2;
+ step_vars->loc2 = sp - eval->genbuf + eval->linebuf;
+- append_to_genbuf(eval, lp, &sp);
+- copy_to_linebuf(eval, eval->genbuf, step_vars);
++ rv = append_to_genbuf(eval, lp, &sp);
++ if (rv != APR_SUCCESS) {
++ return rv;
++ }
++ rv = copy_to_linebuf(eval, eval->genbuf, step_vars);
+ return rv;
+ }
+
+@@ -695,7 +751,10 @@ static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2)
+ apr_size_t reqsize = (sp - eval->genbuf) + n + 1;
+
+ if (eval->gsize < reqsize) {
+- grow_gen_buffer(eval, reqsize, &sp);
++ apr_status_t rc = grow_gen_buffer(eval, reqsize, &sp);
++ if (rc != APR_SUCCESS) {
++ return NULL;
++ }
+ }
+ memcpy(sp, al1, n);
+ return sp + n;
+@@ -750,7 +809,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ }
+
+ p1++;
+- copy_to_linebuf(eval, p1, step_vars);
++ rv = copy_to_linebuf(eval, p1, step_vars);
++ if (rv != APR_SUCCESS) return rv;
+ eval->jflag++;
+ break;
+
+@@ -760,21 +820,27 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ break;
+
+ case GCOM:
+- copy_to_linebuf(eval, eval->holdbuf, step_vars);
++ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
++ if (rv != APR_SUCCESS) return rv;
+ break;
+
+ case CGCOM:
+- append_to_linebuf(eval, "\n", step_vars);
+- append_to_linebuf(eval, eval->holdbuf, step_vars);
++ rv = append_to_linebuf(eval, "\n", step_vars);
++ if (rv != APR_SUCCESS) return rv;
++ rv = append_to_linebuf(eval, eval->holdbuf, step_vars);
++ if (rv != APR_SUCCESS) return rv;
+ break;
+
+ case HCOM:
+- copy_to_holdbuf(eval, eval->linebuf);
++ rv = copy_to_holdbuf(eval, eval->linebuf);
++ if (rv != APR_SUCCESS) return rv;
+ break;
+
+ case CHCOM:
+- append_to_holdbuf(eval, "\n");
+- append_to_holdbuf(eval, eval->linebuf);
++ rv = append_to_holdbuf(eval, "\n");
++ if (rv != APR_SUCCESS) return rv;
++ rv = append_to_holdbuf(eval, eval->linebuf);
++ if (rv != APR_SUCCESS) return rv;
+ break;
+
+ case ICOM:
+@@ -896,7 +962,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+- append_to_linebuf(eval, "\n", step_vars);
++ rv = append_to_linebuf(eval, "\n", step_vars);
++ if (rv != APR_SUCCESS) return rv;
+ eval->pending = ipc->next;
+ break;
+
+@@ -970,9 +1037,12 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
+ break;
+
+ case XCOM:
+- copy_to_genbuf(eval, eval->linebuf);
+- copy_to_linebuf(eval, eval->holdbuf, step_vars);
+- copy_to_holdbuf(eval, eval->genbuf);
++ rv = copy_to_genbuf(eval, eval->linebuf);
++ if (rv != APR_SUCCESS) return rv;
++ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
++ if (rv != APR_SUCCESS) return rv;
++ rv = copy_to_holdbuf(eval, eval->genbuf);
++ if (rv != APR_SUCCESS) return rv;
+ break;
+
+ case YCOM:
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-30556.patch b/SOURCES/httpd-2.4.37-CVE-2022-30556.patch
new file mode 100644
index 0000000..971a8d9
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-30556.patch
@@ -0,0 +1,233 @@
+diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
+index ba63584..c1ba74a 100644
+--- a/modules/lua/lua_request.c
++++ b/modules/lua/lua_request.c
+@@ -2193,23 +2193,20 @@ static int lua_websocket_greet(lua_State *L)
+ return 0;
+ }
+
+-static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer,
+- apr_off_t len)
++static apr_status_t lua_websocket_readbytes(conn_rec* c,
++ apr_bucket_brigade *brigade,
++ char* buffer, apr_off_t len)
+ {
+- apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc);
++ apr_size_t delivered;
+ apr_status_t rv;
++
+ rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES,
+ APR_BLOCK_READ, len);
+ if (rv == APR_SUCCESS) {
+- if (!APR_BRIGADE_EMPTY(brigade)) {
+- apr_bucket* bucket = APR_BRIGADE_FIRST(brigade);
+- const char* data = NULL;
+- apr_size_t data_length = 0;
+- rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ);
+- if (rv == APR_SUCCESS) {
+- memcpy(buffer, data, len);
+- }
+- apr_bucket_delete(bucket);
++ delivered = len;
++ rv = apr_brigade_flatten(brigade, buffer, &delivered);
++ if ((rv == APR_SUCCESS) && (delivered < len)) {
++ rv = APR_INCOMPLETE;
+ }
+ }
+ apr_brigade_cleanup(brigade);
+@@ -2239,35 +2236,28 @@ static int lua_websocket_peek(lua_State *L)
+
+ static int lua_websocket_read(lua_State *L)
+ {
+- apr_socket_t *sock;
+ apr_status_t rv;
+ int do_read = 1;
+ int n = 0;
+- apr_size_t len = 1;
+ apr_size_t plen = 0;
+ unsigned short payload_short = 0;
+ apr_uint64_t payload_long = 0;
+ unsigned char *mask_bytes;
+ char byte;
+- int plaintext;
+-
+-
++ apr_bucket_brigade *brigade;
++ conn_rec* c;
++
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
++ c = r->connection;
+
+-
+ mask_bytes = apr_pcalloc(r->pool, 4);
+- sock = ap_get_conn_socket(r->connection);
++
++ brigade = apr_brigade_create(r->pool, c->bucket_alloc);
+
+ while (do_read) {
+ do_read = 0;
+ /* Get opcode and FIN bit */
+- if (plaintext) {
+- rv = apr_socket_recv(sock, &byte, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection, &byte, 1);
+- }
++ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
+ if (rv == APR_SUCCESS) {
+ unsigned char ubyte, fin, opcode, mask, payload;
+ ubyte = (unsigned char)byte;
+@@ -2277,12 +2267,7 @@ static int lua_websocket_read(lua_State *L)
+ opcode = ubyte & 0xf;
+
+ /* Get the payload length and mask bit */
+- if (plaintext) {
+- rv = apr_socket_recv(sock, &byte, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection, &byte, 1);
+- }
++ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
+ if (rv == APR_SUCCESS) {
+ ubyte = (unsigned char)byte;
+ /* Mask is the first bit */
+@@ -2293,40 +2278,25 @@ static int lua_websocket_read(lua_State *L)
+
+ /* Extended payload? */
+ if (payload == 126) {
+- len = 2;
+- if (plaintext) {
+- /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
+- rv = apr_socket_recv(sock, (char*) &payload_short, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection,
+- (char*) &payload_short, 2);
+- }
+- payload_short = ntohs(payload_short);
++ rv = lua_websocket_readbytes(c, brigade,
++ (char*) &payload_short, 2);
+
+- if (rv == APR_SUCCESS) {
+- plen = payload_short;
+- }
+- else {
++ if (rv != APR_SUCCESS) {
+ return 0;
+ }
++
++ plen = ntohs(payload_short);
+ }
+ /* Super duper extended payload? */
+ if (payload == 127) {
+- len = 8;
+- if (plaintext) {
+- rv = apr_socket_recv(sock, (char*) &payload_long, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection,
+- (char*) &payload_long, 8);
+- }
+- if (rv == APR_SUCCESS) {
+- plen = ap_ntoh64(&payload_long);
+- }
+- else {
++ rv = lua_websocket_readbytes(c, brigade,
++ (char*) &payload_long, 8);
++
++ if (rv != APR_SUCCESS) {
+ return 0;
+ }
++
++ plen = ap_ntoh64(&payload_long);
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
+ "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s",
+@@ -2335,46 +2305,27 @@ static int lua_websocket_read(lua_State *L)
+ mask ? "on" : "off",
+ fin ? "This is a final frame" : "more to follow");
+ if (mask) {
+- len = 4;
+- if (plaintext) {
+- rv = apr_socket_recv(sock, (char*) mask_bytes, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection,
+- (char*) mask_bytes, 4);
+- }
++ rv = lua_websocket_readbytes(c, brigade,
++ (char*) mask_bytes, 4);
++
+ if (rv != APR_SUCCESS) {
+ return 0;
+ }
+ }
+ if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
+ apr_size_t remaining = plen;
+- apr_size_t received;
+- apr_off_t at = 0;
+ char *buffer = apr_palloc(r->pool, plen+1);
+ buffer[plen] = 0;
+
+- if (plaintext) {
+- while (remaining > 0) {
+- received = remaining;
+- rv = apr_socket_recv(sock, buffer+at, &received);
+- if (received > 0 ) {
+- remaining -= received;
+- at += received;
+- }
+- }
+- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+- "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack",
+- at);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection, buffer,
+- remaining);
+- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+- "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\
+- "pushed to Lua stack",
+- remaining);
++ rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
++
++ if (rv != APR_SUCCESS) {
++ return 0;
+ }
++
++ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
++ "Websocket: Frame contained %" APR_SIZE_T_FMT \
++ " bytes, pushed to Lua stack", remaining);
+ if (mask) {
+ for (n = 0; n < plen; n++) {
+ buffer[n] ^= mask_bytes[n%4];
+@@ -2386,14 +2337,25 @@ static int lua_websocket_read(lua_State *L)
+ return 2;
+ }
+
+-
+ /* Decide if we need to react to the opcode or not */
+ if (opcode == 0x09) { /* ping */
+ char frame[2];
+- plen = 2;
++ apr_bucket *b;
++
+ frame[0] = 0x8A;
+ frame[1] = 0;
+- apr_socket_send(sock, frame, &plen); /* Pong! */
++
++ /* Pong! */
++ b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
++ APR_BRIGADE_INSERT_TAIL(brigade, b);
++
++ rv = ap_pass_brigade(c->output_filters, brigade);
++ apr_brigade_cleanup(brigade);
++
++ if (rv != APR_SUCCESS) {
++ return 0;
++ }
++
+ do_read = 1;
+ }
+ }
diff --git a/SOURCES/httpd-2.4.37-CVE-2022-31813.patch b/SOURCES/httpd-2.4.37-CVE-2022-31813.patch
new file mode 100644
index 0000000..7fe91d1
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-CVE-2022-31813.patch
@@ -0,0 +1,229 @@
+diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
+index 3d5b220..ec9a414 100644
+--- a/modules/proxy/proxy_util.c
++++ b/modules/proxy/proxy_util.c
+@@ -3621,12 +3621,14 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ char **old_cl_val,
+ char **old_te_val)
+ {
++ int rc = OK;
+ conn_rec *c = r->connection;
+ int counter;
+ char *buf;
++ apr_table_t *saved_headers_in = r->headers_in;
++ const char *saved_host = apr_table_get(saved_headers_in, "Host");
+ const apr_array_header_t *headers_in_array;
+ const apr_table_entry_t *headers_in;
+- apr_table_t *saved_headers_in;
+ apr_bucket *e;
+ int do_100_continue;
+ conn_rec *origin = p_conn->connection;
+@@ -3662,6 +3664,52 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ ap_xlate_proto_to_ascii(buf, strlen(buf));
+ e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
++
++ /*
++ * Make a copy on r->headers_in for the request we make to the backend,
++ * modify the copy in place according to our configuration and connection
++ * handling, use it to fill in the forwarded headers' brigade, and finally
++ * restore the saved/original ones in r->headers_in.
++ *
++ * Note: We need to take r->pool for apr_table_copy as the key / value
++ * pairs in r->headers_in have been created out of r->pool and
++ * p might be (and actually is) a longer living pool.
++ * This would trigger the bad pool ancestry abort in apr_table_copy if
++ * apr is compiled with APR_POOL_DEBUG.
++ *
++ * icing: if p indeed lives longer than r->pool, we should allocate
++ * all new header values from r->pool as well and avoid leakage.
++ */
++ r->headers_in = apr_table_copy(r->pool, saved_headers_in);
++
++ /* Return the original Transfer-Encoding and/or Content-Length values
++ * then drop the headers, they must be set by the proxy handler based
++ * on the actual body being forwarded.
++ */
++ if ((*old_te_val = (char *)apr_table_get(r->headers_in,
++ "Transfer-Encoding"))) {
++ apr_table_unset(r->headers_in, "Transfer-Encoding");
++ }
++ if ((*old_cl_val = (char *)apr_table_get(r->headers_in,
++ "Content-Length"))) {
++ apr_table_unset(r->headers_in, "Content-Length");
++ }
++
++ /* Clear out hop-by-hop request headers not to forward */
++ if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
++ rc = HTTP_BAD_REQUEST;
++ goto cleanup;
++ }
++
++ /* RFC2616 13.5.1 says we should strip these */
++ apr_table_unset(r->headers_in, "Keep-Alive");
++ apr_table_unset(r->headers_in, "Upgrade");
++ apr_table_unset(r->headers_in, "Trailer");
++ apr_table_unset(r->headers_in, "TE");
++
++ /* We used to send `Host: ` always first, so let's keep it that
++ * way. No telling which legacy backend is relying no this.
++ */
+ if (dconf->preserve_host == 0) {
+ if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */
+ if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
+@@ -3683,7 +3731,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ /* don't want to use r->hostname, as the incoming header might have a
+ * port attached
+ */
+- const char* hostname = apr_table_get(r->headers_in,"Host");
++ const char* hostname = saved_host;
+ if (!hostname) {
+ hostname = r->server->server_hostname;
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01092)
+@@ -3697,21 +3745,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ ap_xlate_proto_to_ascii(buf, strlen(buf));
+ e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+-
+- /*
+- * Save the original headers in here and restore them when leaving, since
+- * we will apply proxy purpose only modifications (eg. clearing hop-by-hop
+- * headers, add Via or X-Forwarded-* or Expect...), whereas the originals
+- * will be needed later to prepare the correct response and logging.
+- *
+- * Note: We need to take r->pool for apr_table_copy as the key / value
+- * pairs in r->headers_in have been created out of r->pool and
+- * p might be (and actually is) a longer living pool.
+- * This would trigger the bad pool ancestry abort in apr_table_copy if
+- * apr is compiled with APR_POOL_DEBUG.
+- */
+- saved_headers_in = r->headers_in;
+- r->headers_in = apr_table_copy(r->pool, saved_headers_in);
++ apr_table_unset(r->headers_in, "Host");
+
+ /* handle Via */
+ if (conf->viaopt == via_block) {
+@@ -3778,8 +3812,6 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ */
+ if (dconf->add_forwarded_headers) {
+ if (PROXYREQ_REVERSE == r->proxyreq) {
+- const char *buf;
+-
+ /* Add X-Forwarded-For: so that the upstream has a chance to
+ * determine, where the original request came from.
+ */
+@@ -3789,8 +3821,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ /* Add X-Forwarded-Host: so that upstream knows what the
+ * original request hostname was.
+ */
+- if ((buf = apr_table_get(r->headers_in, "Host"))) {
+- apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf);
++ if (saved_host) {
++ apr_table_mergen(r->headers_in, "X-Forwarded-Host",
++ saved_host);
+ }
+
+ /* Add X-Forwarded-Server: so that upstream knows what the
+@@ -3802,10 +3835,27 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ }
+ }
+
++ /* Do we want to strip Proxy-Authorization ?
++ * If we haven't used it, then NO
++ * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
++ * So let's make it configurable by env.
++ */
++ if (r->user != NULL /* we've authenticated */
++ && !apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
++ apr_table_unset(r->headers_in, "Proxy-Authorization");
++ }
++
++ /* for sub-requests, ignore freshness/expiry headers */
++ if (r->main) {
++ apr_table_unset(r->headers_in, "If-Match");
++ apr_table_unset(r->headers_in, "If-Modified-Since");
++ apr_table_unset(r->headers_in, "If-Range");
++ apr_table_unset(r->headers_in, "If-Unmodified-Since");
++ apr_table_unset(r->headers_in, "If-None-Match");
++ }
++
++ /* run hook to fixup the request we are about to send */
+ proxy_run_fixups(r);
+- if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
+- return HTTP_BAD_REQUEST;
+- }
+
+ creds = apr_table_get(r->notes, "proxy-basic-creds");
+ if (creds) {
+@@ -3817,55 +3867,8 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ headers_in = (const apr_table_entry_t *) headers_in_array->elts;
+ for (counter = 0; counter < headers_in_array->nelts; counter++) {
+ if (headers_in[counter].key == NULL
+- || headers_in[counter].val == NULL
+-
+- /* Already sent */
+- || !strcasecmp(headers_in[counter].key, "Host")
+-
+- /* Clear out hop-by-hop request headers not to send
+- * RFC2616 13.5.1 says we should strip these headers
+- */
+- || !strcasecmp(headers_in[counter].key, "Keep-Alive")
+- || !strcasecmp(headers_in[counter].key, "TE")
+- || !strcasecmp(headers_in[counter].key, "Trailer")
+- || !strcasecmp(headers_in[counter].key, "Upgrade")
+-
+- ) {
+- continue;
+- }
+- /* Do we want to strip Proxy-Authorization ?
+- * If we haven't used it, then NO
+- * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
+- * So let's make it configurable by env.
+- */
+- if (!strcasecmp(headers_in[counter].key,"Proxy-Authorization")) {
+- if (r->user != NULL) { /* we've authenticated */
+- if (!apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
+- continue;
+- }
+- }
+- }
+-
+- /* Skip Transfer-Encoding and Content-Length for now.
+- */
+- if (!strcasecmp(headers_in[counter].key, "Transfer-Encoding")) {
+- *old_te_val = headers_in[counter].val;
+- continue;
+- }
+- if (!strcasecmp(headers_in[counter].key, "Content-Length")) {
+- *old_cl_val = headers_in[counter].val;
+- continue;
+- }
+-
+- /* for sub-requests, ignore freshness/expiry headers */
+- if (r->main) {
+- if ( !strcasecmp(headers_in[counter].key, "If-Match")
+- || !strcasecmp(headers_in[counter].key, "If-Modified-Since")
+- || !strcasecmp(headers_in[counter].key, "If-Range")
+- || !strcasecmp(headers_in[counter].key, "If-Unmodified-Since")
+- || !strcasecmp(headers_in[counter].key, "If-None-Match")) {
+- continue;
+- }
++ || headers_in[counter].val == NULL) {
++ continue;
+ }
+
+ buf = apr_pstrcat(p, headers_in[counter].key, ": ",
+@@ -3876,11 +3879,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+ }
+
+- /* Restore the original headers in (see comment above),
+- * we won't modify them anymore.
+- */
++cleanup:
+ r->headers_in = saved_headers_in;
+- return OK;
++ return rc;
+ }
+
+ PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc,
diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec
index 1c02a62..c97fc9a 100644
--- a/SPECS/httpd.spec
+++ b/SPECS/httpd.spec
@@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.37
-Release: 47%{?dist}
+Release: 51%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source2: httpd.logrotate
@@ -214,6 +214,31 @@ Patch220: httpd-2.4.37-CVE-2021-33193.patch
Patch221: httpd-2.4.37-CVE-2021-44790.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2034672
Patch222: httpd-2.4.37-CVE-2021-44224.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2064321
+Patch223: httpd-2.4.37-CVE-2022-22720.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1966738
+Patch224: httpd-2.4.37-CVE-2020-13950.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2064322
+Patch225: httpd-2.4.37-CVE-2022-22719.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2064320
+Patch226: httpd-2.4.37-CVE-2022-22721.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2065324
+Patch227: httpd-2.4.37-CVE-2022-23943.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095002
+Patch228: httpd-2.4.37-CVE-2022-28614.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095006
+Patch229: httpd-2.4.37-CVE-2022-28615.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095015
+Patch230: httpd-2.4.37-CVE-2022-30522.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095018
+Patch231: httpd-2.4.37-CVE-2022-30556.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095020
+Patch232: httpd-2.4.37-CVE-2022-31813.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095012
+Patch233: httpd-2.4.37-CVE-2022-29404.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2094997
+Patch234: httpd-2.4.37-CVE-2022-26377.patch
+
License: ASL 2.0
Group: System Environment/Daemons
@@ -418,6 +443,18 @@ interface for storing and accessing per-user session data.
%patch220 -p1 -b .CVE-2021-33193
%patch221 -p1 -b .CVE-2021-44790
%patch222 -p1 -b .CVE-2021-44224
+%patch223 -p1 -b .CVE-2022-22720
+%patch224 -p1 -b .CVE-2020-13950
+%patch225 -p1 -b .CVE-2022-22719
+%patch226 -p1 -b .CVE-2022-22721
+%patch227 -p1 -b .CVE-2022-23943
+%patch228 -p1 -b .CVE-2022-28614
+%patch229 -p1 -b .CVE-2022-28615
+%patch230 -p1 -b .CVE-2022-30522
+%patch231 -p1 -b .CVE-2022-30556
+%patch232 -p1 -b .CVE-2022-31813
+%patch233 -p1 -b .CVE-2022-29404
+%patch234 -p1 -b .CVE-2022-26377
# Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@@ -923,8 +960,37 @@ rm -rf $RPM_BUILD_ROOT
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
-* Tue Mar 29 2022 CentOS Sources - 2.4.37-47.el8.centos
-- Apply debranding changes
+* Mon Jul 25 2022 Luboš Uhliarik - 2.4.37-51
+- Resolves: #2097015 - CVE-2022-28614 httpd:2.4/httpd: out-of-bounds read via
+ ap_rwrite()
+- Resolves: #2097031 - CVE-2022-28615 httpd:2.4/httpd: out-of-bounds read in
+ ap_strcmp_match()
+- Resolves: #2097458 - CVE-2022-30522 httpd:2.4/httpd: mod_sed: DoS
+ vulnerability
+- Resolves: #2097480 - CVE-2022-30556 httpd:2.4/httpd: mod_lua: Information
+ disclosure with websockets
+- Resolves: #2098247 - CVE-2022-31813 httpd:2.4/httpd: mod_proxy:
+ X-Forwarded-For dropped by hop-by-hop mechanism
+- Resolves: #2097451 - CVE-2022-29404 httpd:2.4/httpd: mod_lua: DoS in
+ r:parsebody
+- Resolves: #2096997 - CVE-2022-26377 httpd:2.4/httpd: mod_proxy_ajp: Possible
+ request smuggling
+
+* Tue Jun 21 2022 Luboš Uhliarik - 2.4.37-50
+- Resolves: #2065237 - CVE-2022-22719 httpd:2.4/httpd: mod_lua: Use of
+ uninitialized value of in r:parsebody
+- Resolves: #2065267 - CVE-2022-22721 httpd:2.4/httpd: core: Possible buffer
+ overflow with very large or unlimited LimitXMLRequestBody
+- Resolves: #2065324 - CVE-2022-23943 httpd:2.4/httpd: mod_sed: Read/write
+ beyond bounds
+
+* Fri Jun 10 2022 Luboš Uhliarik - 2.4.37-49
+- Resolves: #2090848 - CVE-2020-13950 httpd:2.4/httpd: mod_proxy NULL pointer
+ dereference
+
+* Mon Mar 21 2022 Luboš Uhliarik - 2.4.37-48
+- Resolves: #2065249 - CVE-2022-22720 httpd:2.4/httpd: HTTP request smuggling
+ vulnerability in Apache HTTP Server 2.4.52 and earlier
* Thu Jan 20 2022 Luboš Uhliarik - 2.4.37-47
- Resolves: #2035030 - CVE-2021-44224 httpd:2.4/httpd: possible NULL dereference