+Date: Wed, 1 Jun 2022 12:34:16 +0000
+Subject: [PATCH] Merge r1901500 from trunk:
+
+handle large writes in ap_rputs
+
+
+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901501 13f79535-47bb-0310-9956-ffa450edef68
+---
+ include/http_protocol.h | 22 +++++++++++++++++++++-
+ server/protocol.c | 3 +++
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/include/http_protocol.h b/include/http_protocol.h
+index 20bd2022266..94c481e5f43 100644
+--- a/include/http_protocol.h
++++ b/include/http_protocol.h
+@@ -475,7 +475,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 298f61e1fb8..7adc7f75c10 100644
+--- a/server/protocol.c
++++ b/server/protocol.c
+@@ -2128,6 +2128,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.53-CVE-2022-28615.patch b/SOURCES/httpd-2.4.53-CVE-2022-28615.patch
new file mode 100644
index 0000000..75a3d0f
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-CVE-2022-28615.patch
@@ -0,0 +1,22 @@
+diff --git a/server/util.c b/server/util.c
+index 604be1a..6808164 100644
+--- a/server/util.c
++++ b/server/util.c
+@@ -185,7 +185,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 (expected[y] == '*') {
+@@ -209,7 +209,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.53-CVE-2022-29404.patch b/SOURCES/httpd-2.4.53-CVE-2022-29404.patch
new file mode 100644
index 0000000..df4f70f
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-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 bb6b90a..d14aed4 100644
+--- a/docs/manual/mod/core.html.en
++++ b/docs/manual/mod/core.html.en
+@@ -2796,16 +2796,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
+@@ -2831,12 +2831,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 ee7b1e3..233d234 100644
+--- a/docs/manual/mod/mod_proxy.html.en
++++ b/docs/manual/mod/mod_proxy.html.en
+@@ -463,9 +463,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 43e8c6d..33c78f3 100644
+--- a/modules/http/http_filters.c
++++ b/modules/http/http_filters.c
+@@ -1703,6 +1703,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;
+@@ -1738,6 +1739,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/proxy_util.c b/modules/proxy/proxy_util.c
+index bc86253..85f2f9c 100644
+--- a/modules/proxy/proxy_util.c
++++ b/modules/proxy/proxy_util.c
+@@ -4260,13 +4260,10 @@ PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r,
+ apr_bucket *e;
+ apr_off_t bytes, fsize = 0;
+ apr_file_t *tmpfile = NULL;
+- apr_off_t limit;
+
+ *bytes_spooled = 0;
+ body_brigade = apr_brigade_create(p, bucket_alloc);
+
+- limit = ap_get_limit_req_body(r);
+-
+ do {
+ if (APR_BRIGADE_EMPTY(input_brigade)) {
+ rv = ap_proxy_read_input(r, backend, input_brigade,
+@@ -4284,17 +4281,6 @@ PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r,
+ 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 3d44e0e..682259f 100644
+--- a/server/core.c
++++ b/server/core.c
+@@ -71,7 +71,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.53-CVE-2022-30522.patch b/SOURCES/httpd-2.4.53-CVE-2022-30522.patch
new file mode 100644
index 0000000..50e0ea3
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-CVE-2022-30522.patch
@@ -0,0 +1,557 @@
+From db47781128e42bd49f55076665b3f6ca4e2bc5e2 Mon Sep 17 00:00:00 2001
+From: Eric Covener
+Date: Wed, 1 Jun 2022 12:50:40 +0000
+Subject: [PATCH] Merge r1901506 from trunk:
+
+limit mod_sed memory use
+
+Resync mod_sed.c with trunk due to merge conflicts.
+
+
+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901509 13f79535-47bb-0310-9956-ffa450edef68
+---
+ modules/filters/mod_sed.c | 75 ++++++++----------
+ modules/filters/sed1.c | 158 +++++++++++++++++++++++++++-----------
+ 2 files changed, 147 insertions(+), 86 deletions(-)
+
+diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c
+index 4bdb4ce33ae..12cb04a20f9 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)
+ {
+@@ -277,7 +277,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;
+@@ -302,9 +302,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.
+@@ -326,63 +326,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);
+@@ -433,7 +422,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
+@@ -475,8 +464,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 67a8d06515e..047f49ba131 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.53-CVE-2022-30556.patch b/SOURCES/httpd-2.4.53-CVE-2022-30556.patch
new file mode 100644
index 0000000..1b8a112
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-CVE-2022-30556.patch
@@ -0,0 +1,246 @@
+From 3a561759fcb37af179585adb8478922dc9bc6a85 Mon Sep 17 00:00:00 2001
+From: Eric Covener
+Date: Wed, 1 Jun 2022 12:36:39 +0000
+Subject: [PATCH] Merge r1901502 from trunk:
+
+use filters consistently
+
+
+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901503 13f79535-47bb-0310-9956-ffa450edef68
+---
+ modules/lua/lua_request.c | 144 ++++++++++++++------------------------
+ 1 file changed, 53 insertions(+), 91 deletions(-)
+
+diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
+index a3e3b613bc9..2ec453e86b4 100644
+--- a/modules/lua/lua_request.c
++++ b/modules/lua/lua_request.c
+@@ -2227,23 +2227,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);
+@@ -2273,35 +2270,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;
+@@ -2311,12 +2301,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 */
+@@ -2327,40 +2312,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",
+@@ -2369,46 +2339,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];
+@@ -2420,14 +2371,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.53-CVE-2022-31813.patch b/SOURCES/httpd-2.4.53-CVE-2022-31813.patch
new file mode 100644
index 0000000..325b5cd
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-CVE-2022-31813.patch
@@ -0,0 +1,230 @@
+diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
+index 3af5aed..bc86253 100644
+--- a/modules/proxy/proxy_util.c
++++ b/modules/proxy/proxy_util.c
+@@ -3854,12 +3854,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;
+@@ -3896,6 +3898,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) {
+@@ -3917,7 +3965,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)
+@@ -3931,21 +3979,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) {
+@@ -4012,8 +4046,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.
+ */
+@@ -4023,8 +4055,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
+@@ -4036,11 +4069,28 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
+ }
+ }
+
+- proxy_run_fixups(r);
+- if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
+- return HTTP_BAD_REQUEST;
++ /* 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);
++
+ creds = apr_table_get(r->notes, "proxy-basic-creds");
+ if (creds) {
+ apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
+@@ -4051,55 +4101,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 */
+- || !ap_cstr_casecmp(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
+- */
+- || !ap_cstr_casecmp(headers_in[counter].key, "Keep-Alive")
+- || !ap_cstr_casecmp(headers_in[counter].key, "TE")
+- || !ap_cstr_casecmp(headers_in[counter].key, "Trailer")
+- || !ap_cstr_casecmp(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 (!ap_cstr_casecmp(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 (!ap_cstr_casecmp(headers_in[counter].key, "Transfer-Encoding")) {
+- *old_te_val = headers_in[counter].val;
+- continue;
+- }
+- if (!ap_cstr_casecmp(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 ( !ap_cstr_casecmp(headers_in[counter].key, "If-Match")
+- || !ap_cstr_casecmp(headers_in[counter].key, "If-Modified-Since")
+- || !ap_cstr_casecmp(headers_in[counter].key, "If-Range")
+- || !ap_cstr_casecmp(headers_in[counter].key, "If-Unmodified-Since")
+- || !ap_cstr_casecmp(headers_in[counter].key, "If-None-Match")) {
+- continue;
+- }
++ || headers_in[counter].val == NULL) {
++ continue;
+ }
+
+ buf = apr_pstrcat(p, headers_in[counter].key, ": ",
+@@ -4110,11 +4113,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_prefetch_input(request_rec *r,
diff --git a/SOURCES/httpd-2.4.53-detect-systemd.patch b/SOURCES/httpd-2.4.53-detect-systemd.patch
new file mode 100644
index 0000000..d501b06
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-detect-systemd.patch
@@ -0,0 +1,45 @@
+diff --git a/Makefile.in b/Makefile.in
+index a2e9c82..bd8045c 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test
+
+ PROGRAM_NAME = $(progname)
+ PROGRAM_SOURCES = modules.c
+-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
+ PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
+ PROGRAM_DEPENDENCIES = \
+ server/libmain.la \
+diff --git a/acinclude.m4 b/acinclude.m4
+index 97484c9..05abe18 100644
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -631,6 +631,7 @@ case $host in
+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
+ AC_MSG_WARN([Your system does not support systemd.])
+ else
++ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS])
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
+ fi
+ fi
+diff --git a/configure.in b/configure.in
+index cf437fe..521fc45 100644
+--- a/configure.in
++++ b/configure.in
+@@ -239,6 +239,7 @@ if test "x$PCRE_CONFIG" != "x"; then
+ AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG])
+ APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`])
+ APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`])
++ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)])
+ else
+ AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/])
+ fi
+@@ -734,6 +735,7 @@ APACHE_SUBST(OS_DIR)
+ APACHE_SUBST(BUILTIN_LIBS)
+ APACHE_SUBST(SHLIBPATH_VAR)
+ APACHE_SUBST(OS_SPECIFIC_VARS)
++APACHE_SUBST(HTTPD_LIBS)
+
+ PRE_SHARED_CMDS='echo ""'
+ POST_SHARED_CMDS='echo ""'
diff --git a/SOURCES/httpd-2.4.53-icons.patch b/SOURCES/httpd-2.4.53-icons.patch
new file mode 100644
index 0000000..efc0c4d
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-icons.patch
@@ -0,0 +1,49 @@
+diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in
+index 51b02ed..93a2b87 100644
+--- a/docs/conf/extra/httpd-autoindex.conf.in
++++ b/docs/conf/extra/httpd-autoindex.conf.in
+@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort
+ Alias /icons/ "@exp_iconsdir@/"
+
+
+- Options Indexes MultiViews
++ Options Indexes MultiViews FollowSymlinks
+ AllowOverride None
+ Require all granted
+
+@@ -37,6 +37,7 @@ AddIconByType (TXT,/icons/text.gif) text/*
+ AddIconByType (IMG,/icons/image2.gif) image/*
+ AddIconByType (SND,/icons/sound2.gif) audio/*
+ AddIconByType (VID,/icons/movie.gif) video/*
++AddIconByType /icons/bomb.gif application/x-coredump
+
+ AddIcon /icons/binary.gif .bin .exe
+ AddIcon /icons/binhex.gif .hqx
+@@ -53,7 +54,6 @@ AddIcon /icons/dvi.gif .dvi
+ AddIcon /icons/uuencoded.gif .uu
+ AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
+ AddIcon /icons/tex.gif .tex
+-AddIcon /icons/bomb.gif core
+
+ AddIcon /icons/back.gif ..
+ AddIcon /icons/hand.right.gif README
+diff --git a/docs/conf/magic b/docs/conf/magic
+index bc891d9..9a41b44 100644
+--- a/docs/conf/magic
++++ b/docs/conf/magic
+@@ -383,3 +383,15 @@
+ 4 string moov video/quicktime
+ 4 string mdat video/quicktime
+
++
++#------------------------------------------------------------------------------
++# application/x-coredump for LE/BE ELF
++#
++0 string \177ELF
++>5 byte 1
++>16 leshort 4 application/x-coredump
++
++0 string \177ELF
++>5 byte 2
++>16 beshort 4 application/x-coredump
++
diff --git a/SOURCES/httpd-2.4.53-r1878890.patch b/SOURCES/httpd-2.4.53-r1878890.patch
new file mode 100644
index 0000000..945c498
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-r1878890.patch
@@ -0,0 +1,116 @@
+diff --git a/include/util_ldap.h b/include/util_ldap.h
+index 28e0760..edb8a81 100644
+--- a/include/util_ldap.h
++++ b/include/util_ldap.h
+@@ -32,7 +32,6 @@
+ #if APR_MAJOR_VERSION < 2
+ /* The LDAP API is currently only present in APR 1.x */
+ #include "apr_ldap.h"
+-#include "apr_ldap_rebind.h"
+ #else
+ #define APR_HAS_LDAP 0
+ #endif
+diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
+index 4d92ec9..864bd62 100644
+--- a/modules/ldap/util_ldap.c
++++ b/modules/ldap/util_ldap.c
+@@ -154,6 +154,38 @@ static int util_ldap_handler(request_rec *r)
+ return OK;
+ }
+
++/* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use
++ * a simpler rebind callback than the implementation in APR-util.
++ * Testing for API version >= 3001 appears safe although OpenLDAP
++ * 2.1.x (API version = 2004) also has the 3-arg API. */
++#if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001
++
++#define uldap_rebind_init(p) APR_SUCCESS /* noop */
++
++static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request,
++ ber_int_t msgid, void *params)
++{
++ util_ldap_connection_t *ldc = params;
++
++ return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE);
++}
++
++static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc)
++{
++ ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc);
++ return APR_SUCCESS;
++}
++
++#else /* !APR_HAS_OPENLDAP_LDAPSDK */
++
++#define USE_APR_LDAP_REBIND
++#include
++
++#define uldap_rebind_init(p) apr_ldap_rebind_init(p)
++#define uldap_rebind_add(ldc) apr_ldap_rebind_add((ldc)->rebind_pool, \
++ (ldc)->ldap, (ldc)->binddn, \
++ (ldc)->bindpw)
++#endif
+
+
+ /* ------------------------------------------------------------------ */
+@@ -195,6 +227,13 @@ static apr_status_t uldap_connection_unbind(void *param)
+ util_ldap_connection_t *ldc = param;
+
+ if (ldc) {
++#ifdef USE_APR_LDAP_REBIND
++ /* forget the rebind info for this conn */
++ if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
++ apr_pool_clear(ldc->rebind_pool);
++ }
++#endif
++
+ if (ldc->ldap) {
+ if (ldc->r) {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc);
+@@ -203,12 +242,6 @@ static apr_status_t uldap_connection_unbind(void *param)
+ ldc->ldap = NULL;
+ }
+ ldc->bound = 0;
+-
+- /* forget the rebind info for this conn */
+- if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
+- apr_ldap_rebind_remove(ldc->ldap);
+- apr_pool_clear(ldc->rebind_pool);
+- }
+ }
+
+ return APR_SUCCESS;
+@@ -344,7 +377,7 @@ static int uldap_connection_init(request_rec *r,
+
+ if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
+ /* Now that we have an ldap struct, add it to the referral list for rebinds. */
+- rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
++ rc = uldap_rebind_add(ldc);
+ if (rc != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277)
+ "LDAP: Unable to add rebind cross reference entry. Out of memory?");
+@@ -870,6 +903,7 @@ static util_ldap_connection_t *
+ /* whether or not to keep this connection in the pool when it's returned */
+ l->keep = (st->connection_pool_ttl == 0) ? 0 : 1;
+
++#ifdef USE_APR_LDAP_REBIND
+ if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
+ if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286)
+@@ -881,6 +915,7 @@ static util_ldap_connection_t *
+ }
+ apr_pool_tag(l->rebind_pool, "util_ldap_rebind");
+ }
++#endif
+
+ if (p) {
+ p->next = l;
+@@ -3068,7 +3103,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
+ }
+
+ /* Initialize the rebind callback's cross reference list. */
+- apr_ldap_rebind_init (p);
++ (void) uldap_rebind_init(p);
+
+ #ifdef AP_LDAP_OPT_DEBUG
+ if (st->debug_level > 0) {
diff --git a/SOURCES/httpd-2.4.53-r1901199.patch b/SOURCES/httpd-2.4.53-r1901199.patch
new file mode 100644
index 0000000..978e653
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-r1901199.patch
@@ -0,0 +1,336 @@
+--- a/server/mpm/event/event.c 2022/05/24 08:59:30 1901198
++++ b/server/mpm/event/event.c 2022/05/24 09:00:19 1901199
+@@ -379,7 +379,7 @@
+ * We use this value to optimize routines that have to scan the entire
+ * scoreboard.
+ */
+- int max_daemons_limit;
++ int max_daemon_used;
+
+ /*
+ * All running workers, active and shutting down, including those that
+@@ -645,7 +645,7 @@
+ *rv = APR_SUCCESS;
+ switch (query_code) {
+ case AP_MPMQ_MAX_DAEMON_USED:
+- *result = retained->max_daemons_limit;
++ *result = retained->max_daemon_used;
+ break;
+ case AP_MPMQ_IS_THREADED:
+ *result = AP_MPMQ_STATIC;
+@@ -696,14 +696,32 @@
+ return OK;
+ }
+
+-static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
++static void event_note_child_stopped(int slot, pid_t pid, ap_generation_t gen)
+ {
+- if (childnum != -1) { /* child had a scoreboard slot? */
+- ap_run_child_status(ap_server_conf,
+- ap_scoreboard_image->parent[childnum].pid,
+- ap_scoreboard_image->parent[childnum].generation,
+- childnum, MPM_CHILD_EXITED);
+- ap_scoreboard_image->parent[childnum].pid = 0;
++ if (slot != -1) { /* child had a scoreboard slot? */
++ process_score *ps = &ap_scoreboard_image->parent[slot];
++ int i;
++
++ pid = ps->pid;
++ gen = ps->generation;
++ for (i = 0; i < threads_per_child; i++) {
++ ap_update_child_status_from_indexes(slot, i, SERVER_DEAD, NULL);
++ }
++ ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_EXITED);
++ if (ps->quiescing != 2) { /* vs perform_idle_server_maintenance() */
++ retained->active_daemons--;
++ }
++ retained->total_daemons--;
++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
++ "Child %d stopped: pid %d, gen %d, "
++ "active %d/%d, total %d/%d/%d, quiescing %d",
++ slot, (int)pid, (int)gen,
++ retained->active_daemons, active_daemons_limit,
++ retained->total_daemons, retained->max_daemon_used,
++ server_limit, ps->quiescing);
++ ps->not_accepting = 0;
++ ps->quiescing = 0;
++ ps->pid = 0;
+ }
+ else {
+ ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
+@@ -713,9 +731,19 @@
+ static void event_note_child_started(int slot, pid_t pid)
+ {
+ ap_generation_t gen = retained->mpm->my_generation;
++
++ retained->total_daemons++;
++ retained->active_daemons++;
+ ap_scoreboard_image->parent[slot].pid = pid;
+ ap_scoreboard_image->parent[slot].generation = gen;
+ ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_STARTED);
++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
++ "Child %d started: pid %d, gen %d, "
++ "active %d/%d, total %d/%d/%d",
++ slot, (int)pid, (int)gen,
++ retained->active_daemons, active_daemons_limit,
++ retained->total_daemons, retained->max_daemon_used,
++ server_limit);
+ }
+
+ static const char *event_get_name(void)
+@@ -737,7 +765,7 @@
+ }
+
+ if (one_process) {
+- event_note_child_killed(/* slot */ 0, 0, 0);
++ event_note_child_stopped(/* slot */ 0, 0, 0);
+ }
+
+ exit(code);
+@@ -2712,8 +2740,8 @@
+ {
+ int pid;
+
+- if (slot + 1 > retained->max_daemons_limit) {
+- retained->max_daemons_limit = slot + 1;
++ if (slot + 1 > retained->max_daemon_used) {
++ retained->max_daemon_used = slot + 1;
+ }
+
+ if (ap_scoreboard_image->parent[slot].pid != 0) {
+@@ -2781,11 +2809,7 @@
+ return -1;
+ }
+
+- ap_scoreboard_image->parent[slot].quiescing = 0;
+- ap_scoreboard_image->parent[slot].not_accepting = 0;
+ event_note_child_started(slot, pid);
+- retained->active_daemons++;
+- retained->total_daemons++;
+ return 0;
+ }
+
+@@ -2805,7 +2829,8 @@
+ }
+ }
+
+-static void perform_idle_server_maintenance(int child_bucket)
++static void perform_idle_server_maintenance(int child_bucket,
++ int *max_daemon_used)
+ {
+ int num_buckets = retained->mpm->num_buckets;
+ int idle_thread_count = 0;
+@@ -2821,7 +2846,7 @@
+ /* We only care about child_bucket in this call */
+ continue;
+ }
+- if (i >= retained->max_daemons_limit &&
++ if (i >= retained->max_daemon_used &&
+ free_length == retained->idle_spawn_rate[child_bucket]) {
+ /* short cut if all active processes have been examined and
+ * enough empty scoreboard slots have been found
+@@ -2835,6 +2860,13 @@
+ if (ps->quiescing == 1) {
+ ps->quiescing = 2;
+ retained->active_daemons--;
++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
++ "Child %d quiescing: pid %d, gen %d, "
++ "active %d/%d, total %d/%d/%d",
++ i, (int)ps->pid, (int)ps->generation,
++ retained->active_daemons, active_daemons_limit,
++ retained->total_daemons, retained->max_daemon_used,
++ server_limit);
+ }
+ for (j = 0; j < threads_per_child; j++) {
+ int status = ap_scoreboard_image->servers[i][j].status;
+@@ -2863,8 +2895,9 @@
+ free_slots[free_length++] = i;
+ }
+ }
+-
+- retained->max_daemons_limit = last_non_dead + 1;
++ if (*max_daemon_used < last_non_dead + 1) {
++ *max_daemon_used = last_non_dead + 1;
++ }
+
+ if (retained->sick_child_detected) {
+ if (had_healthy_child) {
+@@ -2893,6 +2926,10 @@
+ }
+ }
+
++ AP_DEBUG_ASSERT(retained->active_daemons <= retained->total_daemons
++ && retained->total_daemons <= retained->max_daemon_used
++ && retained->max_daemon_used <= server_limit);
++
+ if (idle_thread_count > max_spare_threads / num_buckets) {
+ /*
+ * Child processes that we ask to shut down won't die immediately
+@@ -2915,13 +2952,12 @@
+ active_daemons_limit));
+ ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
+ "%shutting down one child: "
+- "active daemons %d / active limit %d / "
+- "total daemons %d / ServerLimit %d / "
+- "idle threads %d / max workers %d",
++ "active %d/%d, total %d/%d/%d, "
++ "idle threads %d, max workers %d",
+ (do_kill) ? "S" : "Not s",
+ retained->active_daemons, active_daemons_limit,
+- retained->total_daemons, server_limit,
+- idle_thread_count, max_workers);
++ retained->total_daemons, retained->max_daemon_used,
++ server_limit, idle_thread_count, max_workers);
+ if (do_kill) {
+ ap_mpm_podx_signal(all_buckets[child_bucket].pod,
+ AP_MPM_PODX_GRACEFUL);
+@@ -2970,10 +3006,14 @@
+ else {
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
+ "server is at active daemons limit, spawning "
+- "of %d children cancelled: %d/%d active, "
+- "rate %d", free_length,
++ "of %d children cancelled: active %d/%d, "
++ "total %d/%d/%d, rate %d", free_length,
+ retained->active_daemons, active_daemons_limit,
+- retained->idle_spawn_rate[child_bucket]);
++ retained->total_daemons, retained->max_daemon_used,
++ server_limit, retained->idle_spawn_rate[child_bucket]);
++ /* reset the spawning rate and prevent its growth below */
++ retained->idle_spawn_rate[child_bucket] = 1;
++ ++retained->hold_off_on_exponential_spawning;
+ free_length = 0;
+ }
+ }
+@@ -2989,12 +3029,13 @@
+ retained->total_daemons);
+ }
+ for (i = 0; i < free_length; ++i) {
+- ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
+- "Spawning new child: slot %d active / "
+- "total daemons: %d/%d",
+- free_slots[i], retained->active_daemons,
+- retained->total_daemons);
+- make_child(ap_server_conf, free_slots[i], child_bucket);
++ int slot = free_slots[i];
++ if (make_child(ap_server_conf, slot, child_bucket) < 0) {
++ continue;
++ }
++ if (*max_daemon_used < slot + 1) {
++ *max_daemon_used = slot + 1;
++ }
+ }
+ /* the next time around we want to spawn twice as many if this
+ * wasn't good enough, but not if we've just done a graceful
+@@ -3016,6 +3057,7 @@
+ static void server_main_loop(int remaining_children_to_start)
+ {
+ int num_buckets = retained->mpm->num_buckets;
++ int max_daemon_used = 0;
+ int child_slot;
+ apr_exit_why_e exitwhy;
+ int status, processed_status;
+@@ -3061,19 +3103,8 @@
+ }
+ /* non-fatal death... note that it's gone in the scoreboard. */
+ if (child_slot >= 0) {
+- process_score *ps;
++ event_note_child_stopped(child_slot, 0, 0);
+
+- for (i = 0; i < threads_per_child; i++)
+- ap_update_child_status_from_indexes(child_slot, i,
+- SERVER_DEAD, NULL);
+-
+- event_note_child_killed(child_slot, 0, 0);
+- ps = &ap_scoreboard_image->parent[child_slot];
+- if (ps->quiescing != 2)
+- retained->active_daemons--;
+- ps->quiescing = 0;
+- /* NOTE: We don't dec in the (child_slot < 0) case! */
+- retained->total_daemons--;
+ if (processed_status == APEXIT_CHILDSICK) {
+ /* resource shortage, minimize the fork rate */
+ retained->idle_spawn_rate[child_slot % num_buckets] = 1;
+@@ -3123,9 +3154,11 @@
+ continue;
+ }
+
++ max_daemon_used = 0;
+ for (i = 0; i < num_buckets; i++) {
+- perform_idle_server_maintenance(i);
++ perform_idle_server_maintenance(i, &max_daemon_used);
+ }
++ retained->max_daemon_used = max_daemon_used;
+ }
+ }
+
+@@ -3213,7 +3246,7 @@
+ AP_MPM_PODX_RESTART);
+ }
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+- event_note_child_killed);
++ event_note_child_stopped);
+
+ if (!child_fatal) {
+ /* cleanup pid file on normal shutdown */
+@@ -3239,7 +3272,7 @@
+ ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
+ AP_MPM_PODX_GRACEFUL);
+ }
+- ap_relieve_child_processes(event_note_child_killed);
++ ap_relieve_child_processes(event_note_child_stopped);
+
+ if (!child_fatal) {
+ /* cleanup pid file on normal shutdown */
+@@ -3261,10 +3294,10 @@
+ apr_sleep(apr_time_from_sec(1));
+
+ /* Relieve any children which have now exited */
+- ap_relieve_child_processes(event_note_child_killed);
++ ap_relieve_child_processes(event_note_child_stopped);
+
+ active_children = 0;
+- for (index = 0; index < retained->max_daemons_limit; ++index) {
++ for (index = 0; index < retained->max_daemon_used; ++index) {
+ if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
+ active_children = 1;
+ /* Having just one child is enough to stay around */
+@@ -3282,7 +3315,7 @@
+ ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
+ AP_MPM_PODX_RESTART);
+ }
+- ap_reclaim_child_processes(1, event_note_child_killed);
++ ap_reclaim_child_processes(1, event_note_child_stopped);
+
+ return DONE;
+ }
+@@ -3302,8 +3335,7 @@
+
+ if (!retained->mpm->is_ungraceful) {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
+- AP_SIG_GRACEFUL_STRING
+- " received. Doing graceful restart");
++ AP_SIG_GRACEFUL_STRING " received. Doing graceful restart");
+ /* wake up the children...time to die. But we'll have more soon */
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
+@@ -3316,6 +3348,8 @@
+
+ }
+ else {
++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
++ "SIGHUP received. Attempting to restart");
+ /* Kill 'em all. Since the child acts the same on the parents SIGTERM
+ * and a SIGHUP, we may as well use the same signal, because some user
+ * pthreads are stealing signals from us left and right.
+@@ -3326,9 +3360,7 @@
+ }
+
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+- event_note_child_killed);
+- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
+- "SIGHUP received. Attempting to restart");
++ event_note_child_stopped);
+ }
+
+ return OK;
diff --git a/SOURCES/httpd-2.4.53-separate-systemd-fns.patch b/SOURCES/httpd-2.4.53-separate-systemd-fns.patch
new file mode 100644
index 0000000..88b99ff
--- /dev/null
+++ b/SOURCES/httpd-2.4.53-separate-systemd-fns.patch
@@ -0,0 +1,286 @@
+diff --git a/acinclude.m4 b/acinclude.m4
+index 05abe18..97484c9 100644
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -631,7 +631,6 @@ case $host in
+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
+ AC_MSG_WARN([Your system does not support systemd.])
+ else
+- APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS])
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
+ fi
+ fi
+diff --git a/include/ap_listen.h b/include/ap_listen.h
+index 58c2574..d5ed968 100644
+--- a/include/ap_listen.h
++++ b/include/ap_listen.h
+@@ -29,6 +29,7 @@
+ #include "apr_network_io.h"
+ #include "httpd.h"
+ #include "http_config.h"
++#include "apr_optional.h"
+
+ #ifdef __cplusplus
+ extern "C" {
+@@ -143,6 +144,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
+ void *dummy,
+ const char *arg);
+
++#ifdef HAVE_SYSTEMD
++APR_DECLARE_OPTIONAL_FN(int,
++ ap_find_systemd_socket, (process_rec *, apr_port_t));
++
++APR_DECLARE_OPTIONAL_FN(int,
++ ap_systemd_listen_fds, (int));
++#endif
++
++
+ #define LISTEN_COMMANDS \
+ AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \
+ "Maximum length of the queue of pending connections, as used by listen(2)"), \
+diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c
+index eda1272..fc059fc 100644
+--- a/modules/arch/unix/mod_systemd.c
++++ b/modules/arch/unix/mod_systemd.c
+@@ -35,6 +35,15 @@
+ #include
+ #endif
+
++APR_DECLARE_OPTIONAL_FN(int,
++ ap_find_systemd_socket, (process_rec *, apr_port_t));
++
++APR_DECLARE_OPTIONAL_FN(int,
++ ap_systemd_listen_fds, (int));
++
++APR_DECLARE_OPTIONAL_FN(int,
++ ap_systemd_journal_stream_fd, (const char *, int, int));
++
+ static char describe_listeners[30];
+
+ static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+@@ -145,8 +154,47 @@ static int systemd_monitor(apr_pool_t *p, server_rec *s)
+ return DECLINED;
+ }
+
++static int ap_find_systemd_socket(process_rec * process, apr_port_t port) {
++ int fdcount, fd;
++ int sdc = sd_listen_fds(0);
++
++ if (sdc < 0) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
++ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
++ sdc);
++ return -1;
++ }
++
++ if (sdc == 0) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
++ "find_systemd_socket: At least one socket must be set.");
++ return -1;
++ }
++
++ fdcount = atoi(getenv("LISTEN_FDS"));
++ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
++ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
++ return fd;
++ }
++ }
++
++ return -1;
++}
++
++static int ap_systemd_listen_fds(int unset_environment){
++ return sd_listen_fds(unset_environment);
++}
++
++static int ap_systemd_journal_stream_fd(const char *identifier, int priority, int level_prefix){
++ return sd_journal_stream_fd("httpd", priority, 0);
++}
++
+ static void systemd_register_hooks(apr_pool_t *p)
+ {
++ APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds);
++ APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket);
++ APR_REGISTER_OPTIONAL_FN(ap_systemd_journal_stream_fd);
++
+ /* Enable ap_extended_status. */
+ ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST);
+ /* Signal service is ready. */
+diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4
+index 0848d2e..8af2299 100644
+--- a/modules/loggers/config.m4
++++ b/modules/loggers/config.m4
+@@ -5,7 +5,6 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
+ APACHE_MODPATH_INIT(loggers)
+
+ APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes)
+-APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS])
+
+ APACHE_MODULE(log_debug, configurable debug logging, , , most)
+ APACHE_MODULE(log_forensic, forensic logging)
+diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
+index 0b11f60..c3f0a51 100644
+--- a/modules/loggers/mod_log_config.c
++++ b/modules/loggers/mod_log_config.c
+@@ -172,10 +172,6 @@
+ #include
+ #endif
+
+-#ifdef HAVE_SYSTEMD
+-#include
+-#endif
+-
+ #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"
+
+ module AP_MODULE_DECLARE_DATA log_config_module;
+@@ -1640,8 +1636,15 @@ static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd,
+ {
+ #ifdef HAVE_SYSTEMD
+ int fd;
++ APR_OPTIONAL_FN_TYPE(ap_systemd_journal_stream_fd) *systemd_journal_stream_fd;
++
++ systemd_journal_stream_fd = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_journal_stream_fd);
++ if (systemd_journal_stream_fd == NULL) {
++ return APR_ENOTIMPL;
++ }
+
+- fd = sd_journal_stream_fd("httpd", priority, 0);
++ fd = systemd_journal_stream_fd("httpd", priority, 0);
++
+ if (fd < 0) return fd;
+
+ /* This is an AF_UNIX socket fd so is more pipe-like than
+diff --git a/modules/loggers/mod_log_config.h b/modules/loggers/mod_log_config.h
+index 877a593..bd52a98 100644
+--- a/modules/loggers/mod_log_config.h
++++ b/modules/loggers/mod_log_config.h
+@@ -69,6 +69,10 @@ APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writ
+ */
+ APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func));
+
++#ifdef HAVE_SYSTEMD
++APR_DECLARE_OPTIONAL_FN(int, ap_systemd_journal_stream_fd, (const char *, int, int));
++#endif
++
+ #endif /* MOD_LOG_CONFIG */
+ /** @} */
+
+diff --git a/server/listen.c b/server/listen.c
+index e2e028a..5d1c0e1 100644
+--- a/server/listen.c
++++ b/server/listen.c
+@@ -34,10 +34,6 @@
+ #include
+ #endif
+
+-#ifdef HAVE_SYSTEMD
+-#include
+-#endif
+-
+ /* we know core's module_index is 0 */
+ #undef APLOG_MODULE_INDEX
+ #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
+@@ -325,34 +321,6 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
+ }
+
+ #ifdef HAVE_SYSTEMD
+-
+-static int find_systemd_socket(process_rec * process, apr_port_t port) {
+- int fdcount, fd;
+- int sdc = sd_listen_fds(0);
+-
+- if (sdc < 0) {
+- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
+- "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
+- sdc);
+- return -1;
+- }
+-
+- if (sdc == 0) {
+- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
+- "find_systemd_socket: At least one socket must be set.");
+- return -1;
+- }
+-
+- fdcount = atoi(getenv("LISTEN_FDS"));
+- for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
+- if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
+- return fd;
+- }
+- }
+-
+- return -1;
+-}
+-
+ static apr_status_t alloc_systemd_listener(process_rec * process,
+ int fd, const char *proto,
+ ap_listen_rec **out_rec)
+@@ -412,6 +380,14 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port,
+ {
+ ap_listen_rec *last, *new;
+ apr_status_t rv;
++ APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket;
++
++ find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket);
++
++ if (!find_systemd_socket)
++ return "Systemd socket activation is used, but mod_systemd is probably "
++ "not loaded";
++
+ int fd = find_systemd_socket(process, port);
+ if (fd < 0) {
+ return "Systemd socket activation is used, but this port is not "
+@@ -438,7 +414,6 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port,
+
+ return NULL;
+ }
+-
+ #endif /* HAVE_SYSTEMD */
+
+ static const char *alloc_listener(process_rec *process, const char *addr,
+@@ -707,6 +682,9 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
+ int num_listeners = 0;
+ const char* proto;
+ int found;
++#ifdef HAVE_SYSTEMD
++ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
++#endif
+
+ for (ls = s; ls; ls = ls->next) {
+ proto = ap_get_server_protocol(ls);
+@@ -746,7 +724,10 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
+ apr_pool_cleanup_null, s->process->pool);
+ }
+ else {
+- sd_listen_fds(1);
++ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
++ if (systemd_listen_fds != NULL) {
++ systemd_listen_fds(1);
++ }
+ }
+ }
+ else
+@@ -963,6 +944,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
+ apr_port_t port;
+ apr_status_t rv;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
++#ifdef HAVE_SYSTEMD
++ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
++#endif
+
+ if (err != NULL) {
+ return err;
+@@ -973,7 +957,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
+ }
+ #ifdef HAVE_SYSTEMD
+ if (use_systemd == -1) {
+- use_systemd = sd_listen_fds(0) > 0;
++ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
++ if (systemd_listen_fds != NULL) {
++ use_systemd = systemd_listen_fds(0) > 0;
++ } else {
++ use_systemd = 0;
++ }
+ }
+ #endif
+
diff --git a/SOURCES/httpd-2.4.53.tar.bz2.asc b/SOURCES/httpd-2.4.53.tar.bz2.asc
new file mode 100644
index 0000000..9ad167f
--- /dev/null
+++ b/SOURCES/httpd-2.4.53.tar.bz2.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+Comment: GPGTools - https://gpgtools.org
+
+iQIzBAABCgAdFiEEJvUe+agvSstD8ZA+03fJ59GUTGYFAmIotxoACgkQ03fJ59GU
+TGbaAQ//TeVio63uLRIhyhW4qoUlGCL4KfCyY3aj5Yh6JGea9lYdioZ4JdHJan2y
+IYRuF7B2S/MgfWESsEkPq8Nh0+ym78ZObdTFsskUF9so3+3WN9szQwTP/9suNd4+
+fv1vOKKGdy2h4hakR+E182A8gJ9FO6FabiETLvPvYVma3+5Zd2duzyvAOAQUDvkj
+JhFXYVQCrWfiJN7gARePAzZyxbfWd5QVQMuCiWSIQ2PG0SkfQa07CsEiDiN8r8fZ
+NGpNmyfUNqz4aUkBssNr0rVfmLzG2vicrfWaOgyS0rAEqn7fYhgF3s9k5y2htgOu
+mdv2TPYl39NBf3uQNtR5tTUCPaop2GvH1GMJnz18W2fpessscHsuWiqeVVNUDmvV
+zrFWlH2ehYPIOt07moP80nWJzpP7F5BGSG3DqcXPSG1JM/TM8uC3dgbC7k26i3vh
++8ypE1unHjop4nGff4cSkGeC5W2PkXrYNJC8xyjwbT098Q+Z8kAcO8TLpdaSx6tf
+fI/9IwX+2uOhGx+ZHok0BSX0EpGK+i51Kspih++AcNaf6T4urXKdrpEgNm4jdHw7
+maCHPDelUMyxffBM/Jl8/VZD+SHuhK2LzPBFGOJdNhbNKzdkfg5TaxhfIywvV1T6
+JzRtvx/HoglaqCNFsBqflWpctC5dS2DeKEbP9FaDbqfxLmxp/G8=
+=7fpY
+-----END PGP SIGNATURE-----
diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec
index a2a5eef..1e0e486 100644
--- a/SPECS/httpd.spec
+++ b/SPECS/httpd.spec
@@ -12,7 +12,7 @@
Summary: Apache HTTP Server
Name: httpd
-Version: 2.4.51
+Version: 2.4.53
Release: 7%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
@@ -52,6 +52,7 @@ Source31: README.confmod
Source32: httpd.service.xml
Source33: htcacheclean.service.xml
Source34: httpd.conf.xml
+Source35: 00-brotli.conf
Source40: htcacheclean.service
Source41: htcacheclean.sysconf
Source42: httpd-init.service
@@ -66,7 +67,7 @@ Source48: apache-poweredby.png
Patch2: httpd-2.4.43-apxs.patch
Patch3: httpd-2.4.43-deplibs.patch
# Needed for socket activation and mod_systemd patch
-Patch19: httpd-2.4.43-detect-systemd.patch
+Patch19: httpd-2.4.53-detect-systemd.patch
# Features/functional changes
Patch21: httpd-2.4.48-r1842929+.patch
Patch22: httpd-2.4.43-mod_systemd.patch
@@ -74,7 +75,7 @@ Patch23: httpd-2.4.48-export.patch
Patch24: httpd-2.4.43-corelimit.patch
Patch25: httpd-2.4.43-selinux.patch
Patch26: httpd-2.4.43-gettid.patch
-Patch27: httpd-2.4.43-icons.patch
+Patch27: httpd-2.4.53-icons.patch
Patch30: httpd-2.4.43-cachehardmax.patch
Patch34: httpd-2.4.43-socket-activation.patch
Patch38: httpd-2.4.43-sslciphdefault.patch
@@ -92,29 +93,43 @@ Patch48: httpd-2.4.46-freebind.patch
Patch49: httpd-2.4.48-ssl-proxy-chains.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2004143
Patch50: httpd-2.4.48-r1825120.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2079939
+# backported regression fix
+Patch51: httpd-2.4.53-r1901199.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2065677
+Patch52: httpd-2.4.53-separate-systemd-fns.patch
# Bug fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243
Patch60: httpd-2.4.43-enable-sslv3.patch
Patch61: httpd-2.4.46-htcacheclean-dont-break.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1986822
-# https://bugzilla.redhat.com/show_bug.cgi?id=1976080
-Patch62: httpd-2.4.51-openssl3.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1932442
Patch64: httpd-2.4.48-full-release.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1950011
Patch65: httpd-2.4.51-r1877397.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1938740
Patch66: httpd-2.4.51-r1892413+.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2073459
+Patch67: httpd-2.4.51-r1811831.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2098056
+Patch68: httpd-2.4.53-r1878890.patch
# Security fixes
-# https://bugzilla.redhat.com/show_bug.cgi?id=2034674
-Patch200: httpd-2.4.51-CVE-2021-44790.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=2034672
-Patch201: httpd-2.4.51-CVE-2021-44224.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=2065250
-Patch202: httpd-2.4.51-CVE-2022-22720.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2094997
+Patch200: httpd-2.4.53-CVE-2022-26377.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095006
+Patch201: httpd-2.4.53-CVE-2022-28615.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095020
+Patch202: httpd-2.4.53-CVE-2022-31813.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095002
+Patch203: httpd-2.4.53-CVE-2022-28614.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095012
+Patch204: httpd-2.4.53-CVE-2022-29404.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095015
+Patch205: httpd-2.4.53-CVE-2022-30522.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2095018
+Patch206: httpd-2.4.53-CVE-2022-30556.patch
License: ASL 2.0
BuildRequires: gcc, autoconf, pkgconfig, findutils, xmlto
@@ -122,29 +137,38 @@ BuildRequires: perl-interpreter, perl-generators, systemd-devel
BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel
BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0
BuildRequires: gnupg2
-Requires: /etc/mime.types, system-logos-httpd
+Requires: system-logos-httpd
Provides: webserver
-Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release}
-Provides: httpd-mmn = %{mmn}, httpd-mmn = %{mmnisa}
-Requires: httpd-tools = %{version}-%{release}
-Requires: httpd-filesystem = %{version}-%{release}
+Requires: httpd-core = 0:%{version}-%{release}
Recommends: mod_http2, mod_lua
-Requires(pre): httpd-filesystem
Requires(preun): systemd-units
Requires(postun): systemd-units
Requires(post): systemd-units
-Conflicts: apr < 1.5.0-1
-Provides: mod_proxy_uwsgi = %{version}-%{release}
-Obsoletes: mod_proxy_uwsgi < 2.0.17.1-2
%description
The Apache HTTP Server is a powerful, efficient, and extensible
web server.
+%package core
+Summary: httpd minimal core
+Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release}
+Provides: httpd-mmn = %{mmn}, httpd-mmn = %{mmnisa}
+Provides: mod_proxy_uwsgi = %{version}-%{release}
+Requires: /etc/mime.types
+Requires: httpd-tools = %{version}-%{release}
+Requires: httpd-filesystem = %{version}-%{release}
+Requires(pre): httpd-filesystem
+Conflicts: apr < 1.5.0-1
+Conflicts: httpd < 2.4.53-3
+Obsoletes: mod_proxy_uwsgi < 2.0.17.1-2
+
+%description core
+The httpd-core package contains essential httpd binaries.
+
%package devel
Summary: Development interfaces for the Apache HTTP Server
Requires: apr-devel, apr-util-devel, pkgconfig
-Requires: httpd = %{version}-%{release}
+Requires: httpd-core = %{version}-%{release}
%description devel
The httpd-devel package contains the APXS binary and other files
@@ -157,7 +181,7 @@ to install this package.
%package manual
Summary: Documentation for the Apache HTTP Server
-Requires: httpd = %{version}-%{release}
+Requires: httpd-core = 0:%{version}-%{release}
BuildArch: noarch
%description manual
@@ -187,7 +211,7 @@ Summary: SSL/TLS module for the Apache HTTP Server
Epoch: 1
BuildRequires: openssl-devel
Requires(pre): httpd-filesystem
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
+Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
Requires: sscg >= 2.2.0, /usr/bin/hostname
# Require an OpenSSL which supports PROFILE=SYSTEM
Conflicts: openssl-libs < 1:1.0.1h-4
@@ -199,7 +223,7 @@ Security (TLS) protocols.
%package -n mod_proxy_html
Summary: HTML and XML content filters for the Apache HTTP Server
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
+Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
BuildRequires: libxml2-devel
BuildRequires: make
Epoch: 1
@@ -211,7 +235,7 @@ transform and modify HTML and XML content.
%package -n mod_ldap
Summary: LDAP authentication modules for the Apache HTTP Server
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
+Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
Requires: apr-util-ldap
%description -n mod_ldap
@@ -220,7 +244,7 @@ authentication to the Apache HTTP Server.
%package -n mod_session
Summary: Session interface for the Apache HTTP Server
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
+Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
%description -n mod_session
The mod_session module and associated backends provide an abstract
@@ -228,7 +252,7 @@ interface for storing and accessing per-user session data.
%package -n mod_lua
Summary: Lua scripting support for the Apache HTTP Server
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
+Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
%description -n mod_lua
The mod_lua module allows the server to be extended with scripts
@@ -262,17 +286,24 @@ written in the Lua programming language.
%patch48 -p1 -b .freebind
%patch49 -p1 -b .ssl-proxy-chains
%patch50 -p1 -b .r1825120
+%patch51 -p1 -b .r1901199
+%patch52 -p1 -b .separatesystemd
%patch60 -p1 -b .enable-sslv3
%patch61 -p1 -b .htcacheclean-dont-break
-%patch62 -p1 -b .r1876934
%patch64 -p1 -b .full-release
%patch65 -p1 -b .r1877397
%patch66 -p1 -b .r1892413+
+%patch67 -p1 -b .r1811831
+%patch68 -p1 -b .r1878890
-%patch200 -p1 -b .CVE-2021-44790
-%patch201 -p1 -b .CVE-2021-44224
-%patch202 -p1 -b .CVE-2022-22720
+%patch200 -p1 -b .CVE-2022-26377
+%patch201 -p1 -b .CVE-2022-28615
+%patch202 -p1 -b .CVE-2022-31813
+%patch203 -p1 -b .CVE-2022-28614
+%patch204 -p1 -b .CVE-2022-29404
+%patch205 -p1 -b .CVE-2022-30522
+%patch206 -p1 -b .CVE-2022-30556
# Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@@ -366,7 +397,7 @@ export LYNX_PATH=/usr/bin/links
--with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \
--with-brotli \
--enable-pie \
- --with-pcre \
+ --with-pcre=/usr/bin/pcre-config \
--enable-mods-shared=all \
--enable-ssl --with-ssl --disable-distcache \
--enable-proxy --enable-proxy-fdpass \
@@ -405,7 +436,8 @@ install -m 644 $RPM_SOURCE_DIR/README.confmod \
$RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/README
for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \
00-proxy.conf 00-ssl.conf 01-ldap.conf 00-proxyhtml.conf \
- 01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf; do
+ 01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf \
+ 00-brotli.conf; do
install -m 644 -p $RPM_SOURCE_DIR/$f \
$RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f
done
@@ -678,6 +710,22 @@ set -x
exit $rv
%files
+%{_mandir}/man8/*
+%{_mandir}/man5/*
+%exclude %{_mandir}/man8/httpd-init.*
+
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-brotli.conf
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-systemd.conf
+
+%{_libdir}/httpd/modules/mod_brotli.so
+%{_libdir}/httpd/modules/mod_systemd.so
+
+%{_unitdir}/httpd.service
+%{_unitdir}/httpd@.service
+%{_unitdir}/htcacheclean.service
+%{_unitdir}/*.socket
+
+%files core
%doc ABOUT_APACHE README CHANGES LICENSE VERSIONING NOTICE
%doc docs/conf/extra/*.conf
@@ -699,7 +747,10 @@ exit $rv
%dir %{_sysconfdir}/httpd/conf.modules.d
%{_sysconfdir}/httpd/conf.modules.d/README
+
%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/*.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/00-brotli.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/00-systemd.conf
%exclude %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
%exclude %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf
%exclude %{_sysconfdir}/httpd/conf.modules.d/00-lua.conf
@@ -721,6 +772,8 @@ exit $rv
%dir %{_libdir}/httpd
%dir %{_libdir}/httpd/modules
%{_libdir}/httpd/modules/mod*.so
+%exclude %{_libdir}/httpd/modules/mod_brotli.so
+%exclude %{_libdir}/httpd/modules/mod_systemd.so
%exclude %{_libdir}/httpd/modules/mod_auth_form.so
%exclude %{_libdir}/httpd/modules/mod_ssl.so
%exclude %{_libdir}/httpd/modules/mod_*ldap.so
@@ -747,15 +800,6 @@ exit $rv
%attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd
%attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd/proxy
-%{_mandir}/man8/*
-%{_mandir}/man5/*
-%exclude %{_mandir}/man8/httpd-init.*
-
-%{_unitdir}/httpd.service
-%{_unitdir}/httpd@.service
-%{_unitdir}/htcacheclean.service
-%{_unitdir}/*.socket
-
%files filesystem
%dir %{_sysconfdir}/httpd
%dir %{_sysconfdir}/httpd/conf.d
@@ -819,12 +863,47 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
+* Wed Jul 20 2022 Luboš Uhliarik - 2.4.53-7
+- Resolves: #2094997 - CVE-2022-26377 httpd: mod_proxy_ajp: Possible request
+ smuggling
+- Resolves: #2097032 - CVE-2022-28615 httpd: out-of-bounds read in
+ ap_strcmp_match()
+- Resolves: #2098248 - CVE-2022-31813 httpd: mod_proxy: X-Forwarded-For dropped
+ by hop-by-hop mechanism
+- Resolves: #2097016 - CVE-2022-28614 httpd: out-of-bounds read via ap_rwrite()
+- Resolves: #2097452 - CVE-2022-29404 httpd: mod_lua: DoS in r:parsebody
+- Resolves: #2097459 - CVE-2022-30522 httpd: mod_sed: DoS vulnerability
+- Resolves: #2097481 - CVE-2022-30556 httpd: mod_lua: Information disclosure
+ with websockets
+
+* Mon Jun 27 2022 Luboš Uhliarik - 2.4.53-6
+- Related: #2065677 - httpd minimisation for ubi-micro
+
+* Fri Jun 24 2022 Luboš Uhliarik - 2.4.53-5
+- Resolves: #2098056 - mod_ldap: High CPU usage at apr_ldap_rebind_remove()
+
+* Thu Jun 16 2022 Luboš Uhliarik - 2.4.53-4
+- Resolves: #2095838 - mod_mime_magic: invalid type 0 in mconvert()
+
+* Wed Jun 01 2022 Luboš Uhliarik - 2.4.53-3
+- Resolves: #2065677 - httpd minimisation for ubi-micro
+- minimize httpd dependencies (new httpd-core package)
+- mod_systemd and mod_brotli are now packaged in the main httpd package
+
+* Tue May 31 2022 Luboš Uhliarik - 2.4.53-1
+- new version 2.4.53
+- Resolves: #2079939 - httpd rebase to 2.4.53
+- Resolves: #2075406 - httpd.conf uses icon bomb.gif for all files/dirs ending
+ with core
+
+* Mon Apr 11 2022 Luboš Uhliarik - 2.4.51-8
+- Resolves: #2073459 - Cannot override LD_LIBARY_PATH in Apache HTTPD using
+ SetEnv or PassEnv
+
* Mon Mar 21 2022 Luboš Uhliarik - 2.4.51-7
-- Resolves: #2065250 - CVE-2022-22720 httpd: HTTP request smuggling
+- Resolves: #2065251 - CVE-2022-22720 httpd: HTTP request smuggling
vulnerability in Apache HTTP Server 2.4.52 and earlier
-
-* Wed Mar 16 2022 Luboš Uhliarik - 2.4.51-6
-- Resolves: #2035031 - CVE-2021-44224 httpd: possible NULL dereference or SSRF
+- Resolves: #2066311 - CVE-2021-44224 httpd: possible NULL dereference or SSRF
in forward proxy configurations
* Mon Jan 10 2022 Luboš Uhliarik - 2.4.51-5