Skip to content

Fail closed on an unknown BranchAction - #272

Merged
congwang-mk merged 3 commits into
mainfrom
ffi-branch-action-fail-closed
Oct 3, 2026
Merged

congwang-mk merged 3 commits into
mainfrom
ffi-branch-action-fail-closed

Conversation

@congwang-mk

Copy link
Copy Markdown
Contributor

Fixes #175.

An unrecognized branch action fell through to Commit, the only action that writes the COW branch into the workdir, and the build still reported success. The same fallback existed at three layers:

  • FFI: on_exit/on_error mapped any discriminant outside 0..=3 to Commit. An out-of-range value is a binding-layer programmer error, which the C ABI already signals with a null builder, so the setter now frees the builder and returns null; the setter chain carries it through and sandlock_sandbox_build fails with err = -1.
  • Go: BranchAction is a plain uint8, so Sandbox{OnExit: BranchAction(9)} reached the C ABI. buildPolicy now rejects it up front with an error naming the value.
  • Python: the SDK used dict.get(value, 0), so Sandbox(on_exit="Abort") committed. Both fields are now coerced through BranchAction at construction (raising ValueError) and looked up strictly at build.

Tests

  • New crates/sandlock-ffi/tests/branch_action.rs: 0..=3 round-trip for both setters; 4, 99, 255 fail the build.
  • Go TestRunUnknownBranchActionRejected.
  • Python: string coercion and rejection of an unknown value for both fields.

🤖 Generated with Claude Code

The on_exit/on_error setters mapped any unrecognized value to Commit,
the only action that writes the branch into the workdir, and the build
still reported success. A binding passing a bad value had its changes
merged with no way to notice.

An out-of-range discriminant is a binding-layer programmer error, which
the C ABI already signals with a null builder: drop the builder and
return null so the setter chain carries it through and the build fails
with err = -1, rather than guessing an action on the caller's behalf.

Fixes #175

Signed-off-by: Cong Wang <cwang@multikernel.io>
BranchAction is a plain uint8, so Sandbox{OnExit: BranchAction(9)}
compiles and reaches the C ABI. The FFI now fails such a build, but only
with a bare error code; checking up front, before the builder exists,
gives Go callers an error naming the bad value.

Signed-off-by: Cong Wang <cwang@multikernel.io>
The SDK mapped any unrecognized branch action to Commit through a
dict.get default, so Sandbox(on_exit="Abort") committed the workdir it
was meant to discard. Coerce both fields through BranchAction when the
Sandbox is constructed so a bad value raises ValueError immediately,
and look the discriminant up strictly when building.

Signed-off-by: Cong Wang <cwang@multikernel.io>
@congwang-mk
congwang-mk merged commit 1e697ce into main Oct 3, 2026
17 checks passed
@congwang-mk
congwang-mk deleted the ffi-branch-action-fail-closed branch October 3, 2026 02:30
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.

An unrecognized BranchAction discriminant silently commits the COW branch

1 participant