Laufzeiten: die MCP-Bruecke ist auch ohne Starter in der Sandbox (#712)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-09-25 22:59:56 +02:00
co-authored by Claude Opus 5.5
parent a76983aa28
commit 7a8852fe6b
6 changed files with 26 additions and 4 deletions
@@ -101,7 +101,7 @@ public sealed class ClaudeCodeRuntime(Func<ClaudeCodeSettings> settings) : IFore
["CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"] = "1"
};
var readOnly = new List<string>(config.ReadOnlyPaths);
var readOnly = new List<string>(config.ReadOnlyPaths.Concat(context.HelperPaths()));
var directory = Path.GetDirectoryName(executable)!;
if (!directory.StartsWith("/usr/", StringComparison.Ordinal))
readOnly.Add(directory);
@@ -25,7 +25,7 @@ public sealed class CommandRuntime : IForeignRuntime
File.WriteAllText(Path.Combine(context.PrivateDirectory, ForeignRunContext.BriefingFileName), context.Briefing);
var command = runtime.Command.Trim();
var readOnly = new List<string>();
var readOnly = new List<string>(context.HelperPaths());
if (Path.IsPathRooted(command))
{
var directory = Path.GetDirectoryName(command)!;
@@ -56,6 +56,12 @@ public sealed record ForeignRunContext
return mounts;
}
/// <summary>
/// What must be visible read-only for the MCP bridge: the application. Mounted whenever
/// there is MCP — not only when the launcher runs, which needs network or secrets.
/// </summary>
public IReadOnlyList<string> HelperPaths() => HasMcp ? Helper!.ReadOnlyPaths : [];
/// <summary>What a program in the sandbox needs to reach the MCP server itself.</summary>
public IReadOnlyDictionary<string, string> McpEnvironment()
{
@@ -72,6 +78,8 @@ public sealed record ForeignRunContext
environment["CLAWD_MCP_SOCKET"] = McpSocketInSandbox;
environment[Mcp.McpStdioBridge.TokenFileVariable] = Private + "/" + TokenFileName;
environment["CLAWD_HELPER"] = Helper!.Executable;
foreach (var (key, value) in Helper.Environment)
environment[key] = value;
}
return environment;
}
+1 -1
View File
@@ -223,7 +223,7 @@ public sealed class BwrapSandbox : ISandboxRunner
// #712: what the launcher needs — the helper itself, the proxy's socket, the secrets.
if (request.NeedsLauncher && helper is not null)
{
foreach (var path in helper.ReadOnlyPaths)
foreach (var path in helper.ReadOnlyPaths.Except(request.ReadOnlyPaths.Select(Path.GetFullPath)))
args.AddRange(["--ro-bind", path, path]);
if (launch.EgressSocket is { } socket)
args.AddRange(["--bind", socket, SandboxPaths.EgressSocket]);