Skip to content

[Linux-Sandboxing]: Ubuntu 24.04 silently fails due to App Armor profile on bwrap#319061

Draft
dileepyavan wants to merge 3 commits into
mainfrom
DileepY/314041
Draft

[Linux-Sandboxing]: Ubuntu 24.04 silently fails due to App Armor profile on bwrap#319061
dileepyavan wants to merge 3 commits into
mainfrom
DileepY/314041

Conversation

@dileepyavan
Copy link
Copy Markdown
Member

@dileepyavan dileepyavan commented May 29, 2026

fixes #314041

Summary

  • Probe installed bwrap so sandbox prerequisites distinguish a missing dependency from bubblewrap that is installed but cannot create the required user namespace.
  • Detect supported Ubuntu/AppArmor failure scenarios and offer repair actions from runInTerminal before attempting sandboxed command execution.
  • Re-check sandbox prerequisites after installation or remediation, and avoid including redundant exit code 0 text in successful terminal completion notifications.
  • Add coverage for dependency probing, remediation selection/execution, and successful completion notification formatting.

Validation

  • Core - Typecheck watch task: completed with 0 errors.
  • Core - Transpile watch task: completed with 0 errors.
  • npm run valid-layers-check: passed.
  • Attempted focused tests for the affected sandbox and runInTerminal test modules via ./scripts/test.sh --run ...; the test harness could not start in this sandboxed environment because it attempted to download Electron from GitHub and failed with getaddrinfo EAI_AGAIN github.com.

Copilot AI review requested due to automatic review settings May 29, 2026 21:22
Copy link
Copy Markdown
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

This PR addresses a Linux terminal sandboxing failure on Ubuntu 24.04 where bwrap (bubblewrap) can be installed but unusable due to AppArmor/user-namespace restrictions, leading to silent/preconfusing failures when running sandboxed terminal commands.

Changes:

  • Add a bubblewrap capability probe and expose bubblewrapUsable, detailed errors, and Ubuntu 24.04-specific remediation support via ISandboxDependencyStatus.
  • Extend sandbox prerequisite checks to distinguish “missing dependencies” vs “bubblewrap installed but unusable”, returning remediation choices and detail text.
  • Update RunInTerminalTool to surface repair options, re-check prerequisites after installs/remediation, and avoid reporting exit code 0 in chat notifications.
Show a summary per file
File Description
src/vs/workbench/contrib/terminalContrib/chatAgentTools/test/electron-browser/runInTerminalTool.test.ts Adds tests for bubblewrap-unusable flows, remediation choices, and exit-code messaging changes.
src/vs/workbench/contrib/terminalContrib/chatAgentTools/test/browser/terminalSandboxService.test.ts Adds tests for remediation reporting/execution and workspace storage write allow-listing.
src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.ts Adds remediation command execution; currently includes an erroneous appended helper block (see comments).
src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalChatAgentToolsConfiguration.ts Updates settings descriptions to include workspace storage write allowance.
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts Prompts for bubblewrap repair options, re-checks prereqs after installation/remediation, and tweaks exit-code messaging.
src/vs/workbench/contrib/chat/common/chatService/chatService.ts Extends terminal tool invocation data with remediation/failure fields.
src/vs/platform/sandbox/test/node/sandboxHelper.test.ts New unit tests for bubblewrap probing and Ubuntu 24.04 remediation support detection.
src/vs/platform/sandbox/test/common/terminalSandboxEngine.test.ts Adds coverage for new prereq result (bubblewrap unusable + remediations).
src/vs/platform/sandbox/node/sandboxHelper.ts Implements bubblewrap capability probe and Ubuntu 24.04 release detection.
src/vs/platform/sandbox/common/terminalSandboxService.ts Adds new prereq enums and a remediation API to the sandbox service contract.
src/vs/platform/sandbox/common/terminalSandboxEngine.ts Returns bubblewrap-unusable prereq failures with remediations/details; updates dependency checks to include usability.
src/vs/platform/sandbox/common/sandboxHelperService.ts Extends dependency status with usability/error/remediation-support signals.
src/vs/platform/sandbox/browser/sandboxHelperService.ts Updates the browser-side null implementation to satisfy the extended status contract.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 2

Comment on lines 807 to +827
const toolSpecificData: IChatTerminalToolInvocationData = {
kind: 'terminal',
terminalToolSessionId,
terminalCommandId,
commandLine: {
original: args.command,
toolEdited: rewrittenCommand === args.command ? undefined : rewrittenCommand,
forDisplay: forDisplayCommand ?? normalizeTerminalCommandForDisplay(rewrittenCommand ?? args.command),
isSandboxWrapped,
},
cwd,
language,
isBackground: executionOptions.persistentSession,
requestUnsandboxedExecution: requiresUnsandboxConfirmation,
requestUnsandboxedExecutionReason,
missingSandboxDependencies: missingDependencies,
sandboxRemediations,
sandboxPrerequisiteFailure,
};

let sandboxConfirmationMessageForMissingDeps: IToolConfirmationMessages | undefined = undefined;
let sandboxPrerequisiteConfirmation: IToolConfirmationMessages | undefined = undefined;
Comment on lines +397 to +452
private _quoteShellArgument(value: string): string {
return `'${value.replace(/'/g, `'\\''`)}'`;
}

private _getSandboxCommandWithPreservedCwd(command: string, cwd: URI | undefined): string {
if (this._os !== OperatingSystem.Linux || !cwd?.path || cwd.path === this._tempDir?.path) {
return command;
}
return `cd ${this._quoteShellArgument(cwd.path)} && ${command}`;
}

private _wrapSandboxRuntimeCommandForLaunch(sandboxRuntimeCommand: string, cwd: URI | undefined): string {
const tempDirPath = this._tempDir?.path;
return this._os === OperatingSystem.Linux && cwd?.path && tempDirPath && cwd.path !== tempDirPath
? `cd ${this._quoteShellArgument(tempDirPath)}; ${sandboxRuntimeCommand}`
: sandboxRuntimeCommand;
}

private _wrapUnsandboxedCommand(command: string, shell?: string): string {
if (!this._tempDir?.path) {
return command;
}
if (!shell) {
return `(TMPDIR="${this._tempDir.path}"; export TMPDIR; ${command})`;
}
return `env TMPDIR="${this._tempDir.path}" ${this._quoteShellArgument(shell)} -c ${this._quoteShellArgument(command)}`;
}

private _getBlockedDomains(command: string): { blockedDomains: string[]; deniedDomains: string[] } {
if (this._isSandboxAllowNetworkConfigured()) {
return { blockedDomains: [], deniedDomains: [] };
}

const domains = this._extractDomains(command);
if (domains.length === 0) {
return { blockedDomains: [], deniedDomains: [] };
}

const { allowedDomains, deniedDomains } = this.getResolvedNetworkDomains();
const blockedDomains = new Set<string>();
const explicitlyDeniedDomains = new Set<string>();
for (const domain of domains) {
if (deniedDomains.some(pattern => matchesDomainPattern(domain, pattern))) {
blockedDomains.add(domain);
explicitlyDeniedDomains.add(domain);
continue;
}
if (!allowedDomains.some(pattern => matchesDomainPattern(domain, pattern))) {
blockedDomains.add(domain);
}
}
return {
blockedDomains: [...blockedDomains],
deniedDomains: [...explicitlyDeniedDomains],
};
}
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.

Linux: Cannot curl inside sandbox

2 participants