diff --git a/package-lock.json b/package-lock.json index c155a84..c49a227 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@anthropic-ai/sandbox-runtime", - "version": "0.0.45", + "version": "0.0.46", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@anthropic-ai/sandbox-runtime", - "version": "0.0.45", + "version": "0.0.46", "license": "Apache-2.0", "dependencies": { "@pondwader/socks5-server": "^1.0.10", @@ -502,7 +502,6 @@ "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", @@ -1003,7 +1002,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1455,7 +1453,8 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.2.tgz", "integrity": "sha512-D80T+tiqkd/8B0xNlbstWDG4x6aqVfO52+OlSUNIdkTvmNw0uQpJLeos2J/2XvpyidAFuTPmpad+tUxLndwj6g==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/data-view-buffer": { "version": "1.0.2", @@ -1802,7 +1801,6 @@ "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -1892,7 +1890,6 @@ "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -2013,7 +2010,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3734,7 +3730,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3781,7 +3776,6 @@ "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -4634,7 +4628,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 0e98338..786b9ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@anthropic-ai/sandbox-runtime", - "version": "0.0.45", + "version": "0.0.46", "description": "Anthropic Sandbox Runtime (ASRT) - A general-purpose tool for wrapping security boundaries around arbitrary processes", "type": "module", "main": "./dist/index.js", diff --git a/src/sandbox/linux-sandbox-utils.ts b/src/sandbox/linux-sandbox-utils.ts index c37617f..03b3e38 100644 --- a/src/sandbox/linux-sandbox-utils.ts +++ b/src/sandbox/linux-sandbox-utils.ts @@ -1212,6 +1212,16 @@ export async function wrapCommandWithSandboxLinux( if (!enableWeakerNestedSandbox) { // Mount fresh /proc if PID namespace is isolated (secure mode) bwrapArgs.push('--proc', '/proc') + } else { + // --unshare-user: bwrap only auto-adds this when EUID != 0. In an + // unprivileged container (Docker's default: EUID=0 without + // CAP_SYS_ADMIN), bwrap assumes it has caps, tries direct clone, + // and EPERMs. Force the userns path so bwrap starts at all. + // + // --bind /proc /proc: apply-seccomp's nested-userns path writes + // /proc/self/setgroups and uid_map. Without --proc above, the + // --ro-bind / / leaves /proc read-only and those writes EROFS. + bwrapArgs.push('--unshare-user', '--bind', '/proc', '/proc') } // apply-seccomp obtains CAP_SYS_ADMIN for its nested PID+mount unshare diff --git a/vendor/seccomp-src/apply-seccomp.c b/vendor/seccomp-src/apply-seccomp.c index 3a34cb3..81c9511 100644 --- a/vendor/seccomp-src/apply-seccomp.c +++ b/vendor/seccomp-src/apply-seccomp.c @@ -246,7 +246,13 @@ int main(int argc, char *argv[]) { if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) < 0) { die("apply-seccomp: mount(MS_PRIVATE)"); } - if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NODEV | MS_NOEXEC, NULL) < 0) { + /* EPERM here means a masked /proc is underneath (unprivileged Docker) + * and the kernel domination check refused the overmount. The nested + * userns above is the isolation boundary; this remount only hides + * outer PIDs from `ls /proc`. enableWeakerNestedSandbox targets + * exactly this environment. */ + if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NODEV | MS_NOEXEC, NULL) < 0 + && errno != EPERM) { die("apply-seccomp: mount(/proc)"); } diff --git a/vendor/seccomp/arm64/apply-seccomp b/vendor/seccomp/arm64/apply-seccomp index 001b312..9801e12 100755 Binary files a/vendor/seccomp/arm64/apply-seccomp and b/vendor/seccomp/arm64/apply-seccomp differ diff --git a/vendor/seccomp/x64/apply-seccomp b/vendor/seccomp/x64/apply-seccomp index bc8e96f..dec6b88 100755 Binary files a/vendor/seccomp/x64/apply-seccomp and b/vendor/seccomp/x64/apply-seccomp differ