Fix missing kvobj reassignment after reallocation in MOVE command (#14233)
CI / test-ubuntu-latest (push) Waiting to run Details
CI / test-sanitizer-address (push) Waiting to run Details
CI / build-debian-old (push) Waiting to run Details
CI / build-macos-latest (push) Waiting to run Details
CI / build-32bit (push) Waiting to run Details
CI / build-libc-malloc (push) Waiting to run Details
CI / build-centos-jemalloc (push) Waiting to run Details
CI / build-old-chain-jemalloc (push) Waiting to run Details
Codecov / code-coverage (push) Waiting to run Details
External Server Tests / test-external-standalone (push) Waiting to run Details
External Server Tests / test-external-cluster (push) Waiting to run Details
External Server Tests / test-external-nodebug (push) Waiting to run Details
Spellcheck / Spellcheck (push) Waiting to run Details

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.
This commit is contained in:
debing.sun 2025-07-30 22:24:56 +08:00 committed by GitHub
parent 333f679e89
commit bec644aab1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 2 additions and 1 deletions

View File

@ -1975,7 +1975,7 @@ void moveCommand(client *c) {
dbAddByLink(dst, c->argv[1], &kv, &dstBucket); dbAddByLink(dst, c->argv[1], &kv, &dstBucket);
if (expire != -1) 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 /* If object of type hash with expiration on fields. Taken care to add the
* hash to hexpires of `dst` only after dbDelete(). */ * hash to hexpires of `dst` only after dbDelete(). */

View File

@ -616,6 +616,7 @@ start_server {tags {"external:skip needs:debug"}} {
r select 9 r select 9
r flushall r flushall
r hset myhash field1 value1 r hset myhash field1 value1
r expireat myhash 2000000000000 ;# Force kvobj reallocation during move command
r hpexpire myhash 100 NX FIELDS 1 field1 r hpexpire myhash 100 NX FIELDS 1 field1
r move myhash 10 r move myhash 10
assert_equal [r exists myhash] 0 assert_equal [r exists myhash] 0