Skip to content

test(docker): verify capsh execution chain after PR #715#1240

Merged
Mossaka merged 1 commit intomainfrom
fix/034-capsh-execution-chain
Mar 11, 2026
Merged

test(docker): verify capsh execution chain after PR #715#1240
Mossaka merged 1 commit intomainfrom
fix/034-capsh-execution-chain

Conversation

@Mossaka
Copy link
Collaborator

@Mossaka Mossaka commented Mar 11, 2026

Summary

  • Add integration tests verifying the capsh execution chain works correctly after PR fix: eliminate nested bash layer in chroot command execution for Java/.NET #715 eliminated the nested bash layer for Java/.NET compatibility
  • Tests check CapBnd bitmask for dropped capabilities (CAP_NET_ADMIN, CAP_SYS_CHROOT, CAP_SYS_ADMIN)
  • Verifies commands run under bash, /proc/self/exe resolves correctly, and special characters work with direct-write approach

Test plan

  • CI passes all checks (build, lint, unit tests)
  • Integration tests pass on CI runners (chroot tests)
  • CapBnd bitmask assertions correctly detect dropped capabilities

Fixes #842

🤖 Generated with Claude Code

Add integration tests verifying the capsh execution chain works correctly
after PR #715 eliminated the nested bash layer for Java/.NET compatibility.

Tests verify:
- CAP_NET_ADMIN, CAP_SYS_CHROOT, CAP_SYS_ADMIN dropped from CapBnd bitmask
- iptables, chroot, mount commands fail (capabilities enforced)
- Commands run under bash shell (BASH_VERSION set)
- /proc/self/exe resolves correctly for python3 (not /bin/bash)
- Special characters and pipe chains work with direct-write approach

Fixes #842

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 11, 2026 17:48
@github-actions
Copy link
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 82.50% 82.64% 📈 +0.14%
Statements 82.50% 82.63% 📈 +0.13%
Functions 82.69% 82.69% ➡️ +0.00%
Branches 74.78% 74.87% 📈 +0.09%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 84.0% → 84.5% (+0.54%) 83.3% → 83.8% (+0.52%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@Mossaka Mossaka changed the title test(chroot): verify capsh execution chain after PR #715 test(docker): verify capsh execution chain after PR #715 Mar 11, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an integration test to validate the post–PR #715 chroot execution chain (capsh capability dropping + command execution semantics), guarding against regressions in how commands are written/executed inside the chroot script.

Changes:

  • Introduces a new batched integration test suite that inspects CapBnd and attempts privileged operations (iptables/chroot/mount) to confirm capabilities are dropped.
  • Adds checks around bash execution, /proc/self/exe resolution, and special-character/pipeline handling under the direct-write approach.
Comments suppressed due to low confidence (1)

tests/integration/chroot-capsh-chain.test.ts:55

  • The ; echo "exit=$?" suffix makes the batch wrapper’s captured exitCode always 0 (because the subshell’s last command is echo). This also allows false positives (e.g., iptables missing yields a non-zero exit that still looks like a capability drop). Prefer running the command directly and asserting on BatchCommandResult.exitCode (and optionally matching stderr/stdout for Operation not permitted/permission denied to ensure the failure is actually capability-related).
        { name: 'iptables_blocked', command: 'iptables -L 2>&1; echo "exit=$?"' },
        // Verify CAP_SYS_CHROOT (bit 18) is dropped in chroot mode
        { name: 'chroot_blocked', command: 'chroot / /bin/true 2>&1; echo "exit=$?"' },
        // Verify CAP_SYS_ADMIN (bit 21) is dropped - mount should fail
        { name: 'mount_blocked', command: 'mount -t tmpfs tmpfs /tmp/test-mount 2>&1; echo "exit=$?"' },

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +54 to +55
// Verify CAP_SYS_ADMIN (bit 21) is dropped - mount should fail
{ name: 'mount_blocked', command: 'mount -t tmpfs tmpfs /tmp/test-mount 2>&1; echo "exit=$?"' },
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

mount -t tmpfs tmpfs /tmp/test-mount can fail for reasons unrelated to CAP_SYS_ADMIN (e.g., missing mountpoint), and this test currently only checks exit=.... Create a mountpoint first (e.g., under mktemp -d), attempt the mount, and assert the failure mode is permission-related; also ensure any created directory is cleaned up.

Suggested change
// Verify CAP_SYS_ADMIN (bit 21) is dropped - mount should fail
{ name: 'mount_blocked', command: 'mount -t tmpfs tmpfs /tmp/test-mount 2>&1; echo "exit=$?"' },
// Verify CAP_SYS_ADMIN (bit 21) is dropped - mount should fail due to permissions, not missing mountpoint
{ name: 'mount_blocked', command: 'mount_dir="$(mktemp -d)"; mount -t tmpfs tmpfs "$mount_dir" 2>&1; status="$?"; rmdir "$mount_dir"; echo "exit=$status"' },

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +66
// Verify that the process tree doesn't have an extra bash layer
// ps should show bash -> capsh -> bash -> command, NOT bash -> capsh -> bash -> bash -> command
{ name: 'process_tree', command: 'ps -o comm= --ppid $PPID 2>/dev/null || ps -o comm= $PPID 2>/dev/null || echo "ps_unavailable"' },
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

process_tree is executed in the batch but never asserted on, so it adds runtime/noise without increasing coverage. Either add a test that validates the expected chain (no extra nested bash), or remove this batch command to keep the invocation minimal.

Suggested change
// Verify that the process tree doesn't have an extra bash layer
// ps should show bash -> capsh -> bash -> command, NOT bash -> capsh -> bash -> bash -> command
{ name: 'process_tree', command: 'ps -o comm= --ppid $PPID 2>/dev/null || ps -o comm= $PPID 2>/dev/null || echo "ps_unavailable"' },

Copilot uses AI. Check for mistakes.
Comment on lines +136 to +143
if (r.exitCode === 0) {
// python3's /proc/self/exe should point to python, not bash
expect(r.stdout).toMatch(/python/);
expect(r.stdout).not.toMatch(/\/bin\/bash$/);
}
// Skip if python3 not available
});

Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

