Skip to content

fix(uffd): log serve-loop failures and drop the stale handle TODO (rebased #3132) - #3718

Open
AdaAibaby wants to merge 1 commit into
e2b-dev:mainfrom
AdaAibaby:fix/uffd-handle-failure-log
Open

AdaAibaby wants to merge 1 commit into
e2b-dev:mainfrom
AdaAibaby:fix/uffd-handle-failure-log

Conversation

@AdaAibaby

Copy link
Copy Markdown
Contributor

Summary

The userfaultfd (UFFD) serve goroutine carried a stale, misleading TODO ("if the handle function fails, we should kill the sandbox") and logged nothing when handle() failed, leaving UFFD failures invisible in production.

Rebased, trimmed replacement for #3132 (the envd/sandbox and uffd code was reworked on main since). Revisits #3131.

Changes

  • uffd/uffd.go — remove the stale TODO; add an ERROR log for a genuine serve-loop failure. The log is gated on exitErr != nil, which the existing stopping-time check already zeroes for an expected close (net.ErrClosed / context.Canceled), so it does not fire on a normal sandbox stop — only on real failures.
  • sandbox/sandbox.go — add an accurate comment on the resume-path lifecycle watcher: a serve-loop failure completes fcUffd.Exit(), and the select { case <-fcUffd.Exit().Done(): ... } there turns that into sbx.Stop(), so a dead UFFD handler does not leave a VM without a page-fault handler. Scoped to the resume path (the one that actually watches fcUffd.Exit().Done()).
  • uffd/handle_failure_log_test.go (new) — asserts the invariant the log depends on: a genuine handle failure (malformed handshake) completes u.Exit() with a non-nil error.

Scope note

Deliberately minimal, matching what was welcomed for a fresh PR: the log line and the TODO removal. The original #3132 claimed the sandbox "is already stopped" unconditionally; on current main that is only true on the resume path (the create path's watcher waits on fcHandle.Exit only), so the comment is scoped accordingly rather than restated as universal.

Test

go build (uffd + sandbox), go vet, gofmt, and the full pkg/sandbox/uffd suite pass.

The uffd serve goroutine carried a stale TODO ("if the handle function fails,
we should kill the sandbox") and logged nothing when handle() failed, so a
userfaultfd failure was invisible in production.

- Remove the misleading TODO.
- Log the failure at ERROR, but only for a genuine serve-loop failure: the
  existing stopping-time close (net.ErrClosed / context.Canceled) already
  zeroes exitErr, so the log is gated on exitErr != nil and does not fire on
  normal sandbox stop.
- Add an accurate comment on the resume-path lifecycle watcher noting that a
  completed fcUffd.Exit() (which a serve-loop failure triggers) is turned into
  a sandbox stop there, so a dead UFFD handler does not leave a VM without a
  page-fault handler. Scoped to the resume path, which is the one that watches
  fcUffd.Exit().Done().

Rebased, trimmed replacement for e2b-dev#3132 (envd/sandbox code was reworked since).
Adds a focused test asserting a handle failure surfaces a non-nil uffd exit
error - the condition that gates the new log. Revisits e2b-dev#3131.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants