Skip to content

fix: re-validate container status under lock before delete (TOCTOU)#1860

Open
radheradhe01 wants to merge 1 commit into
apple:mainfrom
radheradhe01:fix/delete-toctou-status-recheck
Open

fix: re-validate container status under lock before delete (TOCTOU)#1860
radheradhe01 wants to merge 1 commit into
apple:mainfrom
radheradhe01:fix/delete-toctou-status-recheck

Conversation

@radheradhe01

@radheradhe01 radheradhe01 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

ContainersService.delete reads the container status outside the lock, then in the default branch acquires the lock and calls cleanUp without re-checking status. startProcess holds the same lock while transitioning a container to .running and writing the state back. Between the unlocked read and acquiring the lock, a container observed as stopped can start; cleanUp only guards on containers[id] == nil, not status, so it then deletes the bundle of a now-running container (TOCTOU).

This change re-reads the status inside the lock in the default branch and refuses the delete if the container has since become .running/.stopping, mirroring the existing message used for the non-forced running case. Only the non-forced delete path changes; the --force path is unchanged.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

Verified by static / code-level review; not built locally (no macOS 26 toolchain available here) — CI build will validate.

### Problem
`ContainersService.delete` reads the container status **outside** the lock:

```swift
let state = try self._getContainerState(id: id)   // unlocked read
switch state.snapshot.status {
...
default:
    try await self.lock.withLock { context in
        try await self.cleanUp(id: id, context: context)   // no status re-check
    }
}
```

`startProcess` holds the same lock while transitioning a container to `.running` and writing the state back. Between the unlocked read here and acquiring the lock, a container observed as stopped can start. `cleanUp` only guards on `containers[id] == nil`, not status, so it then deletes the bundle of a now-running container (TOCTOU).

### Fix
Re-read the status **inside** the lock in the `default` branch and refuse the delete if the container has since become `.running`/`.stopping`, mirroring the existing message used for the non-forced running case.

### Notes
Only the non-forced delete path changes; the `--force` path is unchanged.
@radheradhe01 radheradhe01 changed the title Re-validate container status under the lock before delete (TOCTOU) fix: re-validate container status under lock before delete (TOCTOU) Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant