https://github.com/valkey-io/valkey/issues/4207
A security-class issue — link above; worth trying to fix.
Classic trust-boundary length-contract mismatch: the command path requires job_name to be exactly 40 bytes,
but the RDB load path does not validate, so memcpy(..., 40) OOB-reads from a short SDS.
Nature of the bug (memory layout) #
Subsystem contract #
CLUSTER_NAMELEN == 40; job name is a fixed-length hex string (like a node id):
char name[CLUSTER_NAMELEN]; /* Unique name for the job, hex
* string, sha1-size. */
- Save path: always writes 40 bytes
rdbSaveRawString(rdb, job->name, CLUSTER_NAMELEN) - Command path: explicitly rejects non-40
sdslen(...) != CLUSTER_NAMELEN - Load path (the hole):
rdbLoadStringObject()accepts any length and hands it tocreateSlotImportJob()
Crash site #
// 这就是RDB导入的时候造成的问题?
slotMigrationJob *createSlotImportJob(client *c,
clusterNode *source_node,
char *name,
list *slot_ranges) {
slotMigrationJob *job = zcalloc(sizeof(slotMigrationJob));
memcpy(job->name, name, CLUSTER_NAMELEN);
When RDB job_name is only 1 byte:
heap: [sdshdr...]['A']['\0'][ 后续可能是 freelist/相邻分配物 ...]
^ objectGetVal()
memcpy 要读 40 字节 → 越过 SDS 逻辑长度 → heap OOB read
Destination job->name[40] is itself valid; the problem is the source lacks 40 readable bytes.
ASan reports read, not write — typical DoS (reliable crash), not a direct arbitrary write.
Attack surface #
Requires placing a malicious dump.rdb in the instance data directory with cluster-enabled yes.
Common scenarios: backup poisoning, shared storage, bad restore flows. Not an unauthenticated remote protocol bug, but a startup trusted-input validation failure.
Trying to reproduce #
How did AI find this? Fascinating. The issue describes the repro path in detail.
| Step | What |
|---|---|
| A | Branch from unstable |
| B | ASan repro (confirm crash) |
| C | Add length check as suggested |
| D | Add regression test (preferably Tcl, reject at startup load) |
| E | Push to fork quanyeyang/valkey, open PR against valkey-io/valkey, link #4207 |
# 1) ASan 构建
make distclean
make -j"$(nproc)" SANITIZER=address OPTIMIZATION=-O0
# 2) 按 issue 生成 empty.rdb → 插入 opcode 0xF3 短 name → 重算 CRC64
# 3) cluster-enabled 实例加载该 dump.rdb
# 期望:ASan 在 memcpy 处报 heap-buffer-overflow READ