-
-
Notifications
You must be signed in to change notification settings - Fork 165
Expand file tree
/
Copy pathentry.mjs
More file actions
121 lines (104 loc) · 3.68 KB
/
entry.mjs
File metadata and controls
121 lines (104 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// entry.mjs -- ESM sandbox integration test for issue #362
//
// Verifies that ESM imports resolve correctly within the Bazel sandbox
// and that fs.realpathSync.native() does not escape the sandbox.
//
// Issue #362: Node.js ESM resolver captures realpathSync.native() via
// destructuring BEFORE --require patches run, so resolved paths escape
// the Bazel sandbox. The native FS sandbox (LD_PRELOAD) fixes this by
// intercepting libc realpath() at the C level.
import { depUrl } from "./dep.mjs";
import { realpathSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname } from "node:path";
let passed = true;
function check(description, condition) {
if (condition) {
console.log(` PASS: ${description}`);
} else {
console.log(` FAIL: ${description}`);
passed = false;
}
}
console.log("ESM sandbox test (issue #362):");
// The FS_PATCH_ROOTS env var contains the sandbox roots (colon-separated).
// Paths returned by realpathSync must stay within these roots.
// This env var MUST be set by the js_binary launcher — if it's missing,
// the native sandbox is not active and the test should fail.
const rootsEnv = process.env.JS_BINARY__FS_PATCH_ROOTS;
if (!rootsEnv) {
console.log(" FAIL: JS_BINARY__FS_PATCH_ROOTS is not set — native sandbox not active");
process.exit(1);
}
const roots = rootsEnv.split(":").filter(Boolean);
if (roots.length === 0) {
console.log(" FAIL: JS_BINARY__FS_PATCH_ROOTS is empty — no sandbox roots configured");
process.exit(1);
}
console.log(` configured roots: ${roots.length}`);
function isWithinRoots(p) {
return roots.some(root => p.startsWith(root));
}
// Get file paths from import.meta.url
const entryPath = fileURLToPath(import.meta.url);
const depPath = fileURLToPath(depUrl);
const entryDir = dirname(entryPath);
console.log(` entry path: ${entryPath}`);
console.log(` dep path: ${depPath}`);
// Verify import.meta.url is a file:// URL
check(
"entry import.meta.url is file:// URL",
import.meta.url.startsWith("file://")
);
check(
"dep import.meta.url is file:// URL",
depUrl.startsWith("file://")
);
// Verify dep.mjs is in the same directory as entry.mjs
check(
"dep.mjs is in same directory as entry.mjs",
depPath.startsWith(entryDir)
);
// ---- CORE TEST for issue #362 ----
// realpathSync.native() is what the ESM resolver uses internally.
// Without the native FS sandbox, this would resolve through symlinks
// to the real execroot OUTSIDE the sandbox. With our fix, it should
// return a path that stays within the configured roots.
try {
const realNative = realpathSync.native(entryPath);
console.log(` realpathSync.native: ${realNative}`);
check(
"realpathSync.native() returns a valid path",
typeof realNative === "string" && realNative.length > 0
);
check(
"realpathSync.native() stays within sandbox roots",
isWithinRoots(realNative)
);
} catch (err) {
console.log(` FAIL: realpathSync.native() threw: ${err.message}`);
passed = false;
}
// Also verify the JS-level realpathSync (patched by --require)
try {
const realJS = realpathSync(entryPath);
console.log(` realpathSync: ${realJS}`);
check(
"realpathSync() returns a valid path",
typeof realJS === "string" && realJS.length > 0
);
check(
"realpathSync() stays within sandbox roots",
isWithinRoots(realJS)
);
} catch (err) {
console.log(` FAIL: realpathSync() threw: ${err.message}`);
passed = false;
}
if (passed) {
console.log("PASS: All ESM sandbox checks passed.");
process.exit(0);
} else {
console.log("FAIL: Some ESM sandbox checks failed.");
process.exit(1);
}