From bec644aab198049eaa5583631c419b4574b137e1 Mon Sep 17 00:00:00 2001 From: "debing.sun" Date: Wed, 30 Jul 2025 22:24:56 +0800 Subject: [PATCH] Fix missing kvobj reassignment after reallocation in MOVE command (#14233) Introduced by https://github.com/redis/redis/issues/13806 Fixed a crash in the MOVE command when moving hash objects that have both key expiration and field expiration. The issue occurred in the following scenario: 1. A hash has both key expiration and field expiration. 2. During MOVE command, `setExpireByLink()` is called to set the expiration time for the target hash, which may reallocate the kvobj of hash. 3. Since the hash has field expiration, `hashTypeAddToExpires()` is called to update the minimum field expiration time Issue: However, the kvobj pointer wasn't updated with the return value from `setExpireByLink()`, causing `hashTypeAddToExpires()` to use freed memory. --- src/db.c | 2 +- tests/unit/type/hash-field-expire.tcl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/db.c b/src/db.c index a1f476e697..8bbc20c343 100644 --- a/src/db.c +++ b/src/db.c @@ -1975,7 +1975,7 @@ void moveCommand(client *c) { dbAddByLink(dst, c->argv[1], &kv, &dstBucket); if (expire != -1) - setExpireByLink(c, dst, c->argv[1]->ptr, expire, dstBucket); + kv = setExpireByLink(c, dst, c->argv[1]->ptr, expire, dstBucket); /* If object of type hash with expiration on fields. Taken care to add the * hash to hexpires of `dst` only after dbDelete(). */ diff --git a/tests/unit/type/hash-field-expire.tcl b/tests/unit/type/hash-field-expire.tcl index a94a6b303f..99404a1ca1 100644 --- a/tests/unit/type/hash-field-expire.tcl +++ b/tests/unit/type/hash-field-expire.tcl @@ -616,6 +616,7 @@ start_server {tags {"external:skip needs:debug"}} { r select 9 r flushall r hset myhash field1 value1 + r expireat myhash 2000000000000 ;# Force kvobj reallocation during move command r hpexpire myhash 100 NX FIELDS 1 field1 r move myhash 10 assert_equal [r exists myhash] 0