diff --git a/SOURCES/httpd-2.4.37-CVE-2006-20001.patch b/SOURCES/httpd-2.4.37-CVE-2006-20001.patch new file mode 100644 index 0000000..26c9363 --- /dev/null +++ b/SOURCES/httpd-2.4.37-CVE-2006-20001.patch @@ -0,0 +1,20 @@ +diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c +index 1ae5914027c..3f7822fc931 100644 +--- a/modules/dav/main/util.c ++++ b/modules/dav/main/util.c +@@ -801,8 +801,14 @@ static dav_error * dav_process_if_header(request_rec *r, dav_if_header **p_ih) + "for the same state."); + } + condition = DAV_IF_COND_NOT; ++ list += 2; ++ } ++ else { ++ return dav_new_error(r->pool, HTTP_BAD_REQUEST, ++ DAV_ERR_IF_UNK_CHAR, 0, ++ "Invalid \"If:\" header: " ++ "Unexpected character in List"); + } +- list += 2; + break; + + case ' ': 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-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 +
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 +
LimitRequestBody bytes
LimitRequestBody 0
LimitRequestBody 1073741824
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.
LimitRequestBody
only applies to
+- request bodies that the server will spool to disk
$N
in the substitution string!
+ The [B] flag instructs RewriteRule
to escape non-alphanumeric
+ characters before applying the transformation.
In 2.4.26 and later, you can limit the escaping to specific characters
+-in backreferences by listing them: [B=#?;]
. Note: The space
+-character can be used in the list of characters to escape, but it cannot be
+-the last character in the list.
mod_rewrite
has to unescape URLs before mapping them,
+ so backreferences are unescaped at the time they are applied.
+@@ -120,6 +116,20 @@ when the backend may break if presented with an unescaped URL.
An alternative to this flag is using a RewriteCond
to capture against %{THE_REQUEST} which will capture
+ strings in the encoded form.
In 2.4.26 and later, you can limit the escaping to specific characters
++in backreferences by listing them: [B=#?;]
. Note: The space
++character can be used in the list of characters to escape, but you must quote
++the entire third argument of RewriteRule
++and the space must not be the last character in the list.
# Escape spaces and question marks. The quotes around the final argument ++# are required when a space is included. ++RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"++ ++
To limit the characters escaped this way, see #flag_bne ++and #flag_bctls
++ + +++# Escape spaces to %20 in the path instead of + as used in form submission via ++# the query string ++RewriteRule "^search/(.*)$" "/search.php/$1" "[B,BNP]" ++++ +
This flag is available in version 2.4.26 and later.
+ ++The [BCTLS] flag is similar to the [B] flag, but only escapes ++control characters and the space character. This is the same set of ++characters rejected when they are copied into the query string unencoded. ++
++ ++++# Escape control characters and spaces ++RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]" ++++ ++
The list of characters in [BNE=...] are treated as exclusions to the ++characters of the [B] or [BCTLS] flags. The listed characters will not be ++escaped. ++
++ ++++# Escape the default characters, but leave / ++RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]" ++++ +
Consider this example:
+ +RewriteEngine On +-RewriteRule "^/index\.html" "-" [CO=frontdoor:yes:.example.com:1440:/]++RewriteRule "^/index\.html" "-" [CO=frontdoor:yes:.example.com:1440:/] + + +
In the example give, the rule doesn't rewrite the request.
+@@ -410,8 +452,8 @@ argument to index.php
, however, the index.php
, the RewriteRule
will be skipped.
RewriteBase "/" +-RewriteCond "%{REQUEST_URI}" "!=/index.php" +-RewriteRule "^(.*)" "/index.php?req=$1" [L,PT]++RewriteCond "%{REQUEST_URI}" !=/index.php ++RewriteRule "^(.*)" "/index.php?req=$1" [L,PT] + +
A
), perform this substitution (i.e., replace the
+ A
with a B
).
+
+-In 2.4.8 and later, this module returns an error after 32,000 iterations to ++
In 2.4.8 and later, this module returns an error after 10,000 iterations to + protect against unintended looping. An alternative maximum number of + iterations can be specified by adding to the N flag.
+# Be willing to replace 1 character in each pass of the loop +-RewriteRule "(.+)[><;]$" "$1" [N=64000] ++RewriteRule "(.+)[><;]$" "$1" [N=32000] + # ... or, give up if after 10 loops + RewriteRule "(.+)[><;]$" "$1" [N=10]+ +@@ -681,19 +723,21 @@ URI in request' warnings. +
The [S] flag is used to skip rules that you don't want to run. The
+ syntax of the skip flag is [S=N], where N signifies
+ the number of rules to skip (provided the
+-RewriteRule
matches). This can be thought of as a goto
+-statement in your rewrite ruleset. In the following example, we only want
+-to run the RewriteRule
if the
+-requested URI doesn't correspond with an actual file.
++RewriteCond
directives match). This can be thought of as a
++goto
statement in your rewrite ruleset. In the following
++example, we only want to run the
++RewriteRule
if the requested URI doesn't correspond with an
++actual file.
+
+ # Is the request for a non-existent file? +-RewriteCond "%{REQUEST_FILENAME}" "!-f" +-RewriteCond "%{REQUEST_FILENAME}" "!-d" ++RewriteCond "%{REQUEST_FILENAME}" !-f ++RewriteCond "%{REQUEST_FILENAME}" !-d + # If so, skip these two RewriteRules +-RewriteRule ".?" "-" [S=2] ++RewriteRule ".?" "-" [S=2] + +-RewriteRule "(.*\.gif)" "images.php?$1" +-RewriteRule "(.*\.html)" "docs.php?$1"++RewriteRule "(.*\.gif)" "images.php?$1" ++RewriteRule "(.*\.html)" "docs.php?$1" + + +
This technique is useful because a RewriteCond
only applies to the
+@@ -705,18 +749,18 @@ use this to make pseudo if-then-else constructs: The last rule of
+ the then-clause becomes skip=N
, where N is the
+ number of rules in the else-clause:
# Does the file exist? +-RewriteCond "%{REQUEST_FILENAME}" "!-f" +-RewriteCond "%{REQUEST_FILENAME}" "!-d" ++RewriteCond "%{REQUEST_FILENAME}" !-f ++RewriteCond "%{REQUEST_FILENAME}" !-d + # Create an if-then-else construct by skipping 3 lines if we meant to go to the "else" stanza. +-RewriteRule ".?" "-" [S=3] ++RewriteRule ".?" "-" [S=3] + + # IF the file exists, then: +- RewriteRule "(.*\.gif)" "images.php?$1" ++ RewriteRule "(.*\.gif)" "images.php?$1" + RewriteRule "(.*\.html)" "docs.php?$1" + # Skip past the "else" stanza. +- RewriteRule ".?" "-" [S=1] ++ RewriteRule ".?" "-" [S=1] + # ELSE... +- RewriteRule "(.*)" "404.php?file=$1" ++ RewriteRule "(.*)" "404.php?file=$1" + # END+ + +@@ -733,7 +777,7 @@ sent. This has the same effect as the
# Serve .pl files as plain text
+-RewriteRule "\.pl$" "-" [T=text/plain]
++RewriteRule "\.pl$" "-" [T=text/plain]
+
+
+ Or, perhaps, if you have a camera that produces jpeg images without
+@@ -741,7 +785,7 @@ file extensions, you could force those images to be served with the
+ correct MIME type by virtue of their file names:
+
+ # Files with 'IMG' in the name are jpg images.
+-RewriteRule "IMG" "-" [T=image/jpg]
++RewriteRule "IMG" "-" [T=image/jpg]
+
+
+ Please note that this is a trivial example, and could be better done
+diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
+index 38dbb24..b71c67c 100644
+--- a/modules/mappers/mod_rewrite.c
++++ b/modules/mappers/mod_rewrite.c
+@@ -101,6 +101,8 @@
+ #include "mod_rewrite.h"
+ #include "ap_expr.h"
+
++#include "test_char.h"
++
+ static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL;
+ static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
+ static const char* really_last_key = "rewrite_really_last";
+@@ -168,6 +170,8 @@ static const char* really_last_key = "rewrite_really_last";
+ #define RULEFLAG_END (1<<17)
+ #define RULEFLAG_ESCAPENOPLUS (1<<18)
+ #define RULEFLAG_QSLAST (1<<19)
++#define RULEFLAG_QSNONE (1<<20) /* programattic only */
++#define RULEFLAG_ESCAPECTLS (1<<21)
+
+ /* return code of the rewrite rule
+ * the result may be escaped - or not
+@@ -321,7 +325,8 @@ typedef struct {
+ data_item *cookie; /* added cookies */
+ int skip; /* number of next rules to skip */
+ int maxrounds; /* limit on number of loops with N flag */
+- char *escapes; /* specific backref escapes */
++ const char *escapes; /* specific backref escapes */
++ const char *noescapes; /* specific backref chars not to escape */
+ } rewriterule_entry;
+
+ typedef struct {
+@@ -422,7 +427,9 @@ static const char *rewritemap_mutex_type = "rewrite-map";
+ /* Optional functions imported from mod_ssl when loaded: */
+ static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL;
+ static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL;
+-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus);
++static char *escape_backref(apr_pool_t *p, const char *path,
++ const char *escapeme, const char *noescapeme,
++ int flags);
+
+ /*
+ * +-------------------------------------------------------+
+@@ -645,18 +652,26 @@ static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
+ return where;
+ }
+
++
+ /*
+ * Escapes a backreference in a similar way as php's urlencode does.
+ * Based on ap_os_escape_path in server/util.c
+ */
+-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus) {
+- char *copy = apr_palloc(p, 3 * strlen(path) + 3);
++static char *escape_backref(apr_pool_t *p, const char *path,
++ const char *escapeme, const char *noescapeme,
++ int flags)
++{
++ char *copy = apr_palloc(p, 3 * strlen(path) + 1);
+ const unsigned char *s = (const unsigned char *)path;
+ unsigned char *d = (unsigned char *)copy;
+- unsigned c;
++ int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
++ int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
++ unsigned char c;
+
+ while ((c = *s)) {
+- if (!escapeme) {
++ if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
++ || (escapeme && ap_strchr_c(escapeme, c)))
++ && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
+ if (apr_isalnum(c) || c == '_') {
+ *d++ = c;
+ }
+@@ -667,23 +682,8 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem
+ d = c2x(c, '%', d);
+ }
+ }
+- else {
+- const char *esc = escapeme;
+- while (*esc) {
+- if (c == *esc) {
+- if (c == ' ' && !noplus) {
+- *d++ = '+';
+- }
+- else {
+- d = c2x(c, '%', d);
+- }
+- break;
+- }
+- ++esc;
+- }
+- if (!*esc) {
+- *d++ = c;
+- }
++ else {
++ *d++ = c;
+ }
+ ++s;
+ }
+@@ -761,15 +761,24 @@ static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme)
+ ap_escape_uri(p, cp), NULL);
+ }
+
++
+ /*
+ * split out a QUERY_STRING part from
+ * the current URI string
+ */
+-static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
+- int qslast)
++static void splitout_queryargs(request_rec *r, int flags)
+ {
+ char *q;
+ int split;
++ int qsappend = flags & RULEFLAG_QSAPPEND;
++ int qsdiscard = flags & RULEFLAG_QSDISCARD;
++ int qslast = flags & RULEFLAG_QSLAST;
++
++ if (flags & RULEFLAG_QSNONE) {
++ rewritelog((r, 2, NULL, "discarding query string, no parse from substitution"));
++ r->args = NULL;
++ return;
++ }
+
+ /* don't touch, unless it's a scheme for which a query string makes sense.
+ * See RFC 1738 and RFC 2368.
+@@ -794,7 +803,7 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
+ olduri = apr_pstrdup(r->pool, r->filename);
+ *q++ = '\0';
+ if (qsappend) {
+- if (*q) {
++ if (*q) {
+ r->args = apr_pstrcat(r->pool, q, "&" , r->args, NULL);
+ }
+ }
+@@ -802,9 +811,9 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
+ r->args = apr_pstrdup(r->pool, q);
+ }
+
+- if (r->args) {
++ if (r->args) {
+ len = strlen(r->args);
+-
++
+ if (!len) {
+ r->args = NULL;
+ }
+@@ -2436,7 +2445,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
+ /* escape the backreference */
+ char *tmp2, *tmp;
+ tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
+- tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags & RULEFLAG_ESCAPENOPLUS);
++ tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
++ entry->flags);
+ rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
+ tmp, tmp2));
+
+@@ -2733,7 +2743,7 @@ static apr_status_t rewritelock_remove(void *data)
+ * XXX: what an inclined parser. Seems we have to leave it so
+ * for backwards compat. *sigh*
+ */
+-static int parseargline(char *str, char **a1, char **a2, char **a3)
++static int parseargline(char *str, char **a1, char **a2, char **a2_end, char **a3)
+ {
+ char quote;
+
+@@ -2784,8 +2794,10 @@ static int parseargline(char *str, char **a1, char **a2, char **a3)
+
+ if (!*str) {
+ *a3 = NULL; /* 3rd argument is optional */
++ *a2_end = str;
+ return 0;
+ }
++ *a2_end = str;
+ *str++ = '\0';
+
+ while (apr_isspace(*str)) {
+@@ -3323,7 +3335,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
+ rewrite_server_conf *sconf;
+ rewritecond_entry *newcond;
+ ap_regex_t *regexp;
+- char *a1 = NULL, *a2 = NULL, *a3 = NULL;
++ char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
+ const char *err;
+
+ sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
+@@ -3341,7 +3353,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
+ * of the argument line. So we can use a1 .. a3 without
+ * copying them again.
+ */
+- if (parseargline(str, &a1, &a2, &a3)) {
++ if (parseargline(str, &a1, &a2, &a2_end, &a3)) {
+ return apr_pstrcat(cmd->pool, "RewriteCond: bad argument line '", str,
+ "'", NULL);
+ }
+@@ -3500,13 +3512,24 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
+ case 'B':
+ if (!*key || !strcasecmp(key, "ackrefescaping")) {
+ cfg->flags |= RULEFLAG_ESCAPEBACKREF;
+- if (val && *val) {
++ if (val && *val) {
+ cfg->escapes = val;
+ }
+ }
++ else if (!strcasecmp(key, "NE")) {
++ if (val && *val) {
++ cfg->noescapes = val;
++ }
++ else {
++ return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
++ }
++ }
+ else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) {
+ cfg->flags |= RULEFLAG_ESCAPENOPLUS;
+ }
++ else if (!strcasecmp(key, "CTLS")) {
++ cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF;
++ }
+ else {
+ ++error;
+ }
+@@ -3749,7 +3772,7 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
+ rewrite_server_conf *sconf;
+ rewriterule_entry *newrule;
+ ap_regex_t *regexp;
+- char *a1 = NULL, *a2 = NULL, *a3 = NULL;
++ char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
+ const char *err;
+
+ sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
+@@ -3763,12 +3786,11 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
+ }
+
+ /* parse the argument line ourself */
+- if (parseargline(str, &a1, &a2, &a3)) {
++ if (parseargline(str, &a1, &a2, &a2_end, &a3)) {
+ return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str,
+ "'", NULL);
+ }
+
+- /* arg3: optional flags field */
+ newrule->forced_mimetype = NULL;
+ newrule->forced_handler = NULL;
+ newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
+@@ -3777,6 +3799,9 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
+ newrule->cookie = NULL;
+ newrule->skip = 0;
+ newrule->maxrounds = REWRITE_MAX_ROUNDS;
++ newrule->escapes = newrule->noescapes = NULL;
++
++ /* arg3: optional flags field */
+ if (a3 != NULL) {
+ if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
+ cmd_rewriterule_setflag)) != NULL) {
+@@ -3810,6 +3835,17 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
+ newrule->flags |= RULEFLAG_NOSUB;
+ }
+
++ if (*(a2_end-1) == '?') {
++ /* a literal ? at the end of the unsubstituted rewrite rule */
++ newrule->flags |= RULEFLAG_QSNONE;
++ *(a2_end-1) = '\0'; /* trailing ? has done its job */
++ }
++ else if (newrule->flags & RULEFLAG_QSDISCARD) {
++ if (NULL == ap_strchr(newrule->output, '?')) {
++ newrule->flags |= RULEFLAG_QSNONE;
++ }
++ }
++
+ /* now, if the server or per-dir config holds an
+ * array of RewriteCond entries, we take it for us
+ * and clear the array
+@@ -4215,9 +4251,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
+ r->path_info = NULL;
+ }
+
+- splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND,
+- p->flags & RULEFLAG_QSDISCARD,
+- p->flags & RULEFLAG_QSLAST);
++ splitout_queryargs(r, p->flags);
+
+ /* Add the previously stripped per-directory location prefix, unless
+ * (1) it's an absolute URL path and
+@@ -4696,8 +4730,25 @@ static int hook_uri2file(request_rec *r)
+ }
+
+ if (rulestatus) {
+- unsigned skip;
+- apr_size_t flen;
++ unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
++ apr_size_t flen = r->filename ? strlen(r->filename) : 0;
++ int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
++ int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
++
++ if (r->args
++ && !will_escape
++ && *(ap_scan_vchar_obstext(r->args))) {
++ /*
++ * We have a raw control character or a ' ' in r->args.
++ * Correct encoding was missed.
++ * Correct encoding was missed and we're not going to escape
++ * it before returning.
++ */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410)
++ "Rewritten query string contains control "
++ "characters or spaces");
++ return HTTP_FORBIDDEN;
++ }
+
+ if (ACTION_STATUS == rulestatus) {
+ int n = r->status;
+@@ -4706,8 +4757,7 @@ static int hook_uri2file(request_rec *r)
+ return n;
+ }
+
+- flen = r->filename ? strlen(r->filename) : 0;
+- if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
++ if (to_proxyreq) {
+ /* it should be go on as an internal proxy request */
+
+ /* check if the proxy module is enabled, so
+@@ -4749,7 +4799,7 @@ static int hook_uri2file(request_rec *r)
+ r->filename));
+ return OK;
+ }
+- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
++ else if (skip_absolute > 0) {
+ int n;
+
+ /* it was finally rewritten to a remote URL */
+@@ -4757,7 +4807,7 @@ static int hook_uri2file(request_rec *r)
+ if (rulestatus != ACTION_NOESCAPE) {
+ rewritelog((r, 1, NULL, "escaping %s for redirect",
+ r->filename));
+- r->filename = escape_absolute_uri(r->pool, r->filename, skip);
++ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
+ }
+
+ /* append the QUERY_STRING part */
+@@ -4981,7 +5031,26 @@ static int hook_fixup(request_rec *r)
+ */
+ rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory);
+ if (rulestatus) {
+- unsigned skip;
++ unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
++ int to_proxyreq = 0;
++ int will_escape = 0;
++
++ l = strlen(r->filename);
++ to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0;
++ will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
++
++ if (r->args
++ && !will_escape
++ && *(ap_scan_vchar_obstext(r->args))) {
++ /*
++ * We have a raw control character or a ' ' in r->args.
++ * Correct encoding was missed.
++ */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411)
++ "Rewritten query string contains control "
++ "characters or spaces");
++ return HTTP_FORBIDDEN;
++ }
+
+ if (ACTION_STATUS == rulestatus) {
+ int n = r->status;
+@@ -4990,8 +5059,7 @@ static int hook_fixup(request_rec *r)
+ return n;
+ }
+
+- l = strlen(r->filename);
+- if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
++ if (to_proxyreq) {
+ /* it should go on as an internal proxy request */
+
+ /* make sure the QUERY_STRING and
+@@ -5015,7 +5083,7 @@ static int hook_fixup(request_rec *r)
+ "%s [OK]", r->filename));
+ return OK;
+ }
+- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
++ else if (skip_absolute > 0) {
+ /* it was finally rewritten to a remote URL */
+
+ /* because we are in a per-dir context
+@@ -5024,7 +5092,7 @@ static int hook_fixup(request_rec *r)
+ */
+ if (dconf->baseurl != NULL) {
+ /* skip 'scheme://' */
+- cp = r->filename + skip;
++ cp = r->filename + skip_absolute;
+
+ if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) {
+ rewritelog((r, 2, dconf->directory,
+@@ -5069,7 +5137,7 @@ static int hook_fixup(request_rec *r)
+ if (rulestatus != ACTION_NOESCAPE) {
+ rewritelog((r, 1, dconf->directory, "escaping %s for redirect",
+ r->filename));
+- r->filename = escape_absolute_uri(r->pool, r->filename, skip);
++ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
+ }
+
+ /* append the QUERY_STRING part */
+diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
+index 6faabea..59396a8 100644
+--- a/modules/proxy/mod_proxy_ajp.c
++++ b/modules/proxy/mod_proxy_ajp.c
+@@ -69,6 +69,16 @@ static int proxy_ajp_canon(request_rec *r, char *url)
+ path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
+ r->proxyreq);
+ search = r->args;
++ if (search && *(ap_scan_vchar_obstext(search))) {
++ /*
++ * We have a raw control character or a ' ' in r->args.
++ * Correct encoding was missed.
++ */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406)
++ "To be forwarded query string contains control "
++ "characters or spaces");
++ return HTTP_FORBIDDEN;
++ }
+ }
+ if (path == NULL)
+ return HTTP_BAD_REQUEST;
+diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
+index 3a28038..c599e1a 100644
+--- a/modules/proxy/mod_proxy_balancer.c
++++ b/modules/proxy/mod_proxy_balancer.c
+@@ -106,6 +106,16 @@ static int proxy_balancer_canon(request_rec *r, char *url)
+ path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
+ r->proxyreq);
+ search = r->args;
++ if (search && *(ap_scan_vchar_obstext(search))) {
++ /*
++ * We have a raw control character or a ' ' in r->args.
++ * Correct encoding was missed.
++ */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10407)
++ "To be forwarded query string contains control "
++ "characters or spaces");
++ return HTTP_FORBIDDEN;
++ }
+ }
+ if (path == NULL)
+ return HTTP_BAD_REQUEST;
+diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
+index 7da9bde..2cdc61e 100644
+--- a/modules/proxy/mod_proxy_http.c
++++ b/modules/proxy/mod_proxy_http.c
+@@ -90,6 +90,16 @@ static int proxy_http_canon(request_rec *r, char *url)
+ path = ap_proxy_canonenc(r->pool, url, strlen(url),
+ enc_path, 0, r->proxyreq);
+ search = r->args;
++ if (search && *(ap_scan_vchar_obstext(search))) {
++ /*
++ * We have a raw control character or a ' ' in r->args.
++ * Correct encoding was missed.
++ */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408)
++ "To be forwarded query string contains control "
++ "characters or spaces");
++ return HTTP_FORBIDDEN;
++ }
+ }
+ break;
+ case PROXYREQ_PROXY:
+diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
+index e005a94..f5e27d9 100644
+--- a/modules/proxy/mod_proxy_wstunnel.c
++++ b/modules/proxy/mod_proxy_wstunnel.c
+@@ -77,6 +77,16 @@ static int proxy_wstunnel_canon(request_rec *r, char *url)
+ path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
+ r->proxyreq);
+ search = r->args;
++ if (search && *(ap_scan_vchar_obstext(search))) {
++ /*
++ * We have a raw control character or a ' ' in r->args.
++ * Correct encoding was missed.
++ */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409)
++ "To be forwarded query string contains control "
++ "characters or spaces");
++ return HTTP_FORBIDDEN;
++ }
+ }
+ if (path == NULL)
+ return HTTP_BAD_REQUEST;
+diff --git a/server/gen_test_char.c b/server/gen_test_char.c
+index 48ae6f4..6a153a3 100644
+--- a/server/gen_test_char.c
++++ b/server/gen_test_char.c
+@@ -169,5 +169,15 @@ int main(int argc, char *argv[])
+
+ printf("\n};\n");
+
++
++ printf(
++ "/* we assume the folks using this ensure 0 <= c < 256... which means\n"
++ " * you need a cast to (unsigned char) first, you can't just plug a\n"
++ " * char in here and get it to work, because if char is signed then it\n"
++ " * will first be sign extended.\n"
++ " */\n"
++ "#define TEST_CHAR(c, f) (test_char_table[(unsigned char)(c)] & (f))\n"
++ );
++
+ return 0;
+ }
+diff --git a/server/util.c b/server/util.c
+index 2a5dd04..1d82fd8 100644
+--- a/server/util.c
++++ b/server/util.c
+@@ -74,13 +74,6 @@
+ */
+ #include "test_char.h"
+
+-/* we assume the folks using this ensure 0 <= c < 256... which means
+- * you need a cast to (unsigned char) first, you can't just plug a
+- * char in here and get it to work, because if char is signed then it
+- * will first be sign extended.
+- */
+-#define TEST_CHAR(c, f) (test_char_table[(unsigned char)(c)] & (f))
+-
+ /* Win32/NetWare/OS2 need to check for both forward and back slashes
+ * in ap_getparents() and ap_escape_url.
+ */
diff --git a/SOURCES/httpd-2.4.37-add-SNI-support.patch b/SOURCES/httpd-2.4.37-add-SNI-support.patch
new file mode 100644
index 0000000..8b8d9ad
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-add-SNI-support.patch
@@ -0,0 +1,92 @@
+commit 4c0e27d7bfbf46f14dfbd5d888e56c64ad8c8de5
+Author: Tomas Korbar
+Date: Mon Sep 19 13:22:27 2022 +0200
+
+ Backport refactor of SNI support to httpd-2.4.37
+
+diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c
+index a7e0dcd..31ccd32 100644
+--- a/modules/http2/mod_proxy_http2.c
++++ b/modules/http2/mod_proxy_http2.c
+@@ -591,16 +591,6 @@ run_connect:
+ }
+
+ if (!ctx->p_conn->data) {
+- /* New conection: set a note on the connection what CN is
+- * requested and what protocol we want */
+- if (ctx->p_conn->ssl_hostname) {
+- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, ctx->owner,
+- "set SNI to %s for (%s)",
+- ctx->p_conn->ssl_hostname,
+- ctx->p_conn->hostname);
+- apr_table_setn(ctx->p_conn->connection->notes,
+- "proxy-request-hostname", ctx->p_conn->ssl_hostname);
+- }
+ if (ctx->is_ssl) {
+ apr_table_setn(ctx->p_conn->connection->notes,
+ "proxy-request-alpn-protos", "h2");
+diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
+index 1b7bb81..c1c591a 100644
+--- a/modules/proxy/mod_proxy_http.c
++++ b/modules/proxy/mod_proxy_http.c
+@@ -2111,19 +2111,6 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
+ req->origin->keepalive = AP_CONN_CLOSE;
+ }
+
+- /*
+- * On SSL connections set a note on the connection what CN is
+- * requested, such that mod_ssl can check if it is requested to do
+- * so.
+- *
+- * https://github.com/apache/httpd/commit/7d272e2628b4ae05f68cdc74b070707250896a34
+- */
+- if (backend->ssl_hostname) {
+- apr_table_setn(backend->connection->notes,
+- "proxy-request-hostname",
+- backend->ssl_hostname);
+- }
+-
+ /* Step Four: Send the Request
+ * On the off-chance that we forced a 100-Continue as a
+ * kinda HTTP ping test, allow for retries
+diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
+index ec9a414..805820d 100644
+--- a/modules/proxy/proxy_util.c
++++ b/modules/proxy/proxy_util.c
+@@ -3261,6 +3261,16 @@ static int proxy_connection_create(const char *proxy_function,
+ backend_addr, conn->hostname);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
++ if (conn->ssl_hostname) {
++ /* Set a note on the connection about what CN is requested,
++ * such that mod_ssl can check if it is requested to do so.
++ */
++ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, conn->connection,
++ "%s: set SNI to %s for (%s)", proxy_function,
++ conn->ssl_hostname, conn->hostname);
++ apr_table_setn(conn->connection->notes, "proxy-request-hostname",
++ conn->ssl_hostname);
++ }
+ }
+ else {
+ /* TODO: See if this will break FTP */
+diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
+index 4e3875a..9b4280c 100644
+--- a/modules/ssl/ssl_engine_io.c
++++ b/modules/ssl/ssl_engine_io.c
+@@ -1273,7 +1273,6 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
+ ((dc->proxy->ssl_check_peer_cn != FALSE) ||
+ (dc->proxy->ssl_check_peer_name == TRUE)) &&
+ hostname_note) {
+- apr_table_unset(c->notes, "proxy-request-hostname");
+ if (!cert
+ || modssl_X509_match_name(c->pool, cert, hostname_note,
+ TRUE, server) == FALSE) {
+@@ -1290,7 +1289,6 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
+
+ hostname = ssl_var_lookup(NULL, server, c, NULL,
+ "SSL_CLIENT_S_DN_CN");
+- apr_table_unset(c->notes, "proxy-request-hostname");
+
+ /* Do string match or simplest wildcard match if that
+ * fails. */
diff --git a/SOURCES/httpd-init.service b/SOURCES/httpd-init.service
index 3074778..704c314 100644
--- a/SOURCES/httpd-init.service
+++ b/SOURCES/httpd-init.service
@@ -8,5 +8,6 @@ ConditionPathExists=|!/etc/pki/tls/private/localhost.key
[Service]
Type=oneshot
RemainAfterExit=no
+PrivateTmp=true
ExecStart=/usr/libexec/httpd-ssl-gencerts
diff --git a/SOURCES/httpd-ssl-gencerts b/SOURCES/httpd-ssl-gencerts
index 350f5b5..5c271f7 100755
--- a/SOURCES/httpd-ssl-gencerts
+++ b/SOURCES/httpd-ssl-gencerts
@@ -33,6 +33,7 @@ sscg -q \
--cert-file /etc/pki/tls/certs/localhost.crt \
--cert-key-file /etc/pki/tls/private/localhost.key \
--ca-file /etc/pki/tls/certs/localhost.crt \
+ --dhparams-file /tmp/dhparams.pem \
--lifetime 365 \
--hostname $FQDN \
--email root@$FQDN
diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec
index 3764348..c29fbb4 100644
--- a/SPECS/httpd.spec
+++ b/SPECS/httpd.spec
@@ -3,7 +3,7 @@
%define suexec_caller apache
%define mmn 20120211
%define mmnisa %{mmn}%{__isa_name}%{__isa_bits}
-%define vstring %(source /etc/os-release; echo ${NAME})
+%define vstring %(source /etc/os-release; echo ${REDHAT_SUPPORT_PRODUCT})
%if 0%{?fedora} > 26 || 0%{?rhel} > 7
%global mpm event
%else
@@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.37
-Release: 47%{?dist}.2.alma.1
+Release: 56%{?dist}.6.alma
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source2: httpd.logrotate
@@ -163,6 +163,8 @@ Patch88: httpd-2.4.37-r1845768+.patch
Patch89: httpd-2.4.37-r1862410.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1984828
Patch90: httpd-2.4.37-hcheck-mem-issues.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2017543
+Patch91: httpd-2.4.37-add-SNI-support.patch
# Security fixes
Patch200: httpd-2.4.37-r1851471.patch
@@ -218,6 +220,34 @@ Patch222: httpd-2.4.37-CVE-2021-44224.patch
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
+# https://bugzilla.redhat.com/show_bug.cgi?id=2161773
+Patch235: httpd-2.4.37-CVE-2022-37436.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2161774
+Patch236: httpd-2.4.37-CVE-2006-20001.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2161777
+Patch237: httpd-2.4.37-CVE-2022-36760.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2176209
+Patch238: httpd-2.4.37-CVE-2023-25690.patch
# AlmaLinux patches
Patch1000: httpd-2.4.37-CVE-2023-27522.patch
@@ -238,7 +268,7 @@ 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: mod_http2
+Requires: mod_http2 >= 1.15.7-5
Requires(pre): httpd-filesystem
Requires(preun): systemd-units
Requires(postun): systemd-units
@@ -302,7 +332,7 @@ Epoch: 1
BuildRequires: openssl-devel
Requires(pre): httpd-filesystem
Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
-Requires: sscg >= 2.2.0
+Requires: sscg >= 3.0.0-7, /usr/bin/hostname
Obsoletes: stronghold-mod_ssl
# Require an OpenSSL which supports PROFILE=SYSTEM
Conflicts: openssl-libs < 1:1.0.1h-4
@@ -401,6 +431,7 @@ interface for storing and accessing per-user session data.
%patch88 -p1 -b .r1845768+
%patch89 -p1 -b .r1862410
%patch90 -p1 -b .hcheck-mem-issues
+%patch91 -p1 -b .SNI
%patch200 -p1 -b .r1851471
%patch201 -p1 -b .CVE-2019-0211
@@ -427,6 +458,20 @@ interface for storing and accessing per-user session data.
%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
+%patch235 -p1 -b .CVE-2022-37436
+%patch236 -p1 -b .CVE-2006-20001
+%patch237 -p1 -b .CVE-2022-36760
+%patch238 -p1 -b .CVE-2023-25690
# AlmaLinux patches
%patch1000 -p1 -b .CVE-2023-27522
@@ -935,26 +980,69 @@ rm -rf $RPM_BUILD_ROOT
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
-* Tue Aug 01 2023 Eduard Abdullin - 2.4.37-47.2.alma.1
+* Tue Aug 01 2023 Eduard Abdullin - 2.4.37-56.6.alma
- Add patch to fix CVE-2023-27522
-* Wed Jun 22 2022 Andrew Lukoshko - 2.4.37-47.2.alma
-- include AlmaLinux in version string
+* Thu Apr 27 2023 Luboš Uhliarik - 2.4.37-56.6
+- Resolves: #2190133 - mod_rewrite regression with CVE-2023-25690
-* Wed Jun 15 2022 Luboš Uhliarik - 2.4.37-47.2
-- Resolves: #2097247 - CVE-2020-13950 httpd:2.4/httpd: mod_proxy NULL pointer
+* Sat Mar 18 2023 Luboš Uhliarik - 2.4.37-56.4
+- Resolves: #2177748 - CVE-2023-25690 httpd:2.4/httpd: HTTP request splitting
+ with mod_rewrite and mod_proxy
+
+* Tue Jan 31 2023 Luboš Uhliarik - 2.4.37-56
+- Resolves: #2162499 - CVE-2006-20001 httpd: mod_dav: out-of-bounds read/write
+ of zero byte
+- Resolves: #2162485 - CVE-2022-37436 httpd: mod_proxy: HTTP response splitting
+- Resolves: #2162509 - CVE-2022-36760 httpd: mod_proxy_ajp: Possible request
+ smuggling
+
+* Thu Jan 26 2023 Luboš Uhliarik - 2.4.37-55
+- Resolves: #2155961 - prevent sscg creating /dhparams.pem
+
+* Thu Dec 08 2022 Luboš Uhliarik - 2.4.37-54
+- Resolves: #2095650 - Dependency from mod_http2 on httpd broken
+
+* Wed Nov 09 2022 Luboš Uhliarik - 2.4.37-53
+- Resolves: #2050888 - httpd with SSL fails to start unless hostname command
+ was installed
+
+* Mon Sep 19 2022 Tomas Korbar - 2.4.37-52
+- Add the SNI support in mod_proxy_wstunnel module for Apache httpd
+- Resolves: rhbz#2017543
+
+* 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-47.1
-- Resolves: #2065248 - CVE-2022-22720 httpd:2.4/httpd: HTTP request smuggling
+* 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
-* Fri Feb 25 2022 Luboš Uhliarik - 2.4.37-43.2
-- Resolves: #2059256 - CVE-2021-34798 httpd:2.4/httpd: NULL pointer dereference
- via malformed requests
-- Resolves: #2059257 - CVE-2021-39275 httpd:2.4/httpd: out-of-bounds write in
- ap_escape_quotes() via malicious input
-
* Thu Jan 20 2022 Luboš Uhliarik - 2.4.37-47
- Resolves: #2035030 - CVE-2021-44224 httpd:2.4/httpd: possible NULL dereference
or SSRF in forward proxy configurations