Skip to content

performExportCleanup's ownership guard lets an already-orphaned object through, so abandonExports doubles as an unchecked retireImports #1080

Description

@sirtimid

Found in a second reading of #1022 (sirtimid/gc-delivery-hardening).

What

The new guard rejects only when getOwner returns a different live endpoint. An object whose owner mapping is already gone returns undefined, falls through the guard, and reaches forgetKref, which tears down whatever c-list entry the calling endpoint has — including an import entry.

Failure scenario

  1. v1 abandons ko1. This PR now orphans it, so getOwner(ko1) is undefined, while v2 still reaches it.
  2. v2 issues syscall.abandonExports([ko1]) naming its import vref.
  3. owner is undefined → the new guard does not throw.
  4. checkReachable is false for the abandon path, so the reachability assertion performRetireImports would apply is skipped.
  5. v2's reachable import entry is torn down.

Counts stay self-consistent, because deleteCListEntry derives direction from the eref — so the audit sees nothing. The syscall has silently acted as an unchecked retireImports on an object v2 still reaches.

Introduced by this PR (the guard and the orphaning are both new).

Suggested fix

Also require that the calling endpoint's entry is an export:

parseRef(krefToEref(endpointId, kref)).direction === 'export'

That is the property abandonExports actually means, and it rejects the import case whether or not an owner is recorded.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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