Skip to content

Fix missing kvobj reassignment after reallocation in MOVE command#14233

Merged
sundb merged 1 commit into
redis:unstablefrom
sundb:kvobj-assign
Jul 30, 2025
Merged

Fix missing kvobj reassignment after reallocation in MOVE command#14233
sundb merged 1 commit into
redis:unstablefrom
sundb:kvobj-assign

Conversation

@sundb

@sundb sundb commented Jul 30, 2025

Copy link
Copy Markdown
Collaborator

Introduced by #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.

report from the test (build with SANITIZER address):

[err]: Sanitizer error: =================================================================
==133231==ERROR: AddressSanitizer: heap-use-after-free on address 0x50300000f760 at pc 0x55f045aa1565 bp 0x7ffd72709e30 sp 0x7ffd72709e20
READ of size 1 at 0x50300000f760 thread T0
    #0 0x55f045aa1564 in hashTypeAddToExpires /home/sundb/data/rf_1/src/t_hash.c:2021
    #1 0x55f0459ce3b1 in moveCommand /home/sundb/data/rf_1/src/db.c:1983
    #2 0x55f0459109dd in call /home/sundb/data/rf_1/src/server.c:3754
    #3 0x55f04591aa0b in processCommand /home/sundb/data/rf_1/src/server.c:4419
    #4 0x55f04597eb74 in processCommandAndResetClient /home/sundb/data/rf_1/src/networking.c:2766
    #5 0x55f04597eb74 in processInputBuffer /home/sundb/data/rf_1/src/networking.c:2960
    #6 0x55f04598ca77 in readQueryFromClient /home/sundb/data/rf_1/src/networking.c:3122
    #7 0x55f045d1461c in callHandler /home/sundb/data/rf_1/src/connhelpers.h:59
    #8 0x55f045d1461c in connSocketEventHandler /home/sundb/data/rf_1/src/socket.c:288
    #9 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:435
    #10 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:360
    #11 0x55f0458b70ec in aeMain /home/sundb/data/rf_1/src/ae.c:495
    #12 0x55f0458a8a53 in main /home/sundb/data/rf_1/src/server.c:7660
    #13 0x7ff14be2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #14 0x7ff14be2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #15 0x55f0458ab224 in _start (/home/sundb/data/rf_1/src/redis-server+0x150224) (BuildId: 35c15804eed53bbfa49d7f59f3b33ee7a0409286)

0x50300000f760 is located 0 bytes inside of 25-byte region [0x50300000f760,0x50300000f779)
freed by thread T0 here:
    #0 0x7ff14c6fc4d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x55f0459ac00e in kvobjSet /home/sundb/data/rf_1/src/object.c:319
    #2 0x55f0459cb4df in kvobjSetExpire /home/sundb/data/rf_1/src/object.c:266
    #3 0x55f0459cb4df in setExpireByLink /home/sundb/data/rf_1/src/db.c:2353
    #4 0x55f0459ce36f in moveCommand /home/sundb/data/rf_1/src/db.c:1978
    #5 0x55f0459109dd in call /home/sundb/data/rf_1/src/server.c:3754
    #6 0x55f04591aa0b in processCommand /home/sundb/data/rf_1/src/server.c:4419
    #7 0x55f04597eb74 in processCommandAndResetClient /home/sundb/data/rf_1/src/networking.c:2766
    #8 0x55f04597eb74 in processInputBuffer /home/sundb/data/rf_1/src/networking.c:2960
    #9 0x55f04598ca77 in readQueryFromClient /home/sundb/data/rf_1/src/networking.c:3122
    #10 0x55f045d1461c in callHandler /home/sundb/data/rf_1/src/connhelpers.h:59
    #11 0x55f045d1461c in connSocketEventHandler /home/sundb/data/rf_1/src/socket.c:288
    #12 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:435
    #13 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:360
    #14 0x55f0458b70ec in aeMain /home/sundb/data/rf_1/src/ae.c:495
    #15 0x55f0458a8a53 in main /home/sundb/data/rf_1/src/server.c:7660
    #16 0x7ff14be2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #17 0x7ff14be2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #18 0x55f0458ab224 in _start (/home/sundb/data/rf_1/src/redis-server+0x150224) (BuildId: 35c15804eed53bbfa49d7f59f3b33ee7a0409286)

