-
Notifications
You must be signed in to change notification settings - Fork 83
captureDenials run path does not check guarded capture availability before creating the sandbox #1248
Copy link
Copy link
Labels
Backend-ProcessContainerWindows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.Windows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.Issue-BugSomething is not working as intended.Something is not working as intended.OS-WindowsApplies specifically to Windows hosts or Windows behavior.Applies specifically to Windows hosts or Windows behavior.Priority2High-impact issue affecting key functionality; prioritize for the next appropriate release.High-impact issue affecting key functionality; prioritize for the next appropriate release.Release v1.0Issues tracked for the version 1.0 releaseIssues tracked for the version 1.0 release
Description
Activity
Metadata
Metadata
Assignees
Labels
Backend-ProcessContainerWindows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.Windows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.Issue-BugSomething is not working as intended.Something is not working as intended.OS-WindowsApplies specifically to Windows hosts or Windows behavior.Applies specifically to Windows hosts or Windows behavior.Priority2High-impact issue affecting key functionality; prioritize for the next appropriate release.High-impact issue affecting key functionality; prioritize for the next appropriate release.Release v1.0Issues tracked for the version 1.0 releaseIssues tracked for the version 1.0 release
Relevant area(s)
Windows
Brief description of your issue
mxc_enginealready has a cheap, read only availability check for the guarded WPRcaptureDenialsfallback, but only the probe uses it. The run path does not, so a request that is known to be unsatisfiable is accepted, a sandbox is built, and the failure arrives late as an untypedProcess errorwith exit-1.guarded_capture::is_available()(src/core/mxc_engine/src/guarded_capture.rs:97) verifies WPR is present and runsplm::trust::verify_and_pin_launch_binaryagainstplm.exe, which is the same trust check that later gates the elevation. The probe calls it (src/core/mxc_engine/src/probe.rs:101) and correctly reportsguarded WPR captureDenials fallback is unavailable.The run path calls only
factory_for_request, which checksrequest.policy.capture_denials.is_some()and nothing else. Seesrc/core/mxc_engine/src/run.rs:226andsrc/core/mxc_engine/src/dispatch.rs:177.To be clear, the trust failure itself is correct and should stay.
plm.exeself elevates, so refusing to elevate an unsigned binary is the right call. The problem is only when and how the failure surfaces. Any unsigned build hits this, including every local developer build, so it is not specific to CI.7 failing assertions in the 2026-09-23 nightly run. P15a fails on all four jobs, and P14c adds three more on the T3 job:
Related: #785 was the inverse, where the probe ignored
captureDenialsand reported a launchable tier. Here the probe is right and the run path ignores it. #1233 hits the samepsec_policy_compatiblefallback routing but fails further downstream onWRITE_DAC.Steps to reproduce
plm.exeis unsigned.processContainer.leastPrivilegewithprocessContainer.captureDenials.wxc-exec --probeagainst the actual run.Covered by
tests/scripts/run_processcontainer_privilege_test.ps1(P15a) andtests/scripts/run_processcontainer_capture_denials_test.ps1(P14c).Expected behavior
The run path applies the same availability gate the probe uses and rejects before creating a sandbox, with a typed error.
.github/copilot-instructions.mdstates unsupported policy must fail closed and be rejected before the sandbox is created.docs/schema.md:219documents this combination as a tier constraint with a guarded WPR fallback, so callers reasonably expect either a working fallback or a clean rejection.Actual behavior
The backend log shows the full sandbox being built first:
and only then:
The suspended child is terminated, the sandbox is torn down, and the process exits
-1.The three P14c failures are downstream of this. The run never launches, so no denials output path is ever reported: