@ai-ecoverse/slicc-kernel 1.73.0 → 1.73.1
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 +5 -4
- package/dist/kernel-worker.js +63 -21
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +117 -78
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +63 -21
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +117 -78
- package/dist/process-worker.js.map +2 -2
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -2246,6 +2246,9 @@ var UserDb = class {
|
|
|
2246
2246
|
const pnpm = `${home}/.local/share/pnpm`;
|
|
2247
2247
|
if (await this.realDir(pnpm)) await this.fs.chmod(pnpm, scoop ? 488 : 448);
|
|
2248
2248
|
}
|
|
2249
|
+
umaskFor(options) {
|
|
2250
|
+
return (options.umask ?? this.umasks.get(options.name) ?? 18) & 511;
|
|
2251
|
+
}
|
|
2249
2252
|
async realDir(path) {
|
|
2250
2253
|
const parts2 = path.split("/").filter(Boolean);
|
|
2251
2254
|
for (let n = 1; n <= parts2.length; n++) {
|
|
@@ -2269,9 +2272,11 @@ var UserDb = class {
|
|
|
2269
2272
|
group: parseGroup(await this.read(GROUP, DEFAULT_GROUP))
|
|
2270
2273
|
};
|
|
2271
2274
|
}
|
|
2272
|
-
async provision(row) {
|
|
2273
|
-
const
|
|
2274
|
-
const
|
|
2275
|
+
async provision(row, umask, shared) {
|
|
2276
|
+
const dirs = 511 & ~umask | (shared ? 1024 : 0);
|
|
2277
|
+
const gid = shared?.gid ?? row.gid;
|
|
2278
|
+
const owner = this.owners ? { uid: row.uid, gid } : void 0;
|
|
2279
|
+
const made2 = owner ? { recursive: true, owner: { ...owner, mode: dirs, parents: dirs } } : { recursive: true };
|
|
2275
2280
|
const pnpm = `${row.home}/.local/share/pnpm`;
|
|
2276
2281
|
if (!await this.fs.exists(pnpm)) {
|
|
2277
2282
|
await this.fs.mkdir(pnpm, made2);
|
|
@@ -2280,7 +2285,7 @@ var UserDb = class {
|
|
|
2280
2285
|
const config = `${row.home}/.config/pnpm/config.yaml`;
|
|
2281
2286
|
if (!await this.fs.exists(config)) {
|
|
2282
2287
|
await this.fs.mkdir(`${row.home}/.config/pnpm`, made2);
|
|
2283
|
-
await this.fs.writeFile(config, PNPM_CONFIG, owner);
|
|
2288
|
+
await this.fs.writeFile(config, PNPM_CONFIG, owner && { ...owner, mode: 438 & ~umask });
|
|
2284
2289
|
}
|
|
2285
2290
|
}
|
|
2286
2291
|
async commit(passwd, group, then) {
|
|
@@ -2371,7 +2376,7 @@ var UserDb = class {
|
|
|
2371
2376
|
throw fsError("EINVAL", `a user is no member of its own group ${name2}`);
|
|
2372
2377
|
}
|
|
2373
2378
|
if (found.uid >= FIRST_UID && found.uid <= LAST_UID) {
|
|
2374
|
-
await this.provision(found);
|
|
2379
|
+
await this.provision(found, this.umaskFor(options), shared);
|
|
2375
2380
|
await this.stampHome(found, shared, homeMode);
|
|
2376
2381
|
}
|
|
2377
2382
|
if (joined(name2, more)) await this.fs.writeFile(GROUP, formatGroup(group));
|
|
@@ -2389,7 +2394,7 @@ var UserDb = class {
|
|
|
2389
2394
|
const fresh2 = !await this.fs.exists(home);
|
|
2390
2395
|
await this.fs.mkdir(home, { recursive: true });
|
|
2391
2396
|
try {
|
|
2392
|
-
await this.provision(row);
|
|
2397
|
+
await this.provision(row, this.umaskFor(options), shared);
|
|
2393
2398
|
await this.stampHome(row, shared, homeMode);
|
|
2394
2399
|
await this.fs.mkdir("/etc", { recursive: true });
|
|
2395
2400
|
await this.commit(formatPasswd(passwd), formatGroup(group));
|
|
@@ -3944,7 +3949,7 @@ var OpfsFs = class {
|
|
|
3944
3949
|
const above = owner && {
|
|
3945
3950
|
uid: owner.uid,
|
|
3946
3951
|
gid: owner.gid,
|
|
3947
|
-
...mode ? { mode, parents: mode } : {}
|
|
3952
|
+
...mode !== void 0 ? { mode, parents: mode } : {}
|
|
3948
3953
|
};
|
|
3949
3954
|
await this.mkdir(parentOf4(path), { recursive: true, ...above ? { owner: above } : {} });
|
|
3950
3955
|
}
|
|
@@ -6248,6 +6253,11 @@ var HeldPaths = class extends Map {
|
|
|
6248
6253
|
keptFor(handle) {
|
|
6249
6254
|
return this.keptHandles.get(handle);
|
|
6250
6255
|
}
|
|
6256
|
+
keeps(hidden) {
|
|
6257
|
+
for (const file of this.uses.keys()) if (file.hidden === hidden) return true;
|
|
6258
|
+
for (const file of this.unlinked.values()) if (file.hidden === hidden) return true;
|
|
6259
|
+
return false;
|
|
6260
|
+
}
|
|
6251
6261
|
keep(path, file) {
|
|
6252
6262
|
const fresh2 = this.handlesAt(path).filter((id2) => !this.keptHandles.has(id2));
|
|
6253
6263
|
for (const id2 of fresh2) this.keptHandles.set(id2, file);
|
|
@@ -7349,6 +7359,7 @@ function guardOf(entry) {
|
|
|
7349
7359
|
return { fs: entry.fs, cred, pid: entry.pid ?? 0, dac: entry.dac };
|
|
7350
7360
|
}
|
|
7351
7361
|
var FOLLOWING = /* @__PURE__ */ new Set(["exists", "stat", "chown", "statfs"]);
|
|
7362
|
+
var LOOKS = /* @__PURE__ */ new Set(["exists", "stat", "lstat"]);
|
|
7352
7363
|
var NOT_FOLLOWING = /* @__PURE__ */ new Set(["lstat", "readlink", "lchown"]);
|
|
7353
7364
|
async function guard(g, path, req, cwd) {
|
|
7354
7365
|
const { op } = req;
|
|
@@ -7418,6 +7429,7 @@ async function accessOp(entry, path, req) {
|
|
|
7418
7429
|
async function guarded(entry, path, req) {
|
|
7419
7430
|
const g = guardOf(entry);
|
|
7420
7431
|
if (!g) return void 0;
|
|
7432
|
+
if (LOOKS.has(req.op) && await entry.holdsKept?.(path)) return void 0;
|
|
7421
7433
|
try {
|
|
7422
7434
|
await guard(g, path, req, entry.cwd);
|
|
7423
7435
|
return void 0;
|
|
@@ -12309,6 +12321,13 @@ var WasmProcess = class {
|
|
|
12309
12321
|
}
|
|
12310
12322
|
}
|
|
12311
12323
|
keptPath;
|
|
12324
|
+
async holds(path) {
|
|
12325
|
+
for (const fd of this.fds.numbers()) {
|
|
12326
|
+
const { file } = this.fds.get(fd);
|
|
12327
|
+
if ((await file.stat?.().catch(() => void 0))?.path === path) return true;
|
|
12328
|
+
}
|
|
12329
|
+
return false;
|
|
12330
|
+
}
|
|
12312
12331
|
keptHandle;
|
|
12313
12332
|
async keptOr(path, handle) {
|
|
12314
12333
|
const held = handle === void 0 ? void 0 : this.keptHandle?.(handle);
|
|
@@ -12952,7 +12971,8 @@ function spawnWasmProcess(opts) {
|
|
|
12952
12971
|
const token = holdingToken(opts, holds, {
|
|
12953
12972
|
cred: () => process2.cred,
|
|
12954
12973
|
umask: () => process2.umask,
|
|
12955
|
-
created: created3
|
|
12974
|
+
created: created3,
|
|
12975
|
+
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds.keeps(path) || await process2.holds(path))
|
|
12956
12976
|
});
|
|
12957
12977
|
process2.keptPath = (path) => holds.keptAt(path)?.hidden;
|
|
12958
12978
|
process2.keptHandle = (handle2) => holds.keptFor(handle2)?.hidden;
|
|
@@ -15417,9 +15437,14 @@ var Sudo = class {
|
|
|
15417
15437
|
if (walked.denied !== void 0 || walked.missing) return false;
|
|
15418
15438
|
return (await this.o.fs.stat(cwd).catch(() => void 0))?.isDirectory === true;
|
|
15419
15439
|
}
|
|
15420
|
-
async untrusted(path, cwd) {
|
|
15421
|
-
const files = await this.o.backing
|
|
15422
|
-
|
|
15440
|
+
async untrusted(path, cwd, word) {
|
|
15441
|
+
const files = this.o.backing ? await this.o.backing(path, cwd) : [];
|
|
15442
|
+
if (!files) return failed2("ENOENT", `sudo: ${word}: command not found`);
|
|
15443
|
+
for (const file of [path, ...files]) {
|
|
15444
|
+
if (!await this.trusted(file)) {
|
|
15445
|
+
return failed2("EPERM", `sudo: ${file} must be root's, and writable by root only`);
|
|
15446
|
+
}
|
|
15447
|
+
}
|
|
15423
15448
|
return void 0;
|
|
15424
15449
|
}
|
|
15425
15450
|
async locate(word, cwd) {
|
|
@@ -15460,10 +15485,8 @@ var Sudo = class {
|
|
|
15460
15485
|
}
|
|
15461
15486
|
const path = await this.locate(word, cwd);
|
|
15462
15487
|
if (!path) return failed2("ENOENT", `sudo: ${word}: command not found`);
|
|
15463
|
-
const untrusted = await this.untrusted(path, cwd);
|
|
15464
|
-
if (untrusted)
|
|
15465
|
-
return failed2("EPERM", `sudo: ${untrusted} must be root's, and writable by root only`);
|
|
15466
|
-
}
|
|
15488
|
+
const untrusted = await this.untrusted(path, cwd, word);
|
|
15489
|
+
if (untrusted) return untrusted;
|
|
15467
15490
|
const argv = [path, ...args];
|
|
15468
15491
|
const matching = rules.filter(
|
|
15469
15492
|
(rule) => applies(rule) && (rule.target === "ALL" || rule.target === target.name) && (rule.cmnd === "*" || rule.cmnd.length === argv.length && rule.cmnd.every((w, i) => w === argv[i]))
|
|
@@ -15486,10 +15509,8 @@ var Sudo = class {
|
|
|
15486
15509
|
if (await this.canonical(call.cwd) !== cwd || !await this.reachable(cred, cwd)) {
|
|
15487
15510
|
return failed2("EACCES", `sudo: ${call.cwd} changed while the request waited`);
|
|
15488
15511
|
}
|
|
15489
|
-
const changed = await this.untrusted(path, cwd);
|
|
15490
|
-
if (changed)
|
|
15491
|
-
return failed2("EPERM", `sudo: ${changed} must be root's, and writable by root only`);
|
|
15492
|
-
}
|
|
15512
|
+
const changed = await this.untrusted(path, cwd, word);
|
|
15513
|
+
if (changed) return changed;
|
|
15493
15514
|
if (answer === "always" && !await this.remember(self, target, argv)) {
|
|
15494
15515
|
return failed2("EIO", "sudo: the rule could not be recorded");
|
|
15495
15516
|
}
|
|
@@ -16119,7 +16140,7 @@ var Launcher = class {
|
|
|
16119
16140
|
}
|
|
16120
16141
|
async backing(file, cwd) {
|
|
16121
16142
|
const planned = await this.plan(file, [file], cwd, "");
|
|
16122
|
-
if (!planned) return
|
|
16143
|
+
if (!planned) return void 0;
|
|
16123
16144
|
const { glue, wasm, imports } = planned.target;
|
|
16124
16145
|
const files = [glue, wasm, ...imports ? [imports] : []];
|
|
16125
16146
|
const scripts = [];
|
|
@@ -16727,6 +16748,27 @@ var Launcher = class {
|
|
|
16727
16748
|
await this.provisionPnpmHome();
|
|
16728
16749
|
return entry;
|
|
16729
16750
|
}
|
|
16751
|
+
async ownTmp() {
|
|
16752
|
+
const real = await this.realLayoutPath("/tmp");
|
|
16753
|
+
const st = real === void 0 ? void 0 : await this.base.lstat(real).catch(() => void 0);
|
|
16754
|
+
if (real !== void 0 && st?.isDirectory && this.base.hasOwner && !await this.base.hasOwner(real)) {
|
|
16755
|
+
let removed = 0;
|
|
16756
|
+
for (const name2 of await this.base.readdir(real).catch(() => [])) {
|
|
16757
|
+
const path = joinName(real, name2);
|
|
16758
|
+
if (await this.base.hasOwner(path) || this.inUse(path)) continue;
|
|
16759
|
+
const failed3 = await this.base.rm(path, { recursive: true, force: true }).catch(String);
|
|
16760
|
+
if (failed3 === void 0) removed++;
|
|
16761
|
+
}
|
|
16762
|
+
if (removed > 0) {
|
|
16763
|
+
console.warn(`slicc-kernel users: removed ${removed} entries from /tmp that had no owner`);
|
|
16764
|
+
}
|
|
16765
|
+
await this.base.chown?.(real, { uid: 0, gid: 0, mode: 1023, follow: false });
|
|
16766
|
+
}
|
|
16767
|
+
if (st?.isDirectory) await this.base.chmod(real, 1023);
|
|
16768
|
+
}
|
|
16769
|
+
inUse(path) {
|
|
16770
|
+
return [...this.openFiles].some((nodes) => nodes.holds(path)) || heldUnder(this.held, path);
|
|
16771
|
+
}
|
|
16730
16772
|
async stampLayout() {
|
|
16731
16773
|
const layout = [
|
|
16732
16774
|
...LAYOUT,
|
|
@@ -16846,7 +16888,7 @@ var Launcher = class {
|
|
|
16846
16888
|
async prepare() {
|
|
16847
16889
|
await this.resolvePrefixes();
|
|
16848
16890
|
for (const dir of SHARED_DIRS) await this.base.mkdir(dir, { recursive: true });
|
|
16849
|
-
if (this.owners) await this.
|
|
16891
|
+
if (this.owners) await this.ownTmp();
|
|
16850
16892
|
await this.provisionPnpmHome();
|
|
16851
16893
|
await this.users.ensure();
|
|
16852
16894
|
if (this.owners) await this.stampLayout();
|