!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:
openeuler-ci-bot 2022-06-20 11:06:03 +00:00 committed by Gitee
commit 01ba7ead28
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 1096 additions and 1 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -8,7 +8,7 @@
Name: httpd
Summary: Apache HTTP Server
Version: 2.4.51
Release: 4
Release: 5
License: ASL 2.0
URL: https://httpd.apache.org/
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
Patch26: backport-002-CVE-2021-44224.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: zlib-devel libselinux-devel lua-devel brotli-devel
@ -510,6 +516,12 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%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
- Type:CVE
- ID:NA