Skip to content

[CRASH] Lua library stack overflow can cause the KeyDB crash. (CVE-2024-31449) #905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
KIMDONGYEON00 opened this issue Mar 30, 2025 · 0 comments · May be fixed by #906
Open

[CRASH] Lua library stack overflow can cause the KeyDB crash. (CVE-2024-31449) #905

KIMDONGYEON00 opened this issue Mar 30, 2025 · 0 comments · May be fixed by #906

Comments

@KIMDONGYEON00
Copy link

KIMDONGYEON00 commented Mar 30, 2025

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) sets b from the first argument and n 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.
KIMDONGYEON00 pushed a commit to KIMDONGYEON00/KeyDB that referenced this issue Mar 30, 2025
@KIMDONGYEON00 KIMDONGYEON00 linked a pull request Mar 30, 2025 that will close this issue
KIMDONGYEON00 added a commit to KIMDONGYEON00/KeyDB that referenced this issue Mar 30, 2025
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 a pull request may close this issue.

1 participant