!98 fix CVE2022-31813、CVE-2022-28614、CVE-2022-30522、CVE-2022-30556、CVE-2022-29404、CVE-2022-26377
From: @chengyechun Reviewed-by: @seuzw Signed-off-by: @seuzw
This commit is contained in:
commit
01ba7ead28
38
backport-CVE-2022-26377.patch
Normal file
38
backport-CVE-2022-26377.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From f7f15f3d8bfe3032926c8c39eb8434529f680bd4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ylavic <ylavic@apache.org>
|
||||||
|
Date: Wed Jun 1 13:48:21 2022 UTC
|
||||||
|
Subject: [PATCH] mod_proxy_ajp: T-E has precedence over C-L.
|
||||||
|
|
||||||
|
---
|
||||||
|
modules/proxy/mod_proxy_ajp.c | 15 ++++++++++++---
|
||||||
|
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
|
||||||
|
index e2992fc..a77a86b 100644
|
||||||
|
--- a/modules/proxy/mod_proxy_ajp.c
|
||||||
|
+++ b/modules/proxy/mod_proxy_ajp.c
|
||||||
|
@@ -246,9 +246,18 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
|
||||||
|
/* read the first block of data */
|
||||||
|
input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
|
||||||
|
tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
|
||||||
|
- if (tenc && (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");
|
||||||
|
+ 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);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
60
backport-CVE-2022-28614.patch
Normal file
60
backport-CVE-2022-28614.patch
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
From 8c14927162cf3b4f810683e1c5505e9ef9e1f123 Mon Sep 17 00:00:00 2001
|
||||||
|
From: covener <covener@apache.org>
|
||||||
|
Date: Wed Jun 1 07:51:04 2022 UTC
|
||||||
|
Subject: [PATCH] handle large writes in ap_rputs
|
||||||
|
|
||||||
|
---
|
||||||
|
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 20bd202..94c481e 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 298f61e..7adc7f7 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;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
88
backport-CVE-2022-29404.patch
Normal file
88
backport-CVE-2022-29404.patch
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
From 92499e20034485c5e2d29cb85940e309573d976e Mon Sep 17 00:00:00 2001
|
||||||
|
From: covener <covener@apache.org>
|
||||||
|
Date: Wed Jun 1 12:30:46 2022 UTC
|
||||||
|
Subject: [PATCH] use a liberal default limit for LimitRequestBody of 1GB
|
||||||
|
|
||||||
|
---
|
||||||
|
modules/http/http_filters.c | 8 +++++++-
|
||||||
|
modules/proxy/proxy_util.c | 13 -------------
|
||||||
|
server/core.c | 2 +-
|
||||||
|
3 files changed, 8 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
|
||||||
|
index 3e02da8..c3eab95 100644
|
||||||
|
--- a/modules/http/http_filters.c
|
||||||
|
+++ b/modules/http/http_filters.c
|
||||||
|
@@ -1700,7 +1700,8 @@ 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;
|
||||||
|
r->remaining = 0;
|
||||||
|
@@ -1735,6 +1736,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 4f1610f..04733f2 100644
|
||||||
|
--- a/modules/proxy/proxy_util.c
|
||||||
|
+++ b/modules/proxy/proxy_util.c
|
||||||
|
@@ -4249,12 +4249,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)) {
|
||||||
|
@@ -4273,17 +4271,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 957eeff..515047b 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)
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
408
backport-CVE-2022-30522.patch
Normal file
408
backport-CVE-2022-30522.patch
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
From 65b8fb947b144556c7ad1cf7ddc3941010ad77ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: covener <covener@apache.org>
|
||||||
|
Date: Wed Jun 1 12:40:09 2022 UTC
|
||||||
|
Subject: [PATCH] limit mod_sed memory use
|
||||||
|
|
||||||
|
---
|
||||||
|
modules/filters/sed1.c | 156 +++++++++++++++++++++++++++++++++++--------------
|
||||||
|
1 file changed, 113 insertions(+), 43 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c
|
||||||
|
index 67a8d06..a08068e 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,
|
||||||
|
+ rc = grow_buffer(eval->pool, &eval->genbuf, gspend,
|
||||||
|
&eval->gsize, newsize);
|
||||||
|
- eval->lcomend = &eval->genbuf[71];
|
||||||
|
+ 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:
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
246
backport-CVE-2022-30556.patch
Normal file
246
backport-CVE-2022-30556.patch
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
From 11a3fcbf9e64239d8fe8402d941bbdcbc4532c88 Mon Sep 17 00:00:00 2001
|
||||||
|
From: covener <covener@apache.org>
|
||||||
|
Date: Wed Jun 1 12:36:13 2022 UTC
|
||||||
|
Subject: [PATCH] use filters consistently
|
||||||
|
|
||||||
|
---
|
||||||
|
modules/lua/lua_request.c | 145 +++++++++++++++++-----------------------------
|
||||||
|
1 file changed, 54 insertions(+), 91 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
|
||||||
|
index 1eab7b6..a7e501b 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,29 @@ 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;
|
||||||
|
-
|
||||||
|
|
||||||
|
- request_rec *r = ap_lua_check_request_rec(L, 1);
|
||||||
|
- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
|
||||||
|
+ apr_bucket_brigade *brigade;
|
||||||
|
+ conn_rec* c;
|
||||||
|
|
||||||
|
+ request_rec *r = ap_lua_check_request_rec(L, 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 +2302,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 +2313,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);
|
||||||
|
-
|
||||||
|
- if (rv == APR_SUCCESS) {
|
||||||
|
- plen = payload_short;
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
+ rv = lua_websocket_readbytes(c, brigade,
|
||||||
|
+ (char*) &payload_short, 2);
|
||||||
|
+
|
||||||
|
+ 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 +2340,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 +2372,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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
243
backport-CVE-2022-31813.patch
Normal file
243
backport-CVE-2022-31813.patch
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
From 956f708b094698ac9ad570d640d4f30eb0df7305 Mon Sep 17 00:00:00 2001
|
||||||
|
From: icing <icing@apache.org>
|
||||||
|
Date: Wed Jun 1 07:51:04 2022 UTC
|
||||||
|
Subject: [PATCH] mod_proxy: ap_proxy_create_hdrbrgd() to clear hop-by-hop first and fixup last.
|
||||||
|
|
||||||
|
---
|
||||||
|
modules/proxy/proxy_util.c | 155 +++++++++++++++++++++++----------------------
|
||||||
|
1 file changed, 78 insertions(+), 77 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||||
|
index d578452..4f1610f 100644
|
||||||
|
--- a/modules/proxy/proxy_util.c
|
||||||
|
+++ b/modules/proxy/proxy_util.c
|
||||||
|
@@ -3849,12 +3849,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;
|
||||||
|
@@ -3890,6 +3892,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) {
|
||||||
|
@@ -3911,7 +3959,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)
|
||||||
|
@@ -3925,22 +3973,8 @@ 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) {
|
||||||
|
/* Block all outgoing Via: headers */
|
||||||
|
@@ -4006,8 +4040,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.
|
||||||
|
*/
|
||||||
|
@@ -4017,8 +4049,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
|
||||||
|
@@ -4029,67 +4062,37 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||||
|
r->server->server_hostname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* 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");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- proxy_run_fixups(r);
|
||||||
|
- if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
|
||||||
|
- return HTTP_BAD_REQUEST;
|
||||||
|
+ /* 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);
|
||||||
|
|
||||||
|
/* send request headers */
|
||||||
|
headers_in_array = apr_table_elts(r->headers_in);
|
||||||
|
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")
|
||||||
|
-
|
||||||
|
- ) {
|
||||||
|
+ || headers_in[counter].val == NULL) {
|
||||||
|
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;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
|
||||||
|
buf = apr_pstrcat(p, headers_in[counter].key, ": ",
|
||||||
|
headers_in[counter].val, CRLF,
|
||||||
|
@@ -4099,11 +4102,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,
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
14
httpd.spec
14
httpd.spec
@ -8,7 +8,7 @@
|
|||||||
Name: httpd
|
Name: httpd
|
||||||
Summary: Apache HTTP Server
|
Summary: Apache HTTP Server
|
||||||
Version: 2.4.51
|
Version: 2.4.51
|
||||||
Release: 4
|
Release: 5
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
URL: https://httpd.apache.org/
|
URL: https://httpd.apache.org/
|
||||||
Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2
|
Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2
|
||||||
@ -78,6 +78,12 @@ Patch24: backport-CVE-2021-44790.patch
|
|||||||
Patch25: backport-001-CVE-2021-44224.patch
|
Patch25: backport-001-CVE-2021-44224.patch
|
||||||
Patch26: backport-002-CVE-2021-44224.patch
|
Patch26: backport-002-CVE-2021-44224.patch
|
||||||
Patch27: backport-CVE-2022-28615.patch
|
Patch27: backport-CVE-2022-28615.patch
|
||||||
|
Patch28: backport-CVE-2022-31813.patch
|
||||||
|
Patch29: backport-CVE-2022-28614.patch
|
||||||
|
Patch30: backport-CVE-2022-29404.patch
|
||||||
|
Patch31: backport-CVE-2022-26377.patch
|
||||||
|
Patch32: backport-CVE-2022-30522.patch
|
||||||
|
Patch33: backport-CVE-2022-30556.patch
|
||||||
|
|
||||||
BuildRequires: gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel
|
BuildRequires: gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel
|
||||||
BuildRequires: zlib-devel libselinux-devel lua-devel brotli-devel
|
BuildRequires: zlib-devel libselinux-devel lua-devel brotli-devel
|
||||||
@ -510,6 +516,12 @@ exit $rv
|
|||||||
%{_rpmconfigdir}/macros.d/macros.httpd
|
%{_rpmconfigdir}/macros.d/macros.httpd
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jun 20 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-5
|
||||||
|
- Type:CVE
|
||||||
|
- ID:NA
|
||||||
|
- SUG:restart
|
||||||
|
- DESC:fix CVE-2022-31813,CVE-2022-28614,CVE-2022-29404,CVE-2022-26377,CVE-2022-30522,CVE-2022-30556
|
||||||
|
|
||||||
* Mon Jun 20 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-4
|
* Mon Jun 20 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-4
|
||||||
- Type:CVE
|
- Type:CVE
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user