previously allocated by thread T0 here:
    #0 0x7ff14c6fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55f04593c4aa in ztrymalloc_usable_internal /home/sundb/data/rf_1/src/zmalloc.c:135
    #2 0x55f04593c4aa in zmalloc_usable /home/sundb/data/rf_1/src/zmalloc.c:183
    #3 0x55f0459a92fa in kvobjCreate /home/sundb/data/rf_1/src/object.c:56
    #4 0x55f0459abfbc in kvobjSet /home/sundb/data/rf_1/src/object.c:316
    #5 0x55f0459cb91b in dbAddInternal /home/sundb/data/rf_1/src/db.c:336
    #6 0x55f0459ce2de in dbAddByLink /home/sundb/data/rf_1/src/db.c:356
    #7 0x55f0459ce2de in moveCommand /home/sundb/data/rf_1/src/db.c:1976
    #8 0x55f0459109dd in call /home/sundb/data/rf_1/src/server.c:3754
    #9 0x55f04591aa0b in processCommand /home/sundb/data/rf_1/src/server.c:4419
    #10 0x55f04597eb74 in processCommandAndResetClient /home/sundb/data/rf_1/src/networking.c:2766
    #11 0x55f04597eb74 in processInputBuffer /home/sundb/data/rf_1/src/networking.c:2960
    #12 0x55f04598ca77 in readQueryFromClient /home/sundb/data/rf_1/src/networking.c:3122
    #13 0x55f045d1461c in callHandler /home/sundb/data/rf_1/src/connhelpers.h:59
    #14 0x55f045d1461c in connSocketEventHandler /home/sundb/data/rf_1/src/socket.c:288
    #15 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:435
    #16 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:360
    #17 0x55f0458b70ec in aeMain /home/sundb/data/rf_1/src/ae.c:495
    #18 0x55f0458a8a53 in main /home/sundb/data/rf_1/src/server.c:7660
    #19 0x7ff14be2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #20 0x7ff14be2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #21 0x55f0458ab224 in _start (/home/sundb/data/rf_1/src/redis-server+0x150224) (BuildId: 35c15804eed53bbfa49d7f59f3b33ee7a0409286)

SUMMARY: AddressSanitizer: heap-use-after-free /home/sundb/data/rf_1/src/t_hash.c:2021 in hashTypeAddToExpires
Shadow bytes around the buggy address:
  0x50300000f480: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
  0x50300000f500: fd fa fa fa fd fd fd fa fa fa fd fd fd fd fa fa
  0x50300000f580: fd fd fd fa fa fa fd fd fd fd fa fa fd fd fd fd
  0x50300000f600: fa fa 00 00 00 fa fa fa fd fd fd fd fa fa fd fd
  0x50300000f680: fd fd fa fa fd fd fd fd fa fa 00 00 00 fa fa fa
=>0x50300000f700: 00 00 00 02 fa fa 00 00 06 fa fa fa[fd]fd fd fd
  0x50300000f780: fa fa 00 00 00 00 fa fa fd fd fd fa fa fa 00 00
  0x50300000f800: 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50300000f880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50300000f900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50300000f980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==133231==ABORTING


Logged sanitizer errors (pid 133231):
=================================================================
==133231==ERROR: AddressSanitizer: heap-use-after-free on address 0x50300000f760 at pc 0x55f045aa1565 bp 0x7ffd72709e30 sp 0x7ffd72709e20
READ of size 1 at 0x50300000f760 thread T0
    #0 0x55f045aa1564 in hashTypeAddToExpires /home/sundb/data/rf_1/src/t_hash.c:2021
    #1 0x55f0459ce3b1 in moveCommand /home/sundb/data/rf_1/src/db.c:1983
    #2 0x55f0459109dd in call /home/sundb/data/rf_1/src/server.c:3754
    #3 0x55f04591aa0b in processCommand /home/sundb/data/rf_1/src/server.c:4419
    #4 0x55f04597eb74 in processCommandAndResetClient /home/sundb/data/rf_1/src/networking.c:2766
    #5 0x55f04597eb74 in processInputBuffer /home/sundb/data/rf_1/src/networking.c:2960
    #6 0x55f04598ca77 in readQueryFromClient /home/sundb/data/rf_1/src/networking.c:3122
    #7 0x55f045d1461c in callHandler /home/sundb/data/rf_1/src/connhelpers.h:59
    #8 0x55f045d1461c in connSocketEventHandler /home/sundb/data/rf_1/src/socket.c:288
    #9 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:435
    #10 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:360
    #11 0x55f0458b70ec in aeMain /home/sundb/data/rf_1/src/ae.c:495
    #12 0x55f0458a8a53 in main /home/sundb/data/rf_1/src/server.c:7660
    #13 0x7ff14be2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #14 0x7ff14be2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #15 0x55f0458ab224 in _start (/home/sundb/data/rf_1/src/redis-server+0x150224) (BuildId: 35c15804eed53bbfa49d7f59f3b33ee7a0409286)

