Skip to content

Conversation

@tezc
Copy link
Collaborator

@tezc tezc commented Mar 25, 2025

When the diskless load configuration is set to on-empty-db, we retain a pointer to the function library context. When emptyData() is called, it frees this function library context pointer, leading to a use-after-free situation.

I refactored code to ensure that emptyData() is called first, followed by retrieving the valid pointer to the function library context.

Refactored code should not introduce any runtime implications.

Bug introduced by #13495 (Redis 8.0)

Co-authored-by: Oran Agra <oran@redislabs.com>
@tezc tezc requested a review from oranagra March 25, 2025 19:13
@tezc
Copy link
Collaborator Author

tezc commented Mar 25, 2025

==2411403==ERROR: AddressSanitizer: heap-use-after-free on address 0x6030000a91b0 at pc 0x55fb5892e1dd bp 0x7ffedbc7f400 sp 0x7ffedbc7f3f0
READ of size 8 at 0x6030000a91b0 thread T0
    #0 0x55fb5892e1dc in functionsCreateWithLibraryCtx /home/oran/work/RedisLabs/garantia.redis/src/functions.c:984
    #1 0x55fb585f33b9 in rdbLoadCallbackFunction /home/oran/work/RedisLabs/garantia.redis/src/rdb.c:6238
    #2 0x55fb585e6849 in rdbFunctionParse /home/oran/work/RedisLabs/garantia.redis/src/rdb.c:6391
    #3 0x55fb585ef5c6 in rdbParse /home/oran/work/RedisLabs/garantia.redis/src/rdb.c:5098
    #4 0x55fb585f2267 in rdbLoadRioWithLoadingCtx /home/oran/work/RedisLabs/garantia.redis/src/rdb.c:6495
    #5 0x55fb585a1612 in readSyncBulkPayload /home/oran/work/RedisLabs/garantia.redis/src/replication.c:2479
    #6 0x55fb588f21d7 in callHandler /home/oran/work/RedisLabs/garantia.redis/src/connhelpers.h:58
    #7 0x55fb588f21d7 in connSocketEventHandler /home/oran/work/RedisLabs/garantia.redis/src/socket.c:336
    #8 0x55fb58447e61 in aeProcessEvents /home/oran/work/RedisLabs/garantia.redis/src/ae.c:460
    #9 0x55fb58447e61 in aeMain /home/oran/work/RedisLabs/garantia.redis/src/ae.c:520
    #10 0x55fb5840867a in main /home/oran/work/RedisLabs/garantia.redis/src/server.c:9992
    #11 0x7fbda07d9d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #12 0x7fbda07d9e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #13 0x55fb5840b4a4 in _start (/home/oran/work/RedisLabs/garantia.redis/src/redis-server+0x1754a4)

0x6030000a91b0 is located 0 bytes inside of 32-byte region [0x6030000a91b0,0x6030000a91d0)
freed by thread T0 here:
    #0 0x7fbda0e85537 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x55fb58920790 in functionsLibCtxFree /home/oran/work/RedisLabs/garantia.redis/src/functions.c:201
    #2 0x55fb58928066 in functionsLibCtxClearCurrent /home/oran/work/RedisLabs/garantia.redis/src/functions.c:187
    #3 0x55fb5895f408 in emptyData.constprop.1.isra.0 /home/oran/work/RedisLabs/garantia.redis/src/db.c:1339
    #4 0x55fb585a1246 in readSyncBulkPayload /home/oran/work/RedisLabs/garantia.redis/src/replication.c:2466
    #5 0x55fb588f21d7 in callHandler /home/oran/work/RedisLabs/garantia.redis/src/connhelpers.h:58
    #6 0x55fb588f21d7 in connSocketEventHandler /home/oran/work/RedisLabs/garantia.redis/src/socket.c:336
    #7 0x55fb58447e61 in aeProcessEvents /home/oran/work/RedisLabs/garantia.redis/src/ae.c:460
    #8 0x55fb58447e61 in aeMain /home/oran/work/RedisLabs/garantia.redis/src/ae.c:520
    #9 0x55fb5840867a in main /home/oran/work/RedisLabs/garantia.redis/src/server.c:9992
    #10 0x7fbda07d9d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    ```

Copy link
Member

@oranagra oranagra left a comment

Choose a reason for hiding this comment

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

thanks!

@tezc tezc merged commit a0da839 into redis:unstable Mar 26, 2025
18 checks passed
@tezc tezc deleted the fix-repl-uaf branch March 26, 2025 20:41
funny-dog pushed a commit to funny-dog/redis that referenced this pull request Sep 17, 2025
When the diskless load configuration is set to on-empty-db, we retain a
pointer to the function library context. When emptyData() is called, it
frees this function library context pointer, leading to a use-after-free
situation.

I refactored code to ensure that emptyData() is called first, followed
by retrieving the valid pointer to the function library context.

Refactored code should not introduce any runtime implications.

Bug introduced by redis#13495 (Redis 8.0)

Co-authored-by: Oran Agra <oran@redislabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants