mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #4303] [Bug]: P2P Store GetReplica does not validate the caller's sizeList against the stored payload layout #1080
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#1080
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @yaojiejia on GitHub (Sep 23, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/4303
Bug Report
Environment: main (
e88aacf2),mooncake-p2p-store/src/p2pstore/core.go. Not platform specific.What happens
GetReplicaonly checks thataddrListandsizeListhave the same non-zero length (core.go:401-404). It never comparessizeListwith theSizeList,Sizeor shard count stored in etcd for that payload.hasSameLayout(core.go:363) only compares two etcd snapshots to each other.doGetReplica(core.go:284-303) then walks the caller's buffers inMaxShardSizesteps, indexespayload.Shards[taskID]with no bounds check, and transfers the storedshard.Lengthinto the caller's address:If the caller's sizes do not match the registered layout, one of three things happens:
taskIDruns pastlen(payload.Shards)and the process panics withindex out of rangeon the calling goroutine.tcp_transport.cpp:606uses the raw pointer). On RDMA the slicer clamps to the registered buffer, so it fails unless the neighbouring memory is also registered, in which case the data silently lands there.GetReplicareturnsnil, andupdatePayloadMetadataadvertises this node as a replica source. The caller believes it has the whole file.The shipped example passes a hardcoded
fileSize, not the layout fromList(), so a mismatch reaches this path directly.To reproduce
Using the existing test fakes in
metadata_recheck_test.go:Expected
GetReplicashould returnErrInvalidArgumentunlesslen(sizeList) == len(payload.SizeList)and every entry matches, checked right after the firstmetadata.Get. That one check closes all three cases.Suggested fix
Add the layout check in
GetReplicabefore callingdoGetReplica, and add a regression test with the fakes above (mismatched larger size, mismatched smaller size, and a matching layout that still succeeds).Before submitting...
@github-actions[bot] commented on GitHub (Sep 23, 2026):
Thanks for opening this issue, @yaojiejia!
70050131A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide