Skip to content

fix(mxc): reject a non-absolute wxc_exec_path at gateway startup - #3497

Open
pkhodade-NV wants to merge 1 commit into
windowsfrom
fix/mxc-require-absolute-wxc-exec-path
Open

pkhodade-NV wants to merge 1 commit into
windowsfrom
fix/mxc-require-absolute-wxc-exec-path

Conversation

@pkhodade-NV

Copy link
Copy Markdown
Collaborator

Summary

  • wxc_exec_path is the binary that builds every sandbox, but nothing validated it before spawning. A relative value -- including the shipped default, a bare "wxc-exec.exe" -- let PATH-lookup or working-directory-relative resolution execute a decoy binary with the gateway's identity instead of the approved wxc-exec, turning the containment mechanism itself into an arbitrary-code-execution primitive.
  • Live-confirmed: setting wxc_exec_path = "wxc-exec.exe" in the gateway config and starting the gateway succeeded cleanly with zero warning or diagnostic about the relative path.

Related Issue

No linked issue -- this is a security-sensitive, localized fix to a compute-driver config preflight hook that already existed for exactly this purpose (MxcFactory::validate_config, gated by supports_config_preflight() -> true) but performed no semantic validation at all, only shape deserialization.

Changes

  • openshell-driver-mxc: added MxcComputeConfig::validate_configuration, rejecting an empty or non-absolute wxc_exec_path with a diagnostic naming the field -- matching the Path::is_absolute() validation convention already used elsewhere in this codebase for exec/trust-relevant paths.
  • openshell-gateway: wired MxcFactory::validate_config to call it. This runs on every real gateway startup, matching the existing pattern other compute-driver factories (Docker, Kubernetes) already use for their own config validation.
  • Changed MxcComputeConfig::default()'s wxc_exec_path from the relative "wxc-exec.exe" to an empty string. The old default was itself the exact vulnerability this fix closes -- rejecting explicit relative values while leaving an equally-relative default in place would let an operator (or attacker steering config) route around the check by simply not setting the field. No usable-but-insecure fallback survives; wxc_exec_path must now be explicitly configured as an absolute path.

build() intentionally does not re-validate -- it trusts the single preflight gate, matching how Docker's factory is structured.

Testing

  • New unit tests in openshell-driver-mxc: validate_configuration_rejects_unset_wxc_exec_path (covers the now-empty default), validate_configuration_rejects_relative_wxc_exec_path, validate_configuration_accepts_absolute_wxc_exec_path.
  • Full crate suite passes: cargo test -p openshell-driver-mxc --target x86_64-pc-windows-msvc --lib.
  • cargo test -p openshell-gateway --target x86_64-pc-windows-msvc --lib passes, unaffected by this change.

Checklist

  • Tests added for the new behavior
  • No unrelated changes bundled in

Originally opened as GitLab MR !115 against our internal mirror; re-opened here against windows for upstream review. The GitLab MR also updated architecture/mxc-compute-driver.md, which does not exist on windows (the architecture doc structure has diverged) -- that doc change is dropped here as inapplicable; only the code fix (driver validation + gateway wiring) is carried over.

wxc_exec_path is the binary that builds every sandbox, but nothing
validated it before spawning: a relative value (including the shipped
default, a bare "wxc-exec.exe") let PATH-lookup or working-directory-
relative resolution execute a decoy binary with the gateway's identity
instead of the approved wxc-exec, turning the containment mechanism
itself into an arbitrary-code-execution primitive.

Add MxcComputeConfig::validate_configuration, wired into the existing
(previously no-op) compute-driver config preflight, rejecting an
empty or non-absolute wxc_exec_path with a clear diagnostic. Change
the default from the relative "wxc-exec.exe" to an empty string so
the field must be explicitly configured -- no usable-but-insecure
fallback survives. Update the architecture doc's stale "else PATH"
discovery claim to match.

Signed-off-by: Prashant Khodade <pkhodade@nvidia.com>
(cherry picked from commit d4192a0072f8f0ca0a4035f10cae07889c2b578f)
@copy-pr-bot

copy-pr-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@shailendra-nv shailendra-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for two gaps in this security fix: the gateway enforcement boundary is not covered by a regression test, and the new mandatory absolute-path configuration requirement is not documented. The core validation logic itself looks correct.

let _: openshell_driver_mxc::MxcComputeConfig = context.driver_config()?;
Ok(())
let config: openshell_driver_mxc::MxcComputeConfig = context.driver_config()?;
config.validate_configuration()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual enforcement boundary for the security fix, but the new tests only call MxcComputeConfig::validate_configuration directly. If this factory call regressed to the previous no-op, all added tests would still pass and relative paths would again reach startup. Please add a Windows gateway/config-preflight test that selects mxc and verifies omitted and relative paths fail while an absolute path passes.

// comment above). Shipping a bare relative filename here would
// silently reintroduce the exact PATH/CWD-hijack risk the
// validation exists to reject.
wxc_exec_path: String::new(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes an existing omitted field from a usable default to a startup error, but docs/reference/gateway-config.mdx and the MXC README only show examples; neither states that wxc_exec_path is now required and absolute. Please document the migration and requirement in this PR, as required for driver configuration default changes.

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.

2 participants