From 955a866aee2a3a62c09a56eecf17cdf24377ab15 Mon Sep 17 00:00:00 2001 From: wangziliang Date: Thu, 9 Oct 2025 16:49:16 +0800 Subject: [PATCH] fix CVE-2025-46817 --- Backport-CVE-2025-46817.patch | 98 +++++++++++++++++++++++++++++++++++ redis6.spec | 7 ++- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Backport-CVE-2025-46817.patch diff --git a/Backport-CVE-2025-46817.patch b/Backport-CVE-2025-46817.patch new file mode 100644 index 0000000..9632378 --- /dev/null +++ b/Backport-CVE-2025-46817.patch @@ -0,0 +1,98 @@ +From fc9abc775e308374f667fdf3e723ef4b7eb0e3ca Mon Sep 17 00:00:00 2001 +From: Ozan Tezcan +Date: Mon, 23 Jun 2025 13:33:00 +0300 +Subject: [PATCH] Lua script may lead to integer overflow and potential RCE + (CVE-2025-46817) + +--- + deps/lua/src/lbaselib.c | 7 ++++--- + deps/lua/src/ltable.c | 3 +-- + tests/unit/scripting.tcl | 39 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 44 insertions(+), 5 deletions(-) + +diff --git a/deps/lua/src/lbaselib.c b/deps/lua/src/lbaselib.c +index 2ab550bd48d..26172d15b40 100644 +--- a/deps/lua/src/lbaselib.c ++++ b/deps/lua/src/lbaselib.c +@@ -340,13 +340,14 @@ static int luaB_assert (lua_State *L) { + + + static int luaB_unpack (lua_State *L) { +- int i, e, n; ++ int i, e; ++ unsigned int n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ +- n = e - i + 1; /* number of elements */ +- if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ ++ n = (unsigned int)e - (unsigned int)i; /* number of elements minus 1 */ ++ if (n >= INT_MAX || !lua_checkstack(L, ++n)) + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ +diff --git a/deps/lua/src/ltable.c b/deps/lua/src/ltable.c +index f75fe19fe39..55575a8ace9 100644 +--- a/deps/lua/src/ltable.c ++++ b/deps/lua/src/ltable.c +@@ -434,8 +434,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { + ** search function for integers + */ + const TValue *luaH_getnum (Table *t, int key) { +- /* (1 <= key && key <= t->sizearray) */ +- if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) ++ if (1 <= key && key <= t->sizearray) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); +diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl +index eb38ed93efd..dadf53e2a2f 100644 +--- a/tests/unit/scripting.tcl ++++ b/tests/unit/scripting.tcl +@@ -355,6 +355,45 @@ start_server {tags {"scripting"}} { + set e + } {*against a key*} + ++ test {EVAL - Test table unpack with invalid indexes} { ++ catch {run_script { return {unpack({1,2,3}, -2, 2147483647)} } 0} e ++ assert_match {*too many results to unpack*} $e ++ catch {run_script { return {unpack({1,2,3}, 0, 2147483647)} } 0} e ++ assert_match {*too many results to unpack*} $e ++ catch {run_script { return {unpack({1,2,3}, -2147483648, -2)} } 0} e ++ assert_match {*too many results to unpack*} $e ++ set res [run_script { return {unpack({1,2,3}, -1, -2)} } 0] ++ assert_match {} $res ++ set res [run_script { return {unpack({1,2,3}, 1, -1)} } 0] ++ assert_match {} $res ++ ++ # unpack with range -1 to 5, verify nil indexes ++ set res [run_script { ++ local function unpack_to_list(t, i, j) ++ local n, v = select('#', unpack(t, i, j)), {unpack(t, i, j)} ++ for i = 1, n do v[i] = v[i] or '_NIL_' end ++ v.n = n ++ return v ++ end ++ ++ return unpack_to_list({1,2,3}, -1, 5) ++ } 0] ++ assert_match {_NIL_ _NIL_ 1 2 3 _NIL_ _NIL_} $res ++ ++ # unpack with negative range, verify nil indexes ++ set res [run_script { ++ local function unpack_to_list(t, i, j) ++ local n, v = select('#', unpack(t, i, j)), {unpack(t, i, j)} ++ for i = 1, n do v[i] = v[i] or '_NIL_' end ++ v.n = n ++ return v ++ end ++ ++ return unpack_to_list({1,2,3}, -2147483648, -2147483646) ++ } 0] ++ assert_match {_NIL_ _NIL_ _NIL_} $res ++ } {} ++ + test {EVAL - JSON numeric decoding} { + # We must return the table as a string because otherwise + # Redis converts floats to ints and we get 0 and 1023 instead diff --git a/redis6.spec b/redis6.spec index 5d2e0bb..621d4e1 100644 --- a/redis6.spec +++ b/redis6.spec @@ -6,7 +6,7 @@ %global Pname redis Name: redis6 Version: 6.2.7 -Release: 4 +Release: 5 Summary: A persistent key-value database License: BSD and MIT URL: https://redis.io @@ -23,6 +23,7 @@ Patch0001: Modify-aarch64-architecture-jemalloc-page-size-from-from-4k Patch0003: Add-loongarch64-support.patch Patch0004: Update-config.guess-and-config.sub.patch +Patch0005: Backport-CVE-2025-46817.patch Patch0002: fix-help-info.patch BuildRequires: make gcc @@ -91,6 +92,7 @@ tar -xvf %{SOURCE10} %patch0003 -p1 %patch0004 -p1 %endif +%patch0005 -p1 mv ../%{Pname}-doc-%{doc_commit} doc mv deps/lua/COPYRIGHT COPYRIGHT-lua mv deps/jemalloc/COPYING COPYING-jemalloc @@ -219,6 +221,9 @@ fi %{_docdir}/%{Pname} %changelog +* Thu Oct 09 2025 wangziliang - 6.2.7-5 +- Fix CVE-2025-46817 + * Tue Sep 02 2025 wangkai <13474090681@163.com> - 6.2.7-4 - License compliance rectification -- Gitee