Skip to content

[Bug] provenance guard rejects valid interior ranges in copy_to/copy_from #1537

Description

@high-cloud

Diagnosis

simpler runtime provenance guard - copy_to() / copy_from() only accepts an exact live allocation base, but the public runtime API has no supported base-plus-offset copy operation. This prevents valid partial updates to a persistent device allocation.

Description

A caller can allocate a long-lived device buffer and safely update a page inside it, but the current provenance check rejects the page address as an "interior pointer" before the native copy is issued.

This surfaced while synchronizing newly-cleared pages of a resident DeepSeek V4 decode cache. The same issue is reproducible without serving or NPU hardware using the Python orchestration guard.

Minimal reproduction

base = orch.malloc(worker_id=0, size=64)

# A 16-byte write wholly inside the live 64-byte allocation.
orch.copy_to(worker_id=0, dst=base + 32, src=host_ptr, size=16)
# Current result: ValueError: device pointer ... is not a live allocation

The guard currently looks up provenance by the exact (worker_id, ptr) key, so it does not recognize base + 32 as part of the allocation.

Expected behavior

  • copy_to() and copy_from() should accept a range wholly contained in a live allocation on the target worker.
  • Wrong-worker, stale, and out-of-range pointers must still be rejected.
  • free() must continue to require the exact allocation base.

Suggested fix

Record allocation sizes in provenance. Add a range validator for copy operations:

base <= ptr && ptr + nbytes <= base + allocation_size

Use overflow-safe arithmetic. Keep the existing exact-base validator for free() and APIs that require a base pointer.

CommDomain windows should similarly carry their live extent if copy APIs support window/buffer offsets.

Regression coverage

A device-free mocked-orchestrator test should cover:

  1. malloc(64) then copy_to(base + 32, ..., 16) succeeds.
  2. copy_to(base + 63, ..., 2) is rejected as out of range.
  3. The same address on another worker is rejected.
  4. A copy after free(base) is rejected.
  5. free(base + 32) remains rejected.

Environment

Component Version
pypto-serving 5ab2a0c
pypto-lib b183933
pypto 937ebbb7
simpler 9922afdb
PTOAS 0.48
Device / platform Ascend A2A3, 8 devices

Additional context

The immediate serving workaround is a local copy_to_offset(base, offset, ...) helper that validates the base before applying the offset. That helper is not present in origin/main; a first-class runtime solution would avoid every caller needing to reimplement this pattern.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions