mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-07-27 07:57:27 +00:00
redis: Fix CVE-2025-46819
Upstream-Status: Backport from https://github.com/redis/redis/commit/2802b52b554cb9f0f249a24474c9fba94e933dbb Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
This commit is contained in:
committed by
Gyorgy Sarvari
parent
abe7f83cc6
commit
e44b4561a9
@@ -0,0 +1,161 @@
|
|||||||
|
From 2802b52b554cb9f0f249a24474c9fba94e933dbb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ozan Tezcan <ozantezcan@gmail.com>
|
||||||
|
Date: Mon, 23 Jun 2025 12:11:31 +0300
|
||||||
|
Subject: [PATCH] LUA out-of-bound read (CVE-2025-46819)
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://github.com/redis/redis/commit/2802b52b554cb9f0f249a24474c9fba94e933dbb]
|
||||||
|
CVE: CVE-2025-46819
|
||||||
|
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||||
|
---
|
||||||
|
deps/lua/src/llex.c | 34 ++++++++++++++++++-----------
|
||||||
|
tests/unit/scripting.tcl | 47 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 68 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/deps/lua/src/llex.c b/deps/lua/src/llex.c
|
||||||
|
index 88c6790..efad709 100644
|
||||||
|
--- a/deps/lua/src/llex.c
|
||||||
|
+++ b/deps/lua/src/llex.c
|
||||||
|
@@ -138,6 +138,7 @@ static void inclinenumber (LexState *ls) {
|
||||||
|
|
||||||
|
|
||||||
|
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
|
||||||
|
+ ls->t.token = 0;
|
||||||
|
ls->decpoint = '.';
|
||||||
|
ls->L = L;
|
||||||
|
ls->lookahead.token = TK_EOS; /* no look-ahead token */
|
||||||
|
@@ -206,9 +207,13 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) {
|
||||||
|
trydecpoint(ls, seminfo); /* try to update decimal point separator */
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
-static int skip_sep (LexState *ls) {
|
||||||
|
- int count = 0;
|
||||||
|
+/*
|
||||||
|
+** reads a sequence '[=*[' or ']=*]', leaving the last bracket.
|
||||||
|
+** If a sequence is well-formed, return its number of '='s + 2; otherwise,
|
||||||
|
+** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...').
|
||||||
|
+*/
|
||||||
|
+static size_t skip_sep (LexState *ls) {
|
||||||
|
+ size_t count = 0;
|
||||||
|
int s = ls->current;
|
||||||
|
lua_assert(s == '[' || s == ']');
|
||||||
|
save_and_next(ls);
|
||||||
|
@@ -216,11 +221,13 @@ static int skip_sep (LexState *ls) {
|
||||||
|
save_and_next(ls);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
- return (ls->current == s) ? count : (-count) - 1;
|
||||||
|
+ return (ls->current == s) ? count + 2
|
||||||
|
+ : (count == 0) ? 1
|
||||||
|
+ : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
|
||||||
|
+static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) {
|
||||||
|
int cont = 0;
|
||||||
|
(void)(cont); /* avoid warnings when `cont' is not used */
|
||||||
|
save_and_next(ls); /* skip 2nd `[' */
|
||||||
|
@@ -270,8 +277,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
|
||||||
|
}
|
||||||
|
} endloop:
|
||||||
|
if (seminfo)
|
||||||
|
- seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
|
||||||
|
- luaZ_bufflen(ls->buff) - 2*(2 + sep));
|
||||||
|
+ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep,
|
||||||
|
+ luaZ_bufflen(ls->buff) - 2 * sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -346,9 +353,9 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
||||||
|
/* else is a comment */
|
||||||
|
next(ls);
|
||||||
|
if (ls->current == '[') {
|
||||||
|
- int sep = skip_sep(ls);
|
||||||
|
+ size_t sep = skip_sep(ls);
|
||||||
|
luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
|
||||||
|
- if (sep >= 0) {
|
||||||
|
+ if (sep >= 2) {
|
||||||
|
read_long_string(ls, NULL, sep); /* long comment */
|
||||||
|
luaZ_resetbuffer(ls->buff);
|
||||||
|
continue;
|
||||||
|
@@ -360,13 +367,14 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case '[': {
|
||||||
|
- int sep = skip_sep(ls);
|
||||||
|
- if (sep >= 0) {
|
||||||
|
+ size_t sep = skip_sep(ls);
|
||||||
|
+ if (sep >= 2) {
|
||||||
|
read_long_string(ls, seminfo, sep);
|
||||||
|
return TK_STRING;
|
||||||
|
}
|
||||||
|
- else if (sep == -1) return '[';
|
||||||
|
- else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
|
||||||
|
+ else if (sep == 0) /* '[=...' missing second bracket */
|
||||||
|
+ luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
|
||||||
|
+ return '[';
|
||||||
|
}
|
||||||
|
case '=': {
|
||||||
|
next(ls);
|
||||||
|
diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl
|
||||||
|
index 58f2028..2ff0d44 100644
|
||||||
|
--- a/tests/unit/scripting.tcl
|
||||||
|
+++ b/tests/unit/scripting.tcl
|
||||||
|
@@ -1070,6 +1070,53 @@ start_server {tags {"scripting"}} {
|
||||||
|
} {*Script attempted to access nonexistent global variable 'print'*}
|
||||||
|
}
|
||||||
|
|
||||||
|
+# start a new server to test the large-memory tests
|
||||||
|
+start_server {tags {"scripting external:skip large-memory"}} {
|
||||||
|
+
|
||||||
|
+ test {EVAL - JSON string encoding a string larger than 2GB} {
|
||||||
|
+ run_script {
|
||||||
|
+ local s = string.rep("a", 1024 * 1024 * 1024)
|
||||||
|
+ return #cjson.encode(s..s..s)
|
||||||
|
+ } 0
|
||||||
|
+ } {3221225474} ;# length includes two double quotes at both ends
|
||||||
|
+
|
||||||
|
+ test {EVAL - Test long escape sequences for strings} {
|
||||||
|
+ run_script {
|
||||||
|
+ -- Generate 1gb '==...==' separator
|
||||||
|
+ local s = string.rep('=', 1024 * 1024)
|
||||||
|
+ local t = {} for i=1,1024 do t[i] = s end
|
||||||
|
+ local sep = table.concat(t)
|
||||||
|
+ collectgarbage('collect')
|
||||||
|
+
|
||||||
|
+ local code = table.concat({'return [',sep,'[x]',sep,']'})
|
||||||
|
+ collectgarbage('collect')
|
||||||
|
+
|
||||||
|
+ -- Load the code and run it. Script will return the string length.
|
||||||
|
+ -- Escape sequence: [=....=[ to ]=...=] will be ignored
|
||||||
|
+ -- Actual string is a single character: 'x'. Script will return 1
|
||||||
|
+ local func = loadstring(code)
|
||||||
|
+ return #func()
|
||||||
|
+ } 0
|
||||||
|
+ } {1}
|
||||||
|
+
|
||||||
|
+ test {EVAL - Lua can parse string with too many new lines} {
|
||||||
|
+ # Create a long string consisting only of newline characters. When Lua
|
||||||
|
+ # fails to parse a string, it typically includes a snippet like
|
||||||
|
+ # "... near ..." in the error message to indicate the last recognizable
|
||||||
|
+ # token. In this test, since the input contains only newlines, there
|
||||||
|
+ # should be no identifiable token, so the error message should contain
|
||||||
|
+ # only the actual error, without a near clause.
|
||||||
|
+
|
||||||
|
+ run_script {
|
||||||
|
+ local s = string.rep('\n', 1024 * 1024)
|
||||||
|
+ local t = {} for i=1,2048 do t[#t+1] = s end
|
||||||
|
+ local lines = table.concat(t)
|
||||||
|
+ local fn, err = loadstring(lines)
|
||||||
|
+ return err
|
||||||
|
+ } 0
|
||||||
|
+ } {*chunk has too many lines}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Start a new server to test lua-enable-deprecated-api config
|
||||||
|
foreach enabled {no yes} {
|
||||||
|
start_server [subst {tags {"scripting external:skip"} overrides {lua-enable-deprecated-api $enabled}}] {
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ SRC_URI = "http://download.redis.io/releases/${BP}.tar.gz \
|
|||||||
file://CVE-2025-48367.patch \
|
file://CVE-2025-48367.patch \
|
||||||
file://CVE-2025-46817.patch \
|
file://CVE-2025-46817.patch \
|
||||||
file://CVE-2025-46818.patch \
|
file://CVE-2025-46818.patch \
|
||||||
|
file://CVE-2025-46819.patch \
|
||||||
"
|
"
|
||||||
SRC_URI[sha256sum] = "97065774d5fb8388eb0d8913458decfcb167d356e40d31dd01cd30c1cc391673"
|
SRC_URI[sha256sum] = "97065774d5fb8388eb0d8913458decfcb167d356e40d31dd01cd30c1cc391673"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user