0x50300000f760 is located 0 bytes inside of 25-byte region [0x50300000f760,0x50300000f779)
freed by thread T0 here:
    #0 0x7ff14c6fc4d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x55f0459ac00e in kvobjSet /home/sundb/data/rf_1/src/object.c:319
    #2 0x55f0459cb4df in kvobjSetExpire /home/sundb/data/rf_1/src/object.c:266
    #3 0x55f0459cb4df in setExpireByLink /home/sundb/data/rf_1/src/db.c:2353
    #4 0x55f0459ce36f in moveCommand /home/sundb/data/rf_1/src/db.c:1978
    #5 0x55f0459109dd in call /home/sundb/data/rf_1/src/server.c:3754
    #6 0x55f04591aa0b in processCommand /home/sundb/data/rf_1/src/server.c:4419
    #7 0x55f04597eb74 in processCommandAndResetClient /home/sundb/data/rf_1/src/networking.c:2766
    #8 0x55f04597eb74 in processInputBuffer /home/sundb/data/rf_1/src/networking.c:2960
    #9 0x55f04598ca77 in readQueryFromClient /home/sundb/data/rf_1/src/networking.c:3122
    #10 0x55f045d1461c in callHandler /home/sundb/data/rf_1/src/connhelpers.h:59
    #11 0x55f045d1461c in connSocketEventHandler /home/sundb/data/rf_1/src/socket.c:288
    #12 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:435
    #13 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:360
    #14 0x55f0458b70ec in aeMain /home/sundb/data/rf_1/src/ae.c:495
    #15 0x55f0458a8a53 in main /home/sundb/data/rf_1/src/server.c:7660
    #16 0x7ff14be2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #17 0x7ff14be2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #18 0x55f0458ab224 in _start (/home/sundb/data/rf_1/src/redis-server+0x150224) (BuildId: 35c15804eed53bbfa49d7f59f3b33ee7a0409286)

previously allocated by thread T0 here:
    #0 0x7ff14c6fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55f04593c4aa in ztrymalloc_usable_internal /home/sundb/data/rf_1/src/zmalloc.c:135
    #2 0x55f04593c4aa in zmalloc_usable /home/sundb/data/rf_1/src/zmalloc.c:183
    #3 0x55f0459a92fa in kvobjCreate /home/sundb/data/rf_1/src/object.c:56
    #4 0x55f0459abfbc in kvobjSet /home/sundb/data/rf_1/src/object.c:316
    #5 0x55f0459cb91b in dbAddInternal /home/sundb/data/rf_1/src/db.c:336
    #6 0x55f0459ce2de in dbAddByLink /home/sundb/data/rf_1/src/db.c:356
    #7 0x55f0459ce2de in moveCommand /home/sundb/data/rf_1/src/db.c:1976
    #8 0x55f0459109dd in call /home/sundb/data/rf_1/src/server.c:3754
    #9 0x55f04591aa0b in processCommand /home/sundb/data/rf_1/src/server.c:4419
    #10 0x55f04597eb74 in processCommandAndResetClient /home/sundb/data/rf_1/src/networking.c:2766
    #11 0x55f04597eb74 in processInputBuffer /home/sundb/data/rf_1/src/networking.c:2960
    #12 0x55f04598ca77 in readQueryFromClient /home/sundb/data/rf_1/src/networking.c:3122
    #13 0x55f045d1461c in callHandler /home/sundb/data/rf_1/src/connhelpers.h:59
    #14 0x55f045d1461c in connSocketEventHandler /home/sundb/data/rf_1/src/socket.c:288
    #15 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:435
    #16 0x55f0458b70ec in aeProcessEvents /home/sundb/data/rf_1/src/ae.c:360
    #17 0x55f0458b70ec in aeMain /home/sundb/data/rf_1/src/ae.c:495
    #18 0x55f0458a8a53 in main /home/sundb/data/rf_1/src/server.c:7660
    #19 0x7ff14be2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #20 0x7ff14be2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #21 0x55f0458ab224 in _start (/home/sundb/data/rf_1/src/redis-server+0x150224) (BuildId: 35c15804eed53bbfa49d7f59f3b33ee7a0409286)

