mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-11-12 15:31:03 +00:00
redis: fix CVE-2026-23631
This patch applies the upstream fix as referenced in [2], using the commit shown in [1]. [1] https://github.com/redis/redis/commit/0cca172a174642bdae03b871615227896274d9bb [2] https://nvd.nist.gov/vuln/detail/CVE-2026-23631 Signed-off-by: Yogita Urade <yurade@cisco.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
1 parent
0d975df7da
commit
77ca1bfa10
2 files changed
+120
No files matched your search
@@ -0,0 +1,119 @@
|
||||
From 0cca172a174642bdae03b871615227896274d9bb Mon Sep 17 00:00:00 2001
|
||||
From: Ozan Tezcan <ozantezcan@gmail.com>
|
||||
Date: Tue, 14 Apr 2026 08:47:04 +0300
|
||||
Subject: [PATCH] Fix use-after-free when fullsync happens while replica is
|
||||
running a timed out script (CVE-2026-23631)
|
||||
|
||||
Fullsync triggers emptyData and scriptingReset which free the scripting/function engine. If a timed out script is still running on the replica, this causes a use-after-free. Delay fullsync processing in readSyncBulkPayload until the script finishes.
|
||||
|
||||
CVE: CVE-2026-23631
|
||||
Upstream-Status: Backport [https://github.com/redis/redis/commit/0cca172a174642bdae03b871615227896274d9bb]
|
||||
|
||||
(cherry picked from commit 0cca172a174642bdae03b871615227896274d9bb)
|
||||
Signed-off-by: Yogita Urade <yurade@cisco.com>
|
||||
---
|
||||
src/replication.c | 5 ++
|
||||
tests/integration/replication.tcl | 77 +++++++++++++++++++++++++++++++
|
||||
2 files changed, 82 insertions(+)
|
||||
|
||||
diff --git a/src/replication.c b/src/replication.c
|
||||
index 5fab23b1c..489032aed 100644
|
||||
--- a/src/replication.c
|
||||
+++ b/src/replication.c
|
||||
@@ -2022,6 +2022,11 @@ void replicationAttachToNewMaster(void) {
|
||||
/* Asynchronously read the SYNC payload we receive from a master */
|
||||
#define REPL_MAX_WRITTEN_BEFORE_FSYNC (1024*1024*8) /* 8 MB */
|
||||
void readSyncBulkPayload(connection *conn) {
|
||||
+ /* During full sync, the functions engine is freed right before loading
|
||||
+ * the RDB. To avoid this happening while a function is still running,
|
||||
+ * delay full sync processing until it finishes. */
|
||||
+ if (isInsideYieldingLongCommand()) return;
|
||||
+
|
||||
char buf[PROTO_IOBUF_LEN];
|
||||
ssize_t nread, readlen, nwritten;
|
||||
int use_diskless_load = useDisklessLoad();
|
||||
diff --git a/tests/integration/replication.tcl b/tests/integration/replication.tcl
|
||||
index 65494f427..412a00740 100644
|
||||
--- a/tests/integration/replication.tcl
|
||||
+++ b/tests/integration/replication.tcl
|
||||
@@ -1661,3 +1661,80 @@ start_server {tags {"repl external:skip"}} {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+# Fullsync should not free the functions lib ctx while the replica has
|
||||
+# a timed out function that is still running.
|
||||
+foreach type {script function} {
|
||||
+ start_server {tags {"repl external:skip"}} {
|
||||
+ start_server {} {
|
||||
+ set master [srv -1 client]
|
||||
+ set master_host [srv -1 host]
|
||||
+ set master_port [srv -1 port]
|
||||
+ set replica [srv 0 client]
|
||||
+
|
||||
+ test "Fullsync should not free scripting engine on a replica while a $type is running" {
|
||||
+ $master config set repl-diskless-sync yes
|
||||
+ $master config set repl-diskless-sync-delay 0
|
||||
+ # Set small client output buffer limit to trigger fullsync quickly
|
||||
+ $master config set client-output-buffer-limit "replica 1k 1k 0"
|
||||
+ $replica config set repl-diskless-load yes
|
||||
+ $replica config set busy-reply-threshold 1 ;# script timeout in 1 ms
|
||||
+
|
||||
+ # Load function
|
||||
+ if {$type eq "function"} {
|
||||
+ $master function load replace {#!lua name=blocklib
|
||||
+ redis.register_function{
|
||||
+ function_name='blockfunc',
|
||||
+ callback=function() while true do end end,
|
||||
+ flags={'no-writes'}
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ # Start replication
|
||||
+ $replica replicaof $master_host $master_port
|
||||
+ wait_for_sync $replica
|
||||
+
|
||||
+ # Run the blocking script on replica
|
||||
+ set rd [redis_deferring_client]
|
||||
+ if {$type eq "script"} {
|
||||
+ $rd eval {while true do end} 0
|
||||
+ } else {
|
||||
+ $rd fcall_ro blockfunc 0
|
||||
+ }
|
||||
+
|
||||
+ # Verify replica replies with BUSY
|
||||
+ wait_for_condition 50 100 {
|
||||
+ [catch {$replica ping} e] == 1 && [string match {*BUSY*} $e]
|
||||
+ } else {
|
||||
+ fail "$type didn't become busy"
|
||||
+ }
|
||||
+
|
||||
+ # Fills client output buffer and triggers fullsync
|
||||
+ populate 5 bigkey 1000000 -1
|
||||
+ wait_for_condition 50 100 {
|
||||
+ [s -1 sync_full] >= 2
|
||||
+ } else {
|
||||
+ fail "Fullsync was not triggered"
|
||||
+ }
|
||||
+
|
||||
+ # Verify replica is still running the function
|
||||
+ after 1000
|
||||
+ catch {$replica ping} e
|
||||
+ assert_match {*BUSY*} $e "replica should still reply with BUSY"
|
||||
+
|
||||
+ if {$type eq "script"} {
|
||||
+ $replica script kill
|
||||
+ } else {
|
||||
+ $replica function kill
|
||||
+ }
|
||||
+
|
||||
+ # Verify replica is responsive again
|
||||
+ catch {$rd read} result
|
||||
+ $rd close
|
||||
+ wait_for_sync $replica
|
||||
+ assert_equal [$replica ping] "PONG"
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
@@ -17,6 +17,7 @@ SRC_URI = "http://download.redis.io/releases/${BP}.tar.gz \
|
||||
file://0005-Define-_GNU_SOURCE-to-get-PTHREAD_MUTEX_INITIALIZER.patch \
|
||||
file://CVE-2026-81934.patch \
|
||||
file://CVE-2026-23479.patch \
|
||||
file://CVE-2026-23631.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "6d0a9913887a4972536f9da226f1575859c34d86354129163260a5f9c6bd4229"
|
||||
|
||||
|
||||
Reference in new issue
Block a user