Open
Description
Crash report
This issue is related to #871:
- CVE-2024-31449 was found in Redis, and the same behavior is reproduced in KeyDB.
- A Lua stack overflow causes a crash.
- According to the Redis security advisory, this vulnerability can lead to RCE attacks
- Redis security advisory
=== KEYDB BUG REPORT START: Cut & paste starting from here ===
122522:122529:M 28 Mar 2025 20:50:38.439 # KeyDB 255.255.255 crashed by signal: 11, si_code: 1
122522:122529:M 28 Mar 2025 20:50:38.439 # Accessing address: 0x771330bfd75f
122522:122529:M 28 Mar 2025 20:50:38.439 # Crashed running the instruction at: 0x624cced810a8
------ STACK TRACE ------
EIP:
src/keydb-server *:6379(+0x1b50a8) [0x624cced810a8]
Backtrace:
/lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7712b6442520]
src/keydb-server *:6379(+0x1b50a8) [0x624cced810a8]
src/keydb-server *:6379(+0x19cadd) [0x624cced68add]
src/keydb-server *:6379(+0x1a72f7) [0x624cced732f7]
src/keydb-server *:6379(+0x19d17d) [0x624cced6917d]
src/keydb-server *:6379(+0x19c473) [0x624cced68473]
src/keydb-server *:6379(+0x19d324) [0x624cced69324]
src/keydb-server *:6379(lua_pcall+0x5c) [0x624cced666cc]
src/keydb-server *:6379(evalGenericCommand(client*, int)+0x321) [0x624ccecee421]
src/keydb-server *:6379(call(client*, int)+0xa7) [0x624ccec3cff7]
src/keydb-server *:6379(processCommand(client*, int)+0x79c) [0x624ccec3edcc]
src/keydb-server *:6379(processCommandAndResetClient(client*, int)+0x6d) [0x624ccec5bb5d]
src/keydb-server *:6379(processInputBuffer(client*, bool, int)+0x254) [0x624ccec5c024]
src/keydb-server *:6379(readQueryFromClient(connection*)+0x789) [0x624ccec5d1a9]
src/keydb-server *:6379(connSocketEventHandler(aeEventLoop*, int, void*, int)+0x1e0) [0x624cced51f40]
src/keydb-server *:6379(ProcessEventCore+0xf8) [0x624ccec29538]
src/keydb-server *:6379(aeProcessEvents+0x17d) [0x624ccec2d60d]
src/keydb-server *:6379(aeMain+0x3e) [0x624ccec2de9e]
src/keydb-server *:6379(workerThreadMain(void*)+0x12d) [0x624ccec45dcd]
/lib/x86_64-linux-gnu/libc.so.6(+0x94ac3) [0x7712b6494ac3]
/lib/x86_64-linux-gnu/libc.so.6(+0x126850) [0x7712b6526850]
------ REGISTERS ------
122522:122529:M 28 Mar 2025 20:50:38.440 #
RAX:0000771330bfd75e RBX:0000000000000fff
RCX:0000624ccee38ff8 RDX:0000000000000046
RDI:00007712b5ac2050 RSI:00007712b0bfd75f
RBP:00007712b4a0f000 RSP:00007712b0bfd760
R8 :00007712b0bfd760 R9 :ffffffff80000000
R10:00007712b5ac2030 R11:0000000000000000
R12:0000000080000000 R13:00007712afe28094
R14:0000000000000030 R15:00007712b5ac2030
RIP:0000624cced810a8 EFL:0000000000010206
CSGSFS:002b000000000033
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd76f) -> 00007712afe28090
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd76e) -> 00007712afe28094
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd76d) -> 00007712b5ac2030
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd76c) -> 00007712b4a0f000
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd76b) -> 0000000000000030
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd76a) -> 00007712b4a0f000
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd769) -> 00007712b5ac2030
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd768) -> 0000000000000000
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd767) -> 0000624cced71c8f
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd766) -> 0000000000000064
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd765) -> 0000624cced68add
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd764) -> 00000000ffffffff
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd763) -> 00007712b4a0f000
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd762) -> 00007712b5ac2030
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd761) -> 8ce7e5d8e56e4300
122522:122529:M 28 Mar 2025 20:50:38.440 # (00007712b0bfd760) -> 00007712b5a0b488
------ INFO OUTPUT ------
# Server
redis_version:255.255.255
redis_git_sha1:603ebb27
redis_git_dirty:0
redis_build_id:2f16160df6f843dc
redis_mode:standalone
os:Linux 6.8.0-52-generic x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:11.4.0
process_id:122522
process_supervised:no
run_id:72ac0b64c935a981214bbf16489ffd93ab438203
tcp_port:6379
server_time_usec:1743162638440547
uptime_in_seconds:852
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:15109390
executable:/home/dongyeonkim/Desktop/KeyDB/src/keydb-server
config_file:
availability_zone:
features:cluster_mget
# Clients
connected_clients:1
cluster_connections:0
maxclients:10000
client_recent_max_input_buffer:24
client_recent_max_output_buffer:0
blocked_clients:0
tracking_clients:0
clients_in_timeout_table:0
current_client_thread:0
thread_0_clients:1
# Memory
used_memory:1507968
used_memory_human:1.44M
used_memory_rss:15335424
used_memory_rss_human:14.62M
used_memory_peak:1568056
used_memory_peak_human:1.50M
used_memory_peak_perc:96.17%
used_memory_overhead:1463312
used_memory_startup:1442360
used_memory_dataset:44656
used_memory_dataset_perc:68.06%
allocator_allocated:2374608
allocator_active:2949120
allocator_resident:6549504
total_system_memory:16458354688
total_system_memory_human:15.33G
used_memory_lua:35840
used_memory_lua_human:35.00K
used_memory_scripts:448
used_memory_scripts_human:448B
number_of_cached_scripts:4
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.24
allocator_frag_bytes:574512
allocator_rss_ratio:2.22
allocator_rss_bytes:3600384
rss_overhead_ratio:2.34
rss_overhead_bytes:8785920
mem_fragmentation_ratio:10.47
mem_fragmentation_bytes:13870384
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:20504
mem_aof_buffer:0
mem_allocator:jemalloc-5.2.1
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0
storage_provider:none
available_system_memory:unavailable
# Persistence
loading:0
current_cow_size:0
current_cow_size_age:0
current_fork_perc:0.00
current_save_keys_processed:0
current_save_keys_total:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1743161786
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0
module_fork_in_progress:0
module_fork_last_cow_size:0
# Stats
total_connections_received:2
total_commands_processed:12
instantaneous_ops_per_sec:0
total_net_input_bytes:760
total_net_output_bytes:47863
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
expire_cycle_cpu_milliseconds:9
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
total_forks:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
tracking_total_keys:0
tracking_total_items:0
tracking_total_prefixes:0
unexpected_error_replies:0
total_error_replies:5
dump_payload_sanitizations:0
total_reads_processed:18
total_writes_processed:16
instantaneous_lock_contention:1
avg_lock_contention:0.000000
storage_provider_read_hits:0
storage_provider_read_misses:0
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:102270dbe450141dcd5fcdd351049293b34f8ee2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:0.714675
used_cpu_user:2.331960
used_cpu_sys_children:0.000000
used_cpu_user_children:0.000000
server_threads:1
long_lock_waits:29
used_cpu_sys_main_thread:0.541682
used_cpu_user_main_thread:1.325301
# Modules
# Commandstats
cmdstat_eval:calls=6,usec=385,usec_per_call=64.17,rejected_calls=2,failed_calls=1
cmdstat_info:calls=1,usec=120,usec_per_call=120.00,rejected_calls=0,failed_calls=0
cmdstat_ping:calls=2,usec=2,usec_per_call=1.00,rejected_calls=0,failed_calls=0
cmdstat_command:calls=2,usec=1688,usec_per_call=844.00,rejected_calls=0,failed_calls=0
cmdstat_echo:calls=1,usec=4,usec_per_call=4.00,rejected_calls=0,failed_calls=0
# Errorstats
errorstat_ERR:count=5
# Cluster
cluster_enabled:0
# Keyspace
# KeyDB
mvcc_depth:0
------ CLIENT LIST OUTPUT ------
id=4 addr=127.0.0.1:48242 laddr=127.0.0.1:6379 fd=13 name= age=136 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=40954 argv-mem=41 obl=0 oll=0 omem=0 tot-mem=61505 events=r cmd=eval user=default redir=-1
------ CURRENT CLIENT INFO ------
id=4 addr=127.0.0.1:48242 laddr=127.0.0.1:6379 fd=13 name= age=136 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=40954 argv-mem=41 obl=0 oll=0 omem=0 tot-mem=61505 events=r cmd=eval user=default redir=-1
argv[0]: 'EVAL'
argv[1]: 'return bit.tohex(65535, -2147483648)'
argv[2]: '0'
------ MODULES INFO OUTPUT ------
------ FAST MEMORY TEST ------
122522:122529:M 28 Mar 2025 20:50:38.440 # main thread terminated
122522:122529:M 28 Mar 2025 20:50:38.440 # Bio thread for job type #0 terminated
122522:122529:M 28 Mar 2025 20:50:38.440 # Bio thread for job type #1 terminated
122522:122529:M 28 Mar 2025 20:50:38.441 # Bio thread for job type #2 terminated
Fast memory test PASSED, however your memory can still be broken. Please run a memory test for several hours if possible.
------ DUMPING CODE AROUND EIP ------
Symbol: (null) (base: (nil))
Module: src/keydb-server *:6379 (base 0x624ccebcc000)
$ xxd -r -p /tmp/dump.hex /tmp/dump.bin
$ objdump --adjust-vma=(nil) -D -b binary -m i386:x86-64 /tmp/dump.bin
------
=== KEYDB BUG REPORT END. Make sure to include from START to END. ===
Please report the crash by opening an issue on github:
https://github.com/JohnSully/KeyDB/issues
Suspect RAM error? Use keydb-server --test-memory to verify it.
- After the attack, the server disconnected.
dongyeonkim@dongyeonkim-Modern-15-A11M:~/Desktop/KeyDB$ src/keydb-cli
Message of the day:
KeyDB has now joined Snap! See the announcement at: https://docs.keydb.dev/news
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> EVAL "return bit.tohex(65535, -2147483648)" 0 //Payload
Error: Server closed the connection
127.0.0.1:6379>
Aditional information
- KeyDB version : KeyDB v6.3.4
- Operating system : Linux
- Operating system, version and so on : Ubuntu 22.04.5 LTS 64bit
To reproduce
To reproduce this error:
- Send this payload to the server.
EVAL "return bit.tohex(65535, -2147483648)" 0
- KeyDB clients will be disconnected because of a crash.
Description
Located in deps/lua/src/lua_bit.c
static int bit_tohex(lua_State *L)
{
UBits b = barg(L, 1);
SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
const char *hexdigits = "0123456789abcdef";
char buf[8];
int i;
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
if (n > 8) n = 8;
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
lua_pushlstring(L, buf, (size_t)n);
return 1;
}
- The function
static int bit_tohex(lua_State *L)
setsb
from the first argument andn
from second (defaulting to 8 if missing).
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
- At #L134, if
n
is negative, the code tries to make it positive. - But an
int
only stores values from -2,147,483,648 to 2,147,483,647. - When you input -2,147,483,648 and compute
n = -n
, the result should be 2,147,483,648. - However this number is too big for an
int
. - So an intger overflow occurs and
n
stays as -2,147,483,648.
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } //buf[0xffffffff]
- This flaw bypasses the
(n > 8)
check at #L137. - At #L138, a negative
n
makes the loop access buf[0xffffffff] and crash. - This bug was found in Redis and is labeled CVE-2024-31449.
Solution
- Add the following code above line #L134, as shown in the redis commit.
if (n == INT32_MIN) n = INT32_MIN+1;
- This code is a condition that prevents integer overflow.
dongyeonkim@dongyeonkim-Modern-15-A11M:~/Desktop/KeyDB$ src/keydb-cli
Message of the day:
KeyDB has now joined Snap! See the announcement at: https://docs.keydb.dev/news
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> EVAL "return bit.tohex(65535, -2147483648)" 0
"0000FFFF"
127.0.0.1:6379>
- After applying this code, here's what happens during an attack.
- Checking the integer range prevents a stack overflow.
Metadata
Metadata
Assignees
Labels
No labels