summaryrefslogtreecommitdiffstats
path: root/debian/patches/CVE-2022-30556.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/CVE-2022-30556.patch')
-rw-r--r--debian/patches/CVE-2022-30556.patch250
1 files changed, 250 insertions, 0 deletions
diff --git a/debian/patches/CVE-2022-30556.patch b/debian/patches/CVE-2022-30556.patch
new file mode 100644
index 0000000..f9b541d
--- /dev/null
+++ b/debian/patches/CVE-2022-30556.patch
@@ -0,0 +1,250 @@
+From 3a561759fcb37af179585adb8478922dc9bc6a85 Mon Sep 17 00:00:00 2001
+From: Eric Covener <covener@apache.org>
+Date: Wed, 1 Jun 2022 12:36:39 +0000
+Subject: [PATCH] Merge r1901502 from trunk:
+
+use filters consistently
+
+
+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901503 13f79535-47bb-0310-9956-ffa450edef68
+Origin: https://github.com/apache/httpd/commit/3a561759fcb37af179585adb8478922dc9bc6a85
+---
+ modules/lua/lua_request.c | 144 ++++++++++++++------------------------
+ 1 file changed, 53 insertions(+), 91 deletions(-)
+
+diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
+index a3e3b613bc..2ec453e86b 100644
+--- a/modules/lua/lua_request.c
++++ b/modules/lua/lua_request.c
+@@ -2227,23 +2227,20 @@ static int lua_websocket_greet(lua_State *L)
+ return 0;
+ }
+
+-static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer,
+- apr_off_t len)
++static apr_status_t lua_websocket_readbytes(conn_rec* c,
++ apr_bucket_brigade *brigade,
++ char* buffer, apr_off_t len)
+ {
+- apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc);
++ apr_size_t delivered;
+ apr_status_t rv;
++
+ rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES,
+ APR_BLOCK_READ, len);
+ if (rv == APR_SUCCESS) {
+- if (!APR_BRIGADE_EMPTY(brigade)) {
+- apr_bucket* bucket = APR_BRIGADE_FIRST(brigade);
+- const char* data = NULL;
+- apr_size_t data_length = 0;
+- rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ);
+- if (rv == APR_SUCCESS) {
+- memcpy(buffer, data, len);
+- }
+- apr_bucket_delete(bucket);
++ delivered = len;
++ rv = apr_brigade_flatten(brigade, buffer, &delivered);
++ if ((rv == APR_SUCCESS) && (delivered < len)) {
++ rv = APR_INCOMPLETE;
+ }
+ }
+ apr_brigade_cleanup(brigade);
+@@ -2273,35 +2270,28 @@ static int lua_websocket_peek(lua_State *L)
+
+ static int lua_websocket_read(lua_State *L)
+ {
+- apr_socket_t *sock;
+ apr_status_t rv;
+ int do_read = 1;
+ int n = 0;
+- apr_size_t len = 1;
+ apr_size_t plen = 0;
+ unsigned short payload_short = 0;
+ apr_uint64_t payload_long = 0;
+ unsigned char *mask_bytes;
+ char byte;
+- int plaintext;
+-
+-
++ apr_bucket_brigade *brigade;
++ conn_rec* c;
++
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
++ c = r->connection;
+
+-
+ mask_bytes = apr_pcalloc(r->pool, 4);
+- sock = ap_get_conn_socket(r->connection);
++
++ brigade = apr_brigade_create(r->pool, c->bucket_alloc);
+
+ while (do_read) {
+ do_read = 0;
+ /* Get opcode and FIN bit */
+- if (plaintext) {
+- rv = apr_socket_recv(sock, &byte, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection, &byte, 1);
+- }
++ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
+ if (rv == APR_SUCCESS) {
+ unsigned char ubyte, fin, opcode, mask, payload;
+ ubyte = (unsigned char)byte;
+@@ -2311,12 +2301,7 @@ static int lua_websocket_read(lua_State *L)
+ opcode = ubyte & 0xf;
+
+ /* Get the payload length and mask bit */
+- if (plaintext) {
+- rv = apr_socket_recv(sock, &byte, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection, &byte, 1);
+- }
++ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
+ if (rv == APR_SUCCESS) {
+ ubyte = (unsigned char)byte;
+ /* Mask is the first bit */
+@@ -2327,40 +2312,25 @@ static int lua_websocket_read(lua_State *L)
+
+ /* Extended payload? */
+ if (payload == 126) {
+- len = 2;
+- if (plaintext) {
+- /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
+- rv = apr_socket_recv(sock, (char*) &payload_short, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection,
+- (char*) &payload_short, 2);
+- }
+- payload_short = ntohs(payload_short);
++ rv = lua_websocket_readbytes(c, brigade,
++ (char*) &payload_short, 2);
+
+- if (rv == APR_SUCCESS) {
+- plen = payload_short;
+- }
+- else {
++ if (rv != APR_SUCCESS) {
+ return 0;
+ }
++
++ plen = ntohs(payload_short);
+ }
+ /* Super duper extended payload? */
+ if (payload == 127) {
+- len = 8;
+- if (plaintext) {
+- rv = apr_socket_recv(sock, (char*) &payload_long, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection,
+- (char*) &payload_long, 8);
+- }
+- if (rv == APR_SUCCESS) {
+- plen = ap_ntoh64(&payload_long);
+- }
+- else {
++ rv = lua_websocket_readbytes(c, brigade,
++ (char*) &payload_long, 8);
++
++ if (rv != APR_SUCCESS) {
+ return 0;
+ }
++
++ plen = ap_ntoh64(&payload_long);
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
+ "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s",
+@@ -2369,46 +2339,27 @@ static int lua_websocket_read(lua_State *L)
+ mask ? "on" : "off",
+ fin ? "This is a final frame" : "more to follow");
+ if (mask) {
+- len = 4;
+- if (plaintext) {
+- rv = apr_socket_recv(sock, (char*) mask_bytes, &len);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection,
+- (char*) mask_bytes, 4);
+- }
++ rv = lua_websocket_readbytes(c, brigade,
++ (char*) mask_bytes, 4);
++
+ if (rv != APR_SUCCESS) {
+ return 0;
+ }
+ }
+ if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
+ apr_size_t remaining = plen;
+- apr_size_t received;
+- apr_off_t at = 0;
+ char *buffer = apr_palloc(r->pool, plen+1);
+ buffer[plen] = 0;
+
+- if (plaintext) {
+- while (remaining > 0) {
+- received = remaining;
+- rv = apr_socket_recv(sock, buffer+at, &received);
+- if (received > 0 ) {
+- remaining -= received;
+- at += received;
+- }
+- }
+- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+- "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack",
+- at);
+- }
+- else {
+- rv = lua_websocket_readbytes(r->connection, buffer,
+- remaining);
+- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+- "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\
+- "pushed to Lua stack",
+- remaining);
++ rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
++
++ if (rv != APR_SUCCESS) {
++ return 0;
+ }
++
++ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
++ "Websocket: Frame contained %" APR_SIZE_T_FMT \
++ " bytes, pushed to Lua stack", remaining);
+ if (mask) {
+ for (n = 0; n < plen; n++) {
+ buffer[n] ^= mask_bytes[n%4];
+@@ -2420,14 +2371,25 @@ static int lua_websocket_read(lua_State *L)
+ return 2;
+ }
+
+-
+ /* Decide if we need to react to the opcode or not */
+ if (opcode == 0x09) { /* ping */
+ char frame[2];
+- plen = 2;
++ apr_bucket *b;
++
+ frame[0] = 0x8A;
+ frame[1] = 0;
+- apr_socket_send(sock, frame, &plen); /* Pong! */
++
++ /* Pong! */
++ b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
++ APR_BRIGADE_INSERT_TAIL(brigade, b);
++
++ rv = ap_pass_brigade(c->output_filters, brigade);
++ apr_brigade_cleanup(brigade);
++
++ if (rv != APR_SUCCESS) {
++ return 0;
++ }
++
+ do_read = 1;
+ }
+ }
+--
+2.30.2
+