Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/wsl/wsl-container-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ Verify the binary starts without errors:
.\src\target\x86_64-pc-windows-msvc\release\wxc-exec.exe --help
```

> **Note:** paths in this guide use the x64 target directory. On an ARM64 host
> `build.bat` targets `aarch64-pc-windows-msvc`, so substitute that directory.
Comment thread
theelliotm marked this conversation as resolved.
> The WSLC scripts under `scripts\` and `tests\scripts\` pick the host-arch
> directory themselves.

> **Note:** `wxc-exec.exe` does **not** require `wslcsdk.dll` at startup. The
> DLL is loaded at runtime only when the WSLC backend is invoked. All other
> backends (Process Container, Windows Sandbox) work without it.
Expand Down
2 changes: 1 addition & 1 deletion docs/wsl/wslc-sdk-bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ match the pinned SDK.
staged next to `wxc-exec.exe`, then:

```powershell
cargo build -p wxc --features wslc --release --target x86_64-pc-windows-msvc
cargo build -p wxc --features wslc --release --target x86_64-pc-windows-msvc # aarch64-pc-windows-msvc on ARM64
.\tests\scripts\run_wslc_all_tests.ps1
```

Expand Down
4 changes: 0 additions & 4 deletions scripts/ci/run_backend_validation_tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,6 @@ switch ($Backend) {
}
}
'wslc' {
# The current WSLC helper hardcodes the x64 target when locating assets.
if ($Architecture -ne 'x64') {
throw 'The existing WSLC test harness is not architecture-portable yet.'
}
Invoke-TestScript -Path (Join-Path $testScriptRoot 'run_wslc_all_tests.ps1') -Arguments @{
WxcExecPath = $wxc
}
Expand Down
6 changes: 5 additions & 1 deletion scripts/setup-wslc.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ $ErrorActionPreference = "Stop"
$RepoRoot = Split-Path -Parent $PSScriptRoot

# Discover wxc-exec.exe -- prefer explicit path, then probe target dirs.
$Target = "x86_64-pc-windows-msvc"
$Target = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') {
Comment thread
theelliotm marked this conversation as resolved.
'aarch64-pc-windows-msvc'
} else {
'x86_64-pc-windows-msvc'
}
if ($WxcExecPath) {
$WxcExec = $WxcExecPath
} else {
Expand Down
9 changes: 7 additions & 2 deletions tests/scripts/run_wslc_all_tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ $ErrorActionPreference = "Stop"
$RepoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$TestConfigs = Join-Path $RepoRoot "tests\configs"

# Find binary -- prefer explicit path, then probe target-specific and default dirs.
$Target = "x86_64-pc-windows-msvc"
# Find binary -- prefer explicit path, then probe target-specific and default
# dirs. Use the host arch to determine which target to use.
$Target = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') {
Comment thread
theelliotm marked this conversation as resolved.
'aarch64-pc-windows-msvc'
} else {
'x86_64-pc-windows-msvc'
}
Comment thread
theelliotm marked this conversation as resolved.
$Profile = if ($Debug) { "debug" } else { "release" }

if ($WxcExecPath) {
Expand Down
229 changes: 117 additions & 112 deletions tests/scripts/run_wslc_denied_masking_test.ps1
Original file line number Diff line number Diff line change
@@ -1,112 +1,117 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# WSLC denied-path masking test.
#
# WSLC masks a denied path by simply NOT mounting it (see policy_mapping.rs:
# `build_volume_mounts` maps only readwrite/readonly paths; denied paths are
# omitted, and `normalize_object_conflicts` tightens same-object aliases to
# deny). Unlike the Linux LXC/Bubblewrap backends, WSLC does not carve a denied
# child out of a mounted parent, so this test uses the sibling model: a
# read-write subdir (`visible`) is mounted as a positive control, while a denied
# sibling file and a denied sibling directory are left unmounted and must be
# invisible inside the container.
#
# This script owns the on-disk fixture so the config is never run without it
# (running the config alone would pass for the wrong reason -- the paths simply
# would not exist).
#
# Usage:
# .\run_wslc_denied_masking_test.ps1 # auto-discovers wxc-exec.exe
# .\run_wslc_denied_masking_test.ps1 -WxcExecPath <path> # explicit binary
# .\run_wslc_denied_masking_test.ps1 -Debug # debug build + --debug

param(
[switch]$Debug,
[string]$WxcExecPath
)

$ErrorActionPreference = "Stop"
$RepoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$ConfigPath = Join-Path $RepoRoot "tests\configs\wslc_denied_masking.json"

# Resolve the binary: explicit path, then target-specific and default dirs.
$Target = "x86_64-pc-windows-msvc"
$Profile = if ($Debug) { "debug" } else { "release" }
if ($WxcExecPath) {
$WxcExec = $WxcExecPath
} else {
$Candidates = @(
(Join-Path $RepoRoot "src\target\$Target\$Profile\wxc-exec.exe"),
(Join-Path $RepoRoot "src\target\$Profile\wxc-exec.exe")
)
$WxcExec = $Candidates | Where-Object { Test-Path $_ } | Select-Object -First 1
}
if (-not $WxcExec -or -not (Test-Path $WxcExec)) {
Write-Host "ERROR: wxc-exec.exe not found. Build with: cargo build --features wslc --release --target $Target" -ForegroundColor Red
exit 1
}

# Fixed paths must match tests\configs\wslc_denied_masking.json.
$Base = "C:\wslcmask"
$VisibleDir = Join-Path $Base "visible"
$SecretFile = Join-Path $Base "secret_file.txt"
$SecretDir = Join-Path $Base "secret_dir"

function Remove-Fixture {
Remove-Item -Recurse -Force $Base -ErrorAction SilentlyContinue
}

Remove-Fixture
try {
# Positive control (mounted read-write), plus a denied sibling file and a
# denied sibling directory, each holding secret content readable on the host.
New-Item -ItemType Directory -Path $VisibleDir -Force | Out-Null
New-Item -ItemType Directory -Path $SecretDir -Force | Out-Null
Set-Content (Join-Path $VisibleDir "control.txt") "VISIBLE_SECRET"
Set-Content $SecretFile "FILE_SECRET"
Set-Content (Join-Path $SecretDir "inner.txt") "DIR_SECRET"

Write-Host "Running WSLC denied-path masking test (denied sibling file + dir left unmounted)..."
$wxcArgs = @()
if ($Debug) { $wxcArgs += "--debug" }
$wxcArgs += $ConfigPath

$prev = $ErrorActionPreference
$ErrorActionPreference = "Continue"
$output = & $WxcExec @wxcArgs 2>&1 | Out-String
$ErrorActionPreference = $prev
Write-Host $output

$fail = 0

# Positive control: the mounted sibling must be readable, proving the mount
# is present (so masking below is attributable to the deny, not absence).
if (($output -match "VISIBLE_OK") -and ($output -notmatch "VISIBLE_MISSING")) {
Write-Host "PASS: non-denied sibling readable (mount present)." -ForegroundColor Green
} else {
Write-Host "FAIL: non-denied sibling not readable - mount missing, test inconclusive." -ForegroundColor Red
$fail = 1
}

if (($output -match "FILE_MASKED_OK") -and ($output -notmatch "FILE_LEAK")) {
Write-Host "PASS: denied file not mounted (masked)." -ForegroundColor Green
} else {
Write-Host "FAIL: denied file content leaked." -ForegroundColor Red
$fail = 1
}

if (($output -match "DIR_MASKED_OK") -and ($output -notmatch "DIR_LEAK")) {
Write-Host "PASS: denied directory not mounted (masked)." -ForegroundColor Green
} else {
Write-Host "FAIL: denied directory content leaked." -ForegroundColor Red
$fail = 1
}

if ($fail -ne 0) { $exit = 1 } else { $exit = 0 }
} finally {
Remove-Fixture
}

Write-Host "WSLC denied-path masking test complete."
exit $exit
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# WSLC denied-path masking test.
#
# WSLC masks a denied path by simply NOT mounting it (see policy_mapping.rs:
# `build_volume_mounts` maps only readwrite/readonly paths; denied paths are
# omitted, and `normalize_object_conflicts` tightens same-object aliases to
# deny). Unlike the Linux LXC/Bubblewrap backends, WSLC does not carve a denied
# child out of a mounted parent, so this test uses the sibling model: a
# read-write subdir (`visible`) is mounted as a positive control, while a denied
# sibling file and a denied sibling directory are left unmounted and must be
# invisible inside the container.
#
# This script owns the on-disk fixture so the config is never run without it
# (running the config alone would pass for the wrong reason -- the paths simply
# would not exist).
#
# Usage:
# .\run_wslc_denied_masking_test.ps1 # auto-discovers wxc-exec.exe
# .\run_wslc_denied_masking_test.ps1 -WxcExecPath <path> # explicit binary
# .\run_wslc_denied_masking_test.ps1 -Debug # debug build + --debug

param(
[switch]$Debug,
[string]$WxcExecPath
)

$ErrorActionPreference = "Stop"
$RepoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$ConfigPath = Join-Path $RepoRoot "tests\configs\wslc_denied_masking.json"

# Resolve the binary: explicit path, then target-specific and default dirs.
# Use the host arch to determine which target to use.
$Target = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') {
'aarch64-pc-windows-msvc'
} else {
'x86_64-pc-windows-msvc'
}
$Profile = if ($Debug) { "debug" } else { "release" }
if ($WxcExecPath) {
$WxcExec = $WxcExecPath
} else {
$Candidates = @(
(Join-Path $RepoRoot "src\target\$Target\$Profile\wxc-exec.exe"),
(Join-Path $RepoRoot "src\target\$Profile\wxc-exec.exe")
)
$WxcExec = $Candidates | Where-Object { Test-Path $_ } | Select-Object -First 1
}
if (-not $WxcExec -or -not (Test-Path $WxcExec)) {
Write-Host "ERROR: wxc-exec.exe not found. Build with: cargo build --features wslc --release --target $Target" -ForegroundColor Red
exit 1
}

# Fixed paths must match tests\configs\wslc_denied_masking.json.
$Base = "C:\wslcmask"
$VisibleDir = Join-Path $Base "visible"
$SecretFile = Join-Path $Base "secret_file.txt"
$SecretDir = Join-Path $Base "secret_dir"

function Remove-Fixture {
Remove-Item -Recurse -Force $Base -ErrorAction SilentlyContinue
}

Remove-Fixture
try {
# Positive control (mounted read-write), plus a denied sibling file and a
# denied sibling directory, each holding secret content readable on the host.
New-Item -ItemType Directory -Path $VisibleDir -Force | Out-Null
New-Item -ItemType Directory -Path $SecretDir -Force | Out-Null
Set-Content (Join-Path $VisibleDir "control.txt") "VISIBLE_SECRET"
Set-Content $SecretFile "FILE_SECRET"
Set-Content (Join-Path $SecretDir "inner.txt") "DIR_SECRET"

Write-Host "Running WSLC denied-path masking test (denied sibling file + dir left unmounted)..."
$wxcArgs = @()
if ($Debug) { $wxcArgs += "--debug" }
$wxcArgs += $ConfigPath

$prev = $ErrorActionPreference
$ErrorActionPreference = "Continue"
$output = & $WxcExec @wxcArgs 2>&1 | Out-String
$ErrorActionPreference = $prev
Write-Host $output

$fail = 0

# Positive control: the mounted sibling must be readable, proving the mount
# is present (so masking below is attributable to the deny, not absence).
if (($output -match "VISIBLE_OK") -and ($output -notmatch "VISIBLE_MISSING")) {
Write-Host "PASS: non-denied sibling readable (mount present)." -ForegroundColor Green
} else {
Write-Host "FAIL: non-denied sibling not readable - mount missing, test inconclusive." -ForegroundColor Red
$fail = 1
}

if (($output -match "FILE_MASKED_OK") -and ($output -notmatch "FILE_LEAK")) {
Write-Host "PASS: denied file not mounted (masked)." -ForegroundColor Green
} else {
Write-Host "FAIL: denied file content leaked." -ForegroundColor Red
$fail = 1
}

if (($output -match "DIR_MASKED_OK") -and ($output -notmatch "DIR_LEAK")) {
Write-Host "PASS: denied directory not mounted (masked)." -ForegroundColor Green
} else {
Write-Host "FAIL: denied directory content leaked." -ForegroundColor Red
$fail = 1
}

if ($fail -ne 0) { $exit = 1 } else { $exit = 0 }
} finally {
Remove-Fixture
}

Write-Host "WSLC denied-path masking test complete."
exit $exit
9 changes: 7 additions & 2 deletions tests/scripts/run_wslc_dotdot_alias_test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ $ErrorActionPreference = "Stop"
$RepoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$ConfigPath = Join-Path $RepoRoot "tests\configs\wslc_denied_dotdot_alias.json"

# Resolve the binary: explicit path, then target-specific and default dirs.
$Target = "x86_64-pc-windows-msvc"
# Find binary -- prefer explicit path, then probe target-specific and default
# dirs. Use the host arch to determine which target to use.
$Target = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') {
Comment thread
theelliotm marked this conversation as resolved.
'aarch64-pc-windows-msvc'
} else {
'x86_64-pc-windows-msvc'
}
$Profile = if ($Debug) { "debug" } else { "release" }
if ($WxcExecPath) {
$WxcExec = $WxcExecPath
Expand Down
Loading
Loading