This test silently passes if python3 is unavailable (if (r.exitCode === 0) { ... }). Other integration tests in this suite appear to assume python3 exists (and would fail if it didn’t), so this weakens the signal when running this test file in isolation. Consider asserting r.exitCode === 0 (or explicitly test.skip with a clear condition) so missing python fails loudly.

This issue also appears on line 51 of the same file.

Suggested change
if (r.exitCode === 0) {
// python3's /proc/self/exe should point to python, not bash
expect(r.stdout).toMatch(/python/);
expect(r.stdout).not.toMatch(/\/bin\/bash$/);
}
// Skip if python3 not available
});
expect(r.exitCode).toBe(0);
// python3's /proc/self/exe should point to python, not bash
expect(r.stdout).toMatch(/python/);
expect(r.stdout).not.toMatch(/\/bin\/bash$/);
});

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

Smoke Test Results

GitHub MCP: #1229 feat(cli): add short flags for frequently used options, #1228 docs: clarify --image-tag behavior with agent-image presets
Playwright: GitHub page title verified ("GitHub · Change is constant...")
File Write: /tmp/gh-aw/agent/smoke-test-claude-22966572545.txt created
Bash Verify: File contents confirmed

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1240

@github-actions
Copy link
Contributor

Smoke test results for @Mossaka:

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1240

@github-actions
Copy link
Contributor

PRs: feat(cli): add short flags for frequently used options; docs: clarify --image-tag behavior with agent-image presets
GitHub MCP merged PRs: ✅
safeinputs-gh pr list: ✅
Playwright title check: ✅
Tavily search: ❌ (tool unavailable)
File write+cat: ✅
Discussion comment: ✅
Build (npm ci && npm run build): ✅
Overall: FAIL

🔮 The oracle has spoken through Smoke Codex for issue #1240

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.

Verify: capsh execution chain still wraps commands in bash after PR #715 fix

2 participants