Skip to content

Transfer timeout can DMA into freed pinned memory (use-after-free window) #403

Description

@xiaguan

Problem

When the requester-side transfer timeout fires in fetch_blocks_via_rdma (pegaflow-core/src/backing/rdma_fetch.rs), the completion receivers and all staged SegmentAllocs are dropped, returning the pinned staging chunks to the pool — while the RDMA READ work requests already posted to the NIC may still be in flight. A late completion then DMA-writes into memory the pool may have handed to someone else: silent data corruption, strictly worse than the lock leak this path was reviewed under.

The pool's memory stays registered with the NIC (whole-pool MR), so the HCA will not fault the write — nothing stops the stale READ from landing.

Same family: after a completion error, execute_batch (pegaflow-transfer/src/rc_backend/session.rs) returns with inflight non-empty, and the subsequent session drop destroys a QP with outstanding WQEs. Verbs allows destroy-with-outstanding (driver quiesces), but any WQE that completed into freed local memory before the destroy has already corrupted it. Before #399's worker-leak fix, leaked QPs incidentally masked this; now that sessions actually die, the window is real.

Suggested fix directions

  • On timeout/error, transition the QP to ERR (flushes outstanding WQEs) and drain the CQ before dropping the staged allocations; only then release the lock and return.
  • Alternatively, keep the staging chunks alive (hold the Arc<PinnedAllocation>s) until the session confirms quiescence.

Context

Flagged during the #399 review (pre-existing; not a regression of #399).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    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