diff mbox series

[meta-networking,scarthgap,4/4] memcached: patch CVE-2023-46853

Message ID 20251015034244.1445689-4-ankur.tyagi85@gmail.com
State New
Headers show
Series [meta-networking,scarthgap,1/4] libmemcached: ignore CVE-2023-27478 | expand

Commit Message

Ankur Tyagi Oct. 15, 2025, 3:42 a.m. UTC
Details https://nvd.nist.gov/vuln/detail/CVE-2023-46853

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
 .../memcached/memcached/CVE-2023-46853.patch  | 117 ++++++++++++++++++
 .../memcached/memcached_1.6.17.bb             |   1 +
 2 files changed, 118 insertions(+)
 create mode 100644 meta-networking/recipes-support/memcached/memcached/CVE-2023-46853.patch
diff mbox series

Patch

diff --git a/meta-networking/recipes-support/memcached/memcached/CVE-2023-46853.patch b/meta-networking/recipes-support/memcached/memcached/CVE-2023-46853.patch
new file mode 100644
index 0000000000..cf8aaf467b
--- /dev/null
+++ b/meta-networking/recipes-support/memcached/memcached/CVE-2023-46853.patch
@@ -0,0 +1,117 @@ 
+From 51c1f144d57379bd77f5b04c462171d26ebc5514 Mon Sep 17 00:00:00 2001
+From: dormando <dormando@rydia.net>
+Date: Wed, 2 Aug 2023 15:45:56 -0700
+Subject: [PATCH] CVE-2023-46853
+
+proxy: fix off-by-one if \r is missing
+
+A bunch of the parser assumed we only had \r\n, but I didn't actually
+have that strictness set. Some commands worked and some broke in subtle
+ways when just "\n" was being submitted.
+
+I'm not 100% confident in this change yet so I'm opening a PR to stage
+it while I run some more thorough tests.
+
+CVE: CVE-2023-46853
+Upstream-Status: Backport [https://github.com/memcached/memcached/commit/6987918e9a3094ec4fc8976f01f769f624d790fa]
+(cherry picked from commit 6987918e9a3094ec4fc8976f01f769f624d790fa)
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ proxy.h         |  1 +
+ proxy_request.c | 22 ++++++++++++++++------
+ t/proxy.t       |  5 +++--
+ 3 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/proxy.h b/proxy.h
+index 015c093..29e5175 100644
+--- a/proxy.h
++++ b/proxy.h
+@@ -271,6 +271,7 @@ struct mcp_parser_s {
+     uint8_t keytoken; // because GAT. sigh. also cmds without a key.
+     uint32_t parsed; // how far into the request we parsed already
+     uint32_t reqlen; // full length of request buffer.
++    uint32_t endlen; // index to the start of \r\n or \n
+     int vlen;
+     uint32_t klen; // length of key.
+     uint16_t tokens[PARSER_MAX_TOKENS]; // offsets for start of each token
+diff --git a/proxy_request.c b/proxy_request.c
+index 457e9a1..6351d02 100644
+--- a/proxy_request.c
++++ b/proxy_request.c
+@@ -9,7 +9,7 @@
+ // where we later scan or directly feed data into API's.
+ static int _process_tokenize(mcp_parser_t *pr, const size_t max) {
+     const char *s = pr->request;
+-    int len = pr->reqlen - 2;
++    int len = pr->endlen;
+ 
+     // since multigets can be huge, we can't purely judge reqlen against this
+     // limit, but we also can't index past it since the tokens are shorts.
+@@ -93,7 +93,7 @@ static int _process_request_key(mcp_parser_t *pr) {
+ // Returns the offset for the next key.
+ size_t _process_request_next_key(mcp_parser_t *pr) {
+     const char *cur = pr->request + pr->parsed;
+-    int remain = pr->reqlen - pr->parsed - 2;
++    int remain = pr->endlen - pr->parsed;
+ 
+     // chew off any leading whitespace.
+     while (remain) {
+@@ -126,7 +126,7 @@ static int _process_request_metaflags(mcp_parser_t *pr, int token) {
+         return 0;
+     }
+     const char *cur = pr->request + pr->tokens[token];
+-    const char *end = pr->request + pr->reqlen - 2;
++    const char *end = pr->request + pr->endlen;
+ 
+     // We blindly convert flags into bits, since the range of possible
+     // flags is deliberately < 64.
+@@ -290,15 +290,25 @@ int process_request(mcp_parser_t *pr, const char *command, size_t cmdlen) {
+         return -1;
+     }
+ 
+-    const char *s = memchr(command, ' ', cmdlen-2);
++    // Commands can end with bare '\n's. Depressingly I intended to be strict
++    // with a \r\n requirement but never did this and need backcompat.
++    // In this case we _know_ \n is at cmdlen because we can't enter this
++    // function otherwise.
++    if (cm[cmdlen-2] == '\r') {
++        pr->endlen = cmdlen - 2;
++    } else {
++        pr->endlen = cmdlen - 1;
++    }
++
++    const char *s = memchr(command, ' ', pr->endlen);
+     if (s != NULL) {
+         cl = s - command;
+     } else {
+-        cl = cmdlen - 2;
++        cl = pr->endlen;
+     }
+     pr->keytoken = 0;
+     pr->has_space = false;
+-    pr->parsed = cl + 1;
++    pr->parsed = cl;
+     pr->request = command;
+     pr->reqlen = cmdlen;
+     int token_max = PARSER_MAX_TOKENS;
+diff --git a/t/proxy.t b/t/proxy.t
+index 37caa27..af6213a 100644
+--- a/t/proxy.t
++++ b/t/proxy.t
+@@ -151,13 +151,14 @@ my $p_sock = $p_srv->sock;
+ # NOTE: memcached always allowed [\r]\n for single command lines, but payloads
+ # (set/etc) require exactly \r\n as termination.
+ # doc/protocol.txt has always specified \r\n for command/response.
+-# Proxy is more strict than normal server in this case.
++# Note a bug lead me to believe that the proxy was more strict, we accept any
++# \n or \r\n terminated commands.
+ {
+     my $s = $srv[0]->sock;
+     print $s "version\n";
+     like(<$s>, qr/VERSION/, "direct server version cmd with just newline");
+     print $p_sock "version\n";
+-    like(<$p_sock>, qr/SERVER_ERROR/, "proxy version cmd with just newline");
++    like(<$p_sock>, qr/VERSION/, "proxy version cmd with just newline");
+     print $p_sock "version\r\n";
+     like(<$p_sock>, qr/VERSION/, "proxy version cmd with full CRLF");
+ }
diff --git a/meta-networking/recipes-support/memcached/memcached_1.6.17.bb b/meta-networking/recipes-support/memcached/memcached_1.6.17.bb
index b4c1847bf6..bfa1450368 100644
--- a/meta-networking/recipes-support/memcached/memcached_1.6.17.bb
+++ b/meta-networking/recipes-support/memcached/memcached_1.6.17.bb
@@ -23,6 +23,7 @@  SRC_URI = "http://www.memcached.org/files/${BP}.tar.gz \
            file://memcached-add-hugetlbfs-check.patch \
            file://0001-Fix-function-protypes.patch \
            file://CVE-2023-46852.patch \
+           file://CVE-2023-46853.patch \
            "
 SRC_URI[sha256sum] = "2055e373613d8fc21529aff9f0adce3e23b9ce01ba0478d30e7941d9f2bd1224"