SUMMARY: AddressSanitizer: heap-use-after-free /home/sundb/data/rf_1/src/t_hash.c:2021 in hashTypeAddToExpires
Shadow bytes around the buggy address:
  0x50300000f480: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
  0x50300000f500: fd fa fa fa fd fd fd fa fa fa fd fd fd fd fa fa
  0x50300000f580: fd fd fd fa fa fa fd fd fd fd fa fa fd fd fd fd
  0x50300000f600: fa fa 00 00 00 fa fa fa fd fd fd fd fa fa fd fd
  0x50300000f680: fd fd fa fa fd fd fd fd fa fa 00 00 00 fa fa fa
=>0x50300000f700: 00 00 00 02 fa fa 00 00 06 fa fa fa[fd]fd fd fd
  0x50300000f780: fa fa 00 00 00 00 fa fa fd fd fd fa fa fa 00 00
  0x50300000f800: 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50300000f880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50300000f900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50300000f980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==133231==ABORTING

@sundb sundb requested review from Copilot and moticless and removed request for Copilot July 30, 2025 12:04
@snyk-io

snyk-io Bot commented Jul 30, 2025

Copy link
Copy Markdown

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a critical bug in the MOVE command that caused crashes when moving hash objects with both key and field expiration. The crash occurred due to a missing kvobj pointer update after potential reallocation during expiration setting.

  • Fixed missing kvobj reassignment after setExpireByLink() call in MOVE command
  • Added test case to reproduce the bug scenario with forced kvobj reallocation

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/db.c Updated MOVE command to capture returned kvobj from setExpireByLink() to prevent use-after-free
tests/unit/type/hash-field-expire.tcl Added test case with key expiration to force kvobj reallocation during MOVE

Comment thread tests/unit/type/hash-field-expire.tcl
@kaplanben

Copy link
Copy Markdown

Logo
Checkmarx One – Scan Summary & Detailsdc34d962-76d0-466c-ba37-c2fb665d262c

New Issues (8)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/sha1.c: 65
detailsThe buffer buffer created in /src/sha1.c at line 65 is written to a buffer in /src/sha1.c at line 65 by block, but an error in calculating the al...
ID: N9gGLsUP8UQvFZEl1N39fgD7jYQ%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
detailsThe buffer buf created in /src/redis-cli.c at line 3677 is written to a buffer in /deps/hiredis/sds.c at line 234 by newsh, but an error in calc...
ID: %2BpSSxZAM7xfUiads1egmyYebO5I%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
detailsThe buffer buf created in /src/redis-cli.c at line 3677 is written to a buffer in /deps/hiredis/sds.c at line 234 by hdrlen, but an error in cal...
ID: zN%2FI3F1XTVrKpHuopU6EZZmWXt4%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /deps/linenoise/linenoise.c: 1200
detailsThe buffer buf created in /deps/linenoise/linenoise.c at line 1200 is written to a buffer in /deps/hiredis/sds.c at line 97 by sh, but an error i...
ID: oykVSjUcVC%2FEMplDwW4P3YG7%2FzE%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 10594
detailsThe buffer argv created in /src/redis-cli.c at line 10594 is written to a buffer in /deps/hiredis/sds.c at line 97 by sh, but an error in calcul...
ID: eStOv%2FTaWfWWBCJCCgzT7mgYJU0%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /deps/linenoise/linenoise.c: 1166
detailsThe buffer fgetc created in /deps/linenoise/linenoise.c at line 1166 is written to a buffer in /deps/hiredis/sds.c at line 97 by sh, but an error...
ID: v3h9G7I8PLSutWNyC8k4gGzAdDA%3D
Attack Vector
MEDIUM Divide_By_Zero /modules/vector-sets/fastjson_test.c: 121
detailsThe application performs an illegal operation in generate_random_string, in /modules/vector-sets/fastjson_test.c. In line 121, the program at...
ID: qiowoZ%2FDUFf8wA3ZCvKY8M0GHks%3D
Attack Vector
MEDIUM Divide_By_Zero /src/redis-cli.c: 6040
detailsThe application performs an illegal operation in clusterManagerNodeMasterRandom, in /src/redis-cli.c. In line 6053, the program attempts to divi...
ID: Wdmj3BiFZXbdNClmOY%2Fr1waYywk%3D
Attack Vector
Fixed Issues (5)

Great job! The following issues were fixed in this Pull Request

Severity Issue Source File / Package
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
MEDIUM Divide_By_Zero /deps/jemalloc/src/nstime.c: 149

@sundb sundb merged commit bec644a into redis:unstable Jul 30, 2025
26 of 27 checks passed
@sundb sundb added this to Redis 8.2 Aug 15, 2025
@sundb sundb moved this from Todo to Done in Redis 8.2 Aug 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants