@ai-ecoverse/slicc-kernel 1.67.0 → 1.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.js +49 -2
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +269 -24
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +87 -21
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +225 -17
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +87 -21
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -2019,6 +2019,7 @@ function kernelFdKind(file) {
|
|
|
2019
2019
|
if (file.held) return "held";
|
|
2020
2020
|
if (file.heldMeta && "device" in file.heldMeta) return "device";
|
|
2021
2021
|
if (file.tty) return "tty";
|
|
2022
|
+
if (file.sealed) return "sealed";
|
|
2022
2023
|
return file.seek ? "file" : "stream";
|
|
2023
2024
|
}
|
|
2024
2025
|
var FdTable = class _FdTable {
|
|
@@ -10543,8 +10544,8 @@ function ptySyscall(req, ctx) {
|
|
|
10543
10544
|
var RUN_CAPTURE_CAP = 64 * 1024 * 1024;
|
|
10544
10545
|
var RUN_MAX_BUFFER = 1024 * 1024;
|
|
10545
10546
|
function capLimit(maxBuffer) {
|
|
10546
|
-
const asked = maxBuffer ===
|
|
10547
|
-
return Math.
|
|
10547
|
+
const asked = typeof maxBuffer === "number" && maxBuffer >= 0 ? maxBuffer : RUN_MAX_BUFFER;
|
|
10548
|
+
return Math.min(asked, RUN_CAPTURE_CAP);
|
|
10548
10549
|
}
|
|
10549
10550
|
function slot(how, n, extra) {
|
|
10550
10551
|
if (how === "inherit") return { fd: n };
|
|
@@ -10570,6 +10571,7 @@ async function reaped(deps, pid) {
|
|
|
10570
10571
|
}
|
|
10571
10572
|
}
|
|
10572
10573
|
async function runChild(req, deps) {
|
|
10574
|
+
if (!isSignal(req.killSignal)) throw new KernelError("EINVAL");
|
|
10573
10575
|
const max = capLimit(req.maxBuffer);
|
|
10574
10576
|
let failure2;
|
|
10575
10577
|
let pid = 0;
|
|
@@ -11406,6 +11408,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
11406
11408
|
"fd-open-tty",
|
|
11407
11409
|
"fd-tty-names",
|
|
11408
11410
|
"fd-tty-owner",
|
|
11411
|
+
"fd-open-sealed",
|
|
11409
11412
|
"tty-get",
|
|
11410
11413
|
"tty-set",
|
|
11411
11414
|
"tty-winsz",
|
|
@@ -11461,6 +11464,7 @@ var WasmProcess = class {
|
|
|
11461
11464
|
ignored = 0;
|
|
11462
11465
|
inherited = 0;
|
|
11463
11466
|
interrupt = new AbortController();
|
|
11467
|
+
gone = new AbortController();
|
|
11464
11468
|
dying = false;
|
|
11465
11469
|
umask = DEFAULT_UMASK;
|
|
11466
11470
|
cred;
|
|
@@ -11683,6 +11687,7 @@ var WasmProcess = class {
|
|
|
11683
11687
|
}
|
|
11684
11688
|
async write(fd, body, nonblock = false, cancelled) {
|
|
11685
11689
|
const file = this.fds.get(fd).file;
|
|
11690
|
+
if (file.sealed) return file.sealed.send(body, await this.sealedCaller(), this.gone.signal);
|
|
11686
11691
|
if (!file.write) throw new KernelError("EBADF");
|
|
11687
11692
|
if (!pollFile(file).writable) {
|
|
11688
11693
|
if (nonblock) throw new KernelError("EAGAIN");
|
|
@@ -11764,6 +11769,24 @@ var WasmProcess = class {
|
|
|
11764
11769
|
if (name2 !== void 0) ttyOpenable(this.guarded(), tty);
|
|
11765
11770
|
return this.fds.install(tty.file(), 3);
|
|
11766
11771
|
}
|
|
11772
|
+
openSealed() {
|
|
11773
|
+
const broker = this.options.sealed;
|
|
11774
|
+
if (!broker) throw new KernelError("ENOENT");
|
|
11775
|
+
return this.fds.install(broker.open(), 3);
|
|
11776
|
+
}
|
|
11777
|
+
async sealedCaller() {
|
|
11778
|
+
const shown = await this.options.identity?.();
|
|
11779
|
+
const broker = this.options.sealed;
|
|
11780
|
+
const tag = broker.tagOf(this.pid);
|
|
11781
|
+
return {
|
|
11782
|
+
pid: shown?.pid ?? this.pid,
|
|
11783
|
+
ppid: shown?.ppid ?? 0,
|
|
11784
|
+
uid: this.cred.euid,
|
|
11785
|
+
gid: this.cred.egid,
|
|
11786
|
+
...tag !== void 0 ? { tag } : {},
|
|
11787
|
+
users: broker.users
|
|
11788
|
+
};
|
|
11789
|
+
}
|
|
11767
11790
|
guarded() {
|
|
11768
11791
|
const { guard: guard2 } = this.options;
|
|
11769
11792
|
return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
@@ -11884,6 +11907,8 @@ var WasmProcess = class {
|
|
|
11884
11907
|
return { ok: true, kind: "json", json: this.openTty(req.name) };
|
|
11885
11908
|
case "fd-tty-names":
|
|
11886
11909
|
return { ok: true, kind: "json", json: this.options.jobs?.terminalNames() ?? [] };
|
|
11910
|
+
case "fd-open-sealed":
|
|
11911
|
+
return { ok: true, kind: "json", json: this.openSealed() };
|
|
11887
11912
|
case "fd-tty-owner":
|
|
11888
11913
|
return { ok: true, kind: "json", json: this.terminalByName(req.name).owner ?? null };
|
|
11889
11914
|
case "fd-select": {
|
|
@@ -12319,6 +12344,7 @@ var WasmProcess = class {
|
|
|
12319
12344
|
async exit() {
|
|
12320
12345
|
if (this.exited) return;
|
|
12321
12346
|
this.exited = true;
|
|
12347
|
+
this.gone.abort();
|
|
12322
12348
|
this.die();
|
|
12323
12349
|
this.clearAlarm();
|
|
12324
12350
|
this.interrupt.abort();
|
|
@@ -12506,6 +12532,7 @@ function processOptions(opts, header3, hooks, created3) {
|
|
|
12506
12532
|
return {
|
|
12507
12533
|
...inherited(opts),
|
|
12508
12534
|
...opts.owners ? { owners: true } : {},
|
|
12535
|
+
...opts.sealed ? { sealed: opts.sealed } : {},
|
|
12509
12536
|
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
12510
12537
|
...opts.identity ? { identity: opts.identity } : {},
|
|
12511
12538
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
@@ -12988,6 +13015,178 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
12988
13015
|
};
|
|
12989
13016
|
}
|
|
12990
13017
|
|
|
13018
|
+
// src/kernel/sealed.ts
|
|
13019
|
+
var SEALED_MAX_BYTES = 64 * 1024;
|
|
13020
|
+
var SEALED_TIMEOUT_MS = 1e4;
|
|
13021
|
+
var SEALED_OPS = /* @__PURE__ */ new Set([
|
|
13022
|
+
"seal",
|
|
13023
|
+
"placeholder",
|
|
13024
|
+
"list",
|
|
13025
|
+
"test",
|
|
13026
|
+
"request",
|
|
13027
|
+
"status",
|
|
13028
|
+
"cancel",
|
|
13029
|
+
"materialize"
|
|
13030
|
+
]);
|
|
13031
|
+
var encoder3 = new TextEncoder();
|
|
13032
|
+
var decoder2 = new TextDecoder("utf-8", { fatal: true });
|
|
13033
|
+
function parseSealed(bytes) {
|
|
13034
|
+
try {
|
|
13035
|
+
if (bytes.length > SEALED_MAX_BYTES) throw new KernelError("EMSGSIZE");
|
|
13036
|
+
let parsed2;
|
|
13037
|
+
try {
|
|
13038
|
+
parsed2 = JSON.parse(decoder2.decode(bytes));
|
|
13039
|
+
} catch {
|
|
13040
|
+
throw new KernelError("EINVAL");
|
|
13041
|
+
}
|
|
13042
|
+
if (typeof parsed2 !== "object" || parsed2 === null || Array.isArray(parsed2))
|
|
13043
|
+
throw new KernelError("EINVAL");
|
|
13044
|
+
const req = parsed2;
|
|
13045
|
+
if (req.v !== 1 || typeof req.op !== "string" || !SEALED_OPS.has(req.op))
|
|
13046
|
+
throw new KernelError("EINVAL");
|
|
13047
|
+
return req;
|
|
13048
|
+
} finally {
|
|
13049
|
+
bytes.fill(0);
|
|
13050
|
+
}
|
|
13051
|
+
}
|
|
13052
|
+
function errorReply(code, message3) {
|
|
13053
|
+
return { v: 1, error: { code, message: message3 } };
|
|
13054
|
+
}
|
|
13055
|
+
function isRecord(value) {
|
|
13056
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13057
|
+
}
|
|
13058
|
+
function serialized(reply) {
|
|
13059
|
+
let plain;
|
|
13060
|
+
try {
|
|
13061
|
+
const text = JSON.stringify(reply);
|
|
13062
|
+
plain = text === void 0 ? void 0 : JSON.parse(text);
|
|
13063
|
+
} catch (err) {
|
|
13064
|
+
return JSON.stringify(errorReply("EIO", lineOf(err)));
|
|
13065
|
+
}
|
|
13066
|
+
if (!isRecord(plain)) return JSON.stringify(errorReply("EIO", "the vault gave no reply"));
|
|
13067
|
+
const { v: _, ...rest2 } = plain;
|
|
13068
|
+
return JSON.stringify({ v: 1, ...rest2 });
|
|
13069
|
+
}
|
|
13070
|
+
function lineOf(err) {
|
|
13071
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
13072
|
+
return (text.split("\n")[0] ?? "").slice(0, 200);
|
|
13073
|
+
}
|
|
13074
|
+
var SealedChannel = class {
|
|
13075
|
+
reply;
|
|
13076
|
+
offset = 0;
|
|
13077
|
+
inflight;
|
|
13078
|
+
broker;
|
|
13079
|
+
constructor(broker) {
|
|
13080
|
+
this.broker = broker;
|
|
13081
|
+
}
|
|
13082
|
+
send(bytes, caller, gone) {
|
|
13083
|
+
const length2 = bytes.length;
|
|
13084
|
+
const fields = parseSealed(bytes);
|
|
13085
|
+
this.reply = void 0;
|
|
13086
|
+
this.offset = 0;
|
|
13087
|
+
this.inflight?.control.abort("replaced");
|
|
13088
|
+
const control = new AbortController();
|
|
13089
|
+
const withdraw = () => control.abort("withdrawn");
|
|
13090
|
+
if (gone.aborted) withdraw();
|
|
13091
|
+
else gone.addEventListener("abort", withdraw, { once: true });
|
|
13092
|
+
const timer = setTimeout(() => control.abort("timeout"), this.broker.timeoutMs);
|
|
13093
|
+
const req = { ...fields, v: 1, op: fields.op, caller };
|
|
13094
|
+
const flight = { control, done: Promise.resolve() };
|
|
13095
|
+
flight.done = this.answer(req, control.signal).then((reply) => {
|
|
13096
|
+
clearTimeout(timer);
|
|
13097
|
+
gone.removeEventListener("abort", withdraw);
|
|
13098
|
+
if (this.inflight !== flight) return;
|
|
13099
|
+
this.inflight = void 0;
|
|
13100
|
+
if (reply) this.reply = encoder3.encode(serialized(reply));
|
|
13101
|
+
});
|
|
13102
|
+
this.inflight = flight;
|
|
13103
|
+
return length2;
|
|
13104
|
+
}
|
|
13105
|
+
async answer(req, signal) {
|
|
13106
|
+
const hook = this.broker.hook;
|
|
13107
|
+
if (!hook) return errorReply("ENOTCONN", "no vault is connected");
|
|
13108
|
+
const stopped = new Promise((resolve) => {
|
|
13109
|
+
signal.addEventListener("abort", () => resolve(void 0), { once: true });
|
|
13110
|
+
});
|
|
13111
|
+
if (signal.aborted) return void 0;
|
|
13112
|
+
const asked = Promise.resolve().then(() => hook(req, { signal })).then(
|
|
13113
|
+
(reply2) => isRecord(reply2) ? reply2 : errorReply("EIO", "the vault gave no reply"),
|
|
13114
|
+
(err) => errorReply("EIO", lineOf(err))
|
|
13115
|
+
);
|
|
13116
|
+
const reply = await Promise.race([asked, stopped]);
|
|
13117
|
+
if (!signal.aborted) return reply;
|
|
13118
|
+
return signal.reason === "timeout" ? errorReply("ETIMEDOUT", "the vault did not answer within 10 s") : void 0;
|
|
13119
|
+
}
|
|
13120
|
+
async read(max, signal) {
|
|
13121
|
+
for (; ; ) {
|
|
13122
|
+
if (this.reply) {
|
|
13123
|
+
const out = this.reply.slice(this.offset, this.offset + max);
|
|
13124
|
+
this.offset += out.length;
|
|
13125
|
+
if (this.offset >= this.reply.length) {
|
|
13126
|
+
this.reply = void 0;
|
|
13127
|
+
this.offset = 0;
|
|
13128
|
+
}
|
|
13129
|
+
return out;
|
|
13130
|
+
}
|
|
13131
|
+
const flight = this.inflight;
|
|
13132
|
+
if (!flight) return new Uint8Array(0);
|
|
13133
|
+
await this.until(flight, signal);
|
|
13134
|
+
}
|
|
13135
|
+
}
|
|
13136
|
+
async until(flight, signal) {
|
|
13137
|
+
if (!signal) return flight.done;
|
|
13138
|
+
if (signal.aborted) throw new KernelError("EINTR");
|
|
13139
|
+
let stop = () => {
|
|
13140
|
+
};
|
|
13141
|
+
const interrupted2 = new Promise((_, reject) => {
|
|
13142
|
+
stop = () => reject(new KernelError("EINTR"));
|
|
13143
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
13144
|
+
});
|
|
13145
|
+
try {
|
|
13146
|
+
await Promise.race([flight.done, interrupted2]);
|
|
13147
|
+
} finally {
|
|
13148
|
+
signal.removeEventListener("abort", stop);
|
|
13149
|
+
}
|
|
13150
|
+
}
|
|
13151
|
+
poll() {
|
|
13152
|
+
return { readable: this.reply !== void 0 || !this.inflight, writable: true, hangup: false };
|
|
13153
|
+
}
|
|
13154
|
+
async changed(signal) {
|
|
13155
|
+
const flight = this.inflight;
|
|
13156
|
+
if (flight) await this.until(flight, signal);
|
|
13157
|
+
}
|
|
13158
|
+
close() {
|
|
13159
|
+
this.inflight?.control.abort("withdrawn");
|
|
13160
|
+
this.inflight = void 0;
|
|
13161
|
+
this.reply = void 0;
|
|
13162
|
+
}
|
|
13163
|
+
};
|
|
13164
|
+
var SealedBroker = class {
|
|
13165
|
+
hook;
|
|
13166
|
+
users;
|
|
13167
|
+
timeoutMs;
|
|
13168
|
+
tagOf;
|
|
13169
|
+
constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
|
|
13170
|
+
this.hook = hook;
|
|
13171
|
+
this.users = users;
|
|
13172
|
+
this.timeoutMs = timeoutMs;
|
|
13173
|
+
this.tagOf = tagOf;
|
|
13174
|
+
}
|
|
13175
|
+
open() {
|
|
13176
|
+
const channel = new SealedChannel(this);
|
|
13177
|
+
return new OpenFile({
|
|
13178
|
+
read: (max, signal) => channel.read(max, signal),
|
|
13179
|
+
write: async () => {
|
|
13180
|
+
throw new KernelError("EINVAL");
|
|
13181
|
+
},
|
|
13182
|
+
poll: () => channel.poll(),
|
|
13183
|
+
changed: (signal) => channel.changed(signal),
|
|
13184
|
+
close: () => channel.close(),
|
|
13185
|
+
sealed: channel
|
|
13186
|
+
});
|
|
13187
|
+
}
|
|
13188
|
+
};
|
|
13189
|
+
|
|
12991
13190
|
// src/kernel/settling.ts
|
|
12992
13191
|
var SETUP_OPS = /* @__PURE__ */ new Set([
|
|
12993
13192
|
"proc-list",
|
|
@@ -13635,13 +13834,13 @@ var HostfsClient = class {
|
|
|
13635
13834
|
const response = await this.send("/api/hostfs/watch", { method: "POST", signal });
|
|
13636
13835
|
onOpen();
|
|
13637
13836
|
const reader = response.body.getReader();
|
|
13638
|
-
const
|
|
13837
|
+
const decoder3 = new TextDecoder();
|
|
13639
13838
|
let buffered = "";
|
|
13640
13839
|
try {
|
|
13641
13840
|
for (; ; ) {
|
|
13642
13841
|
const { done: done4, value } = await reader.read();
|
|
13643
13842
|
if (done4) return;
|
|
13644
|
-
buffered +=
|
|
13843
|
+
buffered += decoder3.decode(value, { stream: true });
|
|
13645
13844
|
let end = buffered.indexOf("\n");
|
|
13646
13845
|
while (end >= 0) {
|
|
13647
13846
|
const line = buffered.slice(0, end).trim();
|
|
@@ -15019,7 +15218,7 @@ var LAYOUT = [
|
|
|
15019
15218
|
];
|
|
15020
15219
|
var LOAD_SAMPLE_MS = 5e3;
|
|
15021
15220
|
var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
|
|
15022
|
-
var
|
|
15221
|
+
var encoder4 = new TextEncoder();
|
|
15023
15222
|
var USERS_MODES = ["off", "report", "enforce"];
|
|
15024
15223
|
function usersMode(mode = "off") {
|
|
15025
15224
|
if (USERS_MODES.includes(mode)) return mode;
|
|
@@ -15169,12 +15368,19 @@ var Launcher = class {
|
|
|
15169
15368
|
fstab = Promise.resolve([]);
|
|
15170
15369
|
usersMode;
|
|
15171
15370
|
dac;
|
|
15371
|
+
sealed;
|
|
15172
15372
|
nextPid = 1e3;
|
|
15173
15373
|
boot = Date.now();
|
|
15174
15374
|
terminals = 0;
|
|
15175
15375
|
constructor(options) {
|
|
15176
15376
|
this.usersMode = usersMode(options.users);
|
|
15177
15377
|
this.dac = this.usersMode === "off" ? void 0 : new Dac(this.usersMode, options.onDenial);
|
|
15378
|
+
this.sealed = new SealedBroker(
|
|
15379
|
+
options.sealed,
|
|
15380
|
+
this.usersMode,
|
|
15381
|
+
void 0,
|
|
15382
|
+
(pid) => this.tagOf(pid)
|
|
15383
|
+
);
|
|
15178
15384
|
if (this.owners) options.fs.trackOwners?.();
|
|
15179
15385
|
this.mounts = new MountTable({
|
|
15180
15386
|
open: (type, spec) => this.driver(type, spec),
|
|
@@ -15574,6 +15780,7 @@ var Launcher = class {
|
|
|
15574
15780
|
...req.umask !== void 0 ? { umask: req.umask } : {},
|
|
15575
15781
|
cred: req.cred,
|
|
15576
15782
|
...this.owners ? { owners: true } : {},
|
|
15783
|
+
sealed: this.sealed,
|
|
15577
15784
|
...this.dac ? { dac: this.dac } : {},
|
|
15578
15785
|
program: req.program,
|
|
15579
15786
|
argv0: req.argv0,
|
|
@@ -16212,7 +16419,7 @@ var Launcher = class {
|
|
|
16212
16419
|
},
|
|
16213
16420
|
account
|
|
16214
16421
|
);
|
|
16215
|
-
const report = (message3) => options.onData(
|
|
16422
|
+
const report = (message3) => options.onData(encoder4.encode(`${message3}\r
|
|
16216
16423
|
`));
|
|
16217
16424
|
const handle = await this.launch(planned, {
|
|
16218
16425
|
env,
|
|
@@ -16249,7 +16456,7 @@ var Launcher = class {
|
|
|
16249
16456
|
};
|
|
16250
16457
|
const stdout = collect(out, options.onStdout);
|
|
16251
16458
|
const stderr = collect(err, options.onStderr);
|
|
16252
|
-
const report = (message3) => stderr(
|
|
16459
|
+
const report = (message3) => stderr(encoder4.encode(`${message3}
|
|
16253
16460
|
`));
|
|
16254
16461
|
if (!planned) {
|
|
16255
16462
|
report(`${file}: command not found`);
|
|
@@ -16274,6 +16481,33 @@ var Launcher = class {
|
|
|
16274
16481
|
}
|
|
16275
16482
|
};
|
|
16276
16483
|
|
|
16484
|
+
// src/sealed-relay.ts
|
|
16485
|
+
function sealedAsker(port) {
|
|
16486
|
+
const asks = /* @__PURE__ */ new Map();
|
|
16487
|
+
let next2 = 0;
|
|
16488
|
+
const hook = (req, { signal }) => {
|
|
16489
|
+
const id2 = ++next2;
|
|
16490
|
+
const waiting = Promise.withResolvers();
|
|
16491
|
+
asks.set(id2, waiting);
|
|
16492
|
+
const abort = () => {
|
|
16493
|
+
if (!asks.delete(id2)) return;
|
|
16494
|
+
port.postMessage({ sealedAbort: { id: id2, reason: signal.reason } });
|
|
16495
|
+
waiting.reject(new Error(String(signal.reason)));
|
|
16496
|
+
};
|
|
16497
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
16498
|
+
port.postMessage({ sealedAsk: { id: id2, req } });
|
|
16499
|
+
return waiting.promise.finally(() => signal.removeEventListener("abort", abort));
|
|
16500
|
+
};
|
|
16501
|
+
const answer = ({ id: id2, reply, error }) => {
|
|
16502
|
+
const waiting = asks.get(id2);
|
|
16503
|
+
if (!waiting) return;
|
|
16504
|
+
asks.delete(id2);
|
|
16505
|
+
if (reply) waiting.resolve(reply);
|
|
16506
|
+
else waiting.reject(new Error(error ?? "no reply"));
|
|
16507
|
+
};
|
|
16508
|
+
return { hook, answer };
|
|
16509
|
+
}
|
|
16510
|
+
|
|
16277
16511
|
// src/serve.ts
|
|
16278
16512
|
async function inOpfs(deps, root) {
|
|
16279
16513
|
if (deps.syncAccess !== true) return false;
|
|
@@ -16388,11 +16622,31 @@ function usersOp(l, req) {
|
|
|
16388
16622
|
if (req.op === "groups-remove-member") return l.users.removeMember(req.group, req.user);
|
|
16389
16623
|
return l.users.list();
|
|
16390
16624
|
}
|
|
16391
|
-
function hostOptions(req, port) {
|
|
16625
|
+
function hostOptions(req, port, sealed) {
|
|
16392
16626
|
return {
|
|
16393
16627
|
...req.hostname !== void 0 ? { hostname: req.hostname } : {},
|
|
16394
16628
|
...req.users !== void 0 ? { users: req.users } : {},
|
|
16395
|
-
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {}
|
|
16629
|
+
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {},
|
|
16630
|
+
...req.sealed ? { sealed } : {}
|
|
16631
|
+
};
|
|
16632
|
+
}
|
|
16633
|
+
function policyAsker(port) {
|
|
16634
|
+
const policies = /* @__PURE__ */ new Map();
|
|
16635
|
+
let nextPolicy = 0;
|
|
16636
|
+
const askPolicy = (req) => new Promise((resolve) => {
|
|
16637
|
+
const id2 = ++nextPolicy;
|
|
16638
|
+
policies.set(id2, resolve);
|
|
16639
|
+
port.postMessage({ mountPolicy: { id: id2, req } });
|
|
16640
|
+
});
|
|
16641
|
+
return {
|
|
16642
|
+
mountPolicy: (policy) => policy === void 0 ? {} : { processMounts: policy === "ask" ? askPolicy : policy },
|
|
16643
|
+
allowed(data) {
|
|
16644
|
+
const answer = data.mountAllowed;
|
|
16645
|
+
if (!answer) return false;
|
|
16646
|
+
policies.get(answer.id)?.(answer.allowed);
|
|
16647
|
+
policies.delete(answer.id);
|
|
16648
|
+
return true;
|
|
16649
|
+
}
|
|
16396
16650
|
};
|
|
16397
16651
|
}
|
|
16398
16652
|
function serveKernel(port, deps) {
|
|
@@ -16402,6 +16656,7 @@ function serveKernel(port, deps) {
|
|
|
16402
16656
|
const terminals = /* @__PURE__ */ new Map();
|
|
16403
16657
|
const reply = (id2, body, transfer) => port.postMessage({ id: id2, ...body }, transfer);
|
|
16404
16658
|
const clients = /* @__PURE__ */ new Set();
|
|
16659
|
+
const sealed = sealedAsker(port);
|
|
16405
16660
|
const approvals = sudoApprovals(port);
|
|
16406
16661
|
const locks = deps.locks === null ? void 0 : deps.locks ?? locksOf();
|
|
16407
16662
|
let holding;
|
|
@@ -16466,7 +16721,7 @@ function serveKernel(port, deps) {
|
|
|
16466
16721
|
...deps.createDriverWorker ? { createDriverWorker: deps.createDriverWorker } : {},
|
|
16467
16722
|
...req.modules ? { modules: req.modules } : {},
|
|
16468
16723
|
...req.env ? { env: req.env } : {},
|
|
16469
|
-
...hostOptions(req, port),
|
|
16724
|
+
...hostOptions(req, port, sealed.hook),
|
|
16470
16725
|
...req.approve ? { approve: approvals.ask } : {},
|
|
16471
16726
|
...net,
|
|
16472
16727
|
...media ? { media } : {},
|
|
@@ -16529,23 +16784,13 @@ function serveKernel(port, deps) {
|
|
|
16529
16784
|
if (grant) waiting.resolve(grant);
|
|
16530
16785
|
else waiting.reject(Object.assign(new Error(error ?? "no grant"), { code: "EACCES" }));
|
|
16531
16786
|
}
|
|
16532
|
-
const
|
|
16533
|
-
let nextPolicy = 0;
|
|
16534
|
-
const askPolicy = (req) => new Promise((resolve) => {
|
|
16535
|
-
const id2 = ++nextPolicy;
|
|
16536
|
-
policies.set(id2, resolve);
|
|
16537
|
-
port.postMessage({ mountPolicy: { id: id2, req } });
|
|
16538
|
-
});
|
|
16539
|
-
const mountPolicy = (policy) => policy === void 0 ? {} : { processMounts: policy === "ask" ? askPolicy : policy };
|
|
16787
|
+
const { mountPolicy, allowed } = policyAsker(port);
|
|
16540
16788
|
port.addEventListener("message", (event) => {
|
|
16789
|
+
const sealedReply = event.data.sealedReply;
|
|
16790
|
+
if (sealedReply) return sealed.answer(sealedReply);
|
|
16541
16791
|
const grant = event.data.hostfsGrant;
|
|
16542
16792
|
if (grant) return granted2(grant);
|
|
16543
|
-
|
|
16544
|
-
if (answer) {
|
|
16545
|
-
policies.get(answer.id)?.(answer.allowed);
|
|
16546
|
-
policies.delete(answer.id);
|
|
16547
|
-
return;
|
|
16548
|
-
}
|
|
16793
|
+
if (allowed(event.data)) return;
|
|
16549
16794
|
if (answered(event.data, remote, uplink, approvals)) return;
|
|
16550
16795
|
const req = event.data;
|
|
16551
16796
|
handle(req).then(
|