Use-after-Free

HIGH
redis/redis
Commit: 5c355b68ecc8
Affected: <= 8.6.2 (pre-fix); vulnerable prior to this commit; patched in this change
2026-05-14 15:56 UTC

Description

This commit appears to fix a genuine use-after-free vulnerability concern. The race occurs when evicting a blocked client during an unblock and re-executing a pending command. Previously, the engine could access a client after it had been freed during processCommandAndResetClient. The fix guards against this by checking the return value of processCommandAndResetClient; if the client was freed, it exits the execution unit and returns early, preventing use-after-free in subsequent logic. The accompanying test case exercises eviction of a blocked client to ensure no use-after-free occurs during unblock.

Proof of Concept

start_server {} { r flushall r client no-evict on r config set maxmemory-clients 0 test "Verify blocked client eviction during unblock does not cause use-after-free" { # Create a deferring client that will be blocked on stream # Use a long stream name to ensure memory usage is substantial set rd [redis_deferring_client] $rd XREAD BLOCK 0 STREAMS mystream stream_[string repeat x 200000] $ $ # Wait for the client to be blocked wait_for_condition 50 100 { [s blocked_clients] eq {1} } else { fail "Client was not blocked" } # Evict by lowering maxmemory-clients and issuing a command to unblock r MULTI r CONFIG SET MAXMEMORY-CLIENTS 100000 r XADD mystream * field val r EXEC r PING $rd close } }

Commit Details

Author: debing.sun

Date: 2025-12-29 08:20 UTC

Message:

Fix use-after-free when evicting blocked client during unblock (CVE-2026-23479) When re-executing a pending command after unblocking, check the return value of `processCommandAndResetClient` and exit if needed.

Triage Assessment

Vulnerability Type: Use-after-free

Confidence: HIGH

Reasoning:

Commit explicitly fixes a use-after-free scenario when evicting a blocked client during an unblock, by checking processCommandAndResetClient return value and guarding against the client being freed. This addresses a memory-safety vulnerability (use-after-free) likely exploitable as CVE-2026-23479.

Verification Assessment

Vulnerability Type: Use-after-Free

Confidence: HIGH

Affected Versions: <= 8.6.2 (pre-fix); vulnerable prior to this commit; patched in this change

Code Diff

diff --git a/src/blocked.c b/src/blocked.c index b973adeaf75..74558b485dc 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -699,7 +699,13 @@ static void unblockClientOnKey(client *c, robj *key) { client *old_client = server.current_client; server.current_client = c; enterExecutionUnit(1, 0); - processCommandAndResetClient(c); + if (processCommandAndResetClient(c) == C_ERR) { + /* Client was freed during command processing, exit immediately */ + exitExecutionUnit(); + server.current_client = old_client; + return; + } + if (!(c->flags & CLIENT_BLOCKED)) { if (c->flags & CLIENT_MODULE) { moduleCallCommandUnblockedHandler(c); diff --git a/tests/unit/client-eviction.tcl b/tests/unit/client-eviction.tcl index 2e08715b8d6..afe32e4f960 100644 --- a/tests/unit/client-eviction.tcl +++ b/tests/unit/client-eviction.tcl @@ -611,5 +611,34 @@ start_server {} { } } +start_server {} { + r flushall + r client no-evict on + r config set maxmemory-clients 0 + + test "Verify blocked client eviction during unblock does not cause use-after-free" { + # Create a deferring client that will be blocked on stream + # Use a long stream name to make client memory usage exceed 200000 bytes + set rd [redis_deferring_client] + $rd XREAD BLOCK 0 STREAMS mystream stream_[string repeat x 200000] $ $ + + # Wait for the client to be blocked + wait_for_condition 50 100 { + [s blocked_clients] eq {1} + } else { + fail "Client was not blocked" + } + + # Now lower MAXMEMORY-CLIENTS to a low value and use + # XADD to unblock the blocked client, triggering eviction. + r MULTI + r CONFIG SET MAXMEMORY-CLIENTS 100000 ;# Put in MULTI to defer blocked client eviction until after EXEC + r XADD mystream * field val + r EXEC + r PING + $rd close + } +} + } ;# tags
← Back to Alerts View on GitHub →