@ai-ecoverse/slicc-kernel 1.64.0 → 1.64.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/dist/node.js CHANGED
@@ -410,6 +410,11 @@ var Created = class {
410
410
  function deny(g, op, path, errno = "EACCES") {
411
411
  g.dac.denied({ pid: g.pid, uid: g.cred.euid, op, path, errno });
412
412
  }
413
+ var TTY_MODE = 400;
414
+ function ttyOpenable(g, tty) {
415
+ if (!g || !tty.owner || permits(g.cred, tty.owner, R_OK | W_OK, false)) return;
416
+ deny(g, "open", tty.name ?? "/dev/tty");
417
+ }
413
418
  async function need(g, op, path, want, options = {}, shown = path) {
414
419
  const walked = await access(g.fs, g.cred, path, want, options);
415
420
  if (walked.denied !== void 0) deny(g, op, shown);
@@ -2307,10 +2312,18 @@ var UserDb = class {
2307
2312
  };
2308
2313
  }
2309
2314
  async lookup(user) {
2315
+ return (await this.lookupTerminal(user))?.account;
2316
+ }
2317
+ async ttyGroup() {
2318
+ return parsed(parseGroup(await this.read(GROUP, DEFAULT_GROUP))).find((g) => g.name === "tty")?.gid;
2319
+ }
2320
+ async lookupTerminal(user) {
2310
2321
  const { passwd, group } = await this.tables();
2311
2322
  const key = typeof user === "number" ? "uid" : "name";
2312
2323
  const row = parsed(passwd).find((r) => r[key] === user);
2313
- return row && this.account(row, parsed(group));
2324
+ const groups = parsed(group);
2325
+ const tty = groups.find((g) => g.name === "tty")?.gid;
2326
+ return row && { account: this.account(row, groups), tty };
2314
2327
  }
2315
2328
  async list() {
2316
2329
  const { passwd, group } = await this.tables();
@@ -9589,6 +9602,7 @@ var KernelTty = class {
9589
9602
  waiters = [];
9590
9603
  hungUp = false;
9591
9604
  name;
9605
+ owner;
9592
9606
  onRead;
9593
9607
  readers = 0;
9594
9608
  screen;
@@ -9932,10 +9946,11 @@ var PtyTable = class {
9932
9946
  this.signal = signal;
9933
9947
  this.onRead = onRead;
9934
9948
  }
9935
- open() {
9949
+ open(owner) {
9936
9950
  let index = 0;
9937
9951
  while (this.pairs.has(index)) index += 1;
9938
9952
  const pair = new PtyPair(index, this.signal, (p) => this.pairs.delete(p.index), this.onRead);
9953
+ if (owner) pair.slave.owner = { uid: owner.uid, gid: owner.gid, mode: TTY_MODE };
9939
9954
  this.pairs.set(index, pair);
9940
9955
  return { pair, master: pair.master() };
9941
9956
  }
@@ -9948,6 +9963,10 @@ var PtyTable = class {
9948
9963
  return [...this.pairs.keys()].sort((a, b) => a - b);
9949
9964
  }
9950
9965
  };
9966
+ function ptsNumber(path) {
9967
+ const m = /^\/dev\/pts\/(\d+)$/.exec(path);
9968
+ return m ? Number(m[1]) : void 0;
9969
+ }
9951
9970
  var PTY_OPS = [
9952
9971
  "pty-open",
9953
9972
  "pty-slave-open",
@@ -9975,11 +9994,12 @@ function ptySyscall(req, ctx) {
9975
9994
  switch (req.op) {
9976
9995
  case "pty-open": {
9977
9996
  if (!ctx.ptys) throw new KernelError("ENOENT");
9978
- return json4(ctx.fds.install(ctx.ptys.open().master, 3));
9997
+ return json4(ctx.fds.install(ctx.ptys.open(ctx.owner).master, 3));
9979
9998
  }
9980
9999
  case "pty-slave-open": {
9981
10000
  if (!ctx.ptys) throw new KernelError("ENOENT");
9982
10001
  const pair = ctx.ptys.get(req.n);
10002
+ ttyOpenable(ctx.guard, pair.slave);
9983
10003
  const fd = ctx.fds.install(pair.openSlave(), 3);
9984
10004
  if (!req.noctty) ctx.jobs?.acquireTerminal(ctx.pid, pair.slave);
9985
10005
  return json4(fd);
@@ -10795,6 +10815,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
10795
10815
  "fd-promote",
10796
10816
  "fd-open-tty",
10797
10817
  "fd-tty-names",
10818
+ "fd-tty-owner",
10798
10819
  "tty-get",
10799
10820
  "tty-set",
10800
10821
  "tty-winsz",
@@ -10996,7 +11017,9 @@ var WasmProcess = class {
10996
11017
  }
10997
11018
  if (isPtySyscall(req)) {
10998
11019
  const { ptys, jobs } = this.options;
10999
- return ptySyscall(req, { pid: this.pid, fds: this.fds, ptys, jobs });
11020
+ const owner = this.options.owners ? this.ttyOwner() : void 0;
11021
+ const guard2 = this.guarded();
11022
+ return ptySyscall(req, { pid: this.pid, fds: this.fds, ptys, jobs, guard: guard2, owner });
11000
11023
  }
11001
11024
  return await this.procSyscall(req, cancelled);
11002
11025
  } catch (e) {
@@ -11128,6 +11151,25 @@ var WasmProcess = class {
11128
11151
  const want = (access2 === 1 ? 0 : R_OK) | (access2 !== 0 || req.truncate ? W_OK : 0);
11129
11152
  await openable(g, "open", req.path, want, req.create === true);
11130
11153
  }
11154
+ openTty(name2) {
11155
+ const tty = name2 === void 0 ? this.controllingTerminal() : this.options.jobs?.terminalNamed(name2);
11156
+ if (!tty) throw new KernelError("ENXIO");
11157
+ if (name2 !== void 0) ttyOpenable(this.guarded(), tty);
11158
+ return this.fds.install(tty.file(), 3);
11159
+ }
11160
+ guarded() {
11161
+ const { guard: guard2 } = this.options;
11162
+ return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
11163
+ }
11164
+ ttyOwner() {
11165
+ return { uid: this.cred.euid, gid: this.cred.egid, mode: TTY_MODE };
11166
+ }
11167
+ terminalByName(name2) {
11168
+ const n = ptsNumber(name2);
11169
+ const tty = n === void 0 ? this.options.jobs?.terminalNamed(name2) : this.options.ptys?.get(n).slave;
11170
+ if (!tty) throw new KernelError("ENOENT");
11171
+ return tty;
11172
+ }
11131
11173
  newOwner() {
11132
11174
  if (!this.options.owners) return void 0;
11133
11175
  return { uid: this.cred.euid, gid: this.cred.egid, mode: 438 & ~this.umask };
@@ -11231,13 +11273,12 @@ var WasmProcess = class {
11231
11273
  if (!req.keep) await Promise.resolve(this.fds.close(req.from));
11232
11274
  }
11233
11275
  return { ok: true, kind: "void" };
11234
- case "fd-open-tty": {
11235
- const tty = req.name === void 0 ? this.controllingTerminal() : this.options.jobs?.terminalNamed(req.name);
11236
- if (!tty) throw new KernelError("ENXIO");
11237
- return { ok: true, kind: "json", json: this.fds.install(tty.file(), 3) };
11238
- }
11276
+ case "fd-open-tty":
11277
+ return { ok: true, kind: "json", json: this.openTty(req.name) };
11239
11278
  case "fd-tty-names":
11240
11279
  return { ok: true, kind: "json", json: this.options.jobs?.terminalNames() ?? [] };
11280
+ case "fd-tty-owner":
11281
+ return { ok: true, kind: "json", json: this.terminalByName(req.name).owner ?? null };
11241
11282
  case "fd-select": {
11242
11283
  const { read, write, timeoutMs } = req;
11243
11284
  if (this.owed && timeoutMs !== 0) {
@@ -14962,7 +15003,12 @@ var Launcher = class {
14962
15003
  }
14963
15004
  async account(user) {
14964
15005
  if (typeof user === "object") return user;
14965
- const found = await this.users.lookup(user ?? 0);
15006
+ return (await this.terminalAccount(user)).account;
15007
+ }
15008
+ async terminalAccount(user) {
15009
+ if (typeof user === "object")
15010
+ return { account: user, tty: this.owners ? await this.users.ttyGroup() : void 0 };
15011
+ const found = await this.users.lookupTerminal(user ?? 0);
14966
15012
  if (!found) throw fsError("ENOENT", `no user ${String(user)}`);
14967
15013
  return found;
14968
15014
  }
@@ -14984,7 +15030,7 @@ var Launcher = class {
14984
15030
  return { cwd, file, planned };
14985
15031
  }
14986
15032
  async openTerminal(argv, options) {
14987
- const account = await this.account(options.user);
15033
+ const { account, tty: ttyGroup } = await this.terminalAccount(options.user);
14988
15034
  const { cwd, file, planned } = await this.starting(argv, options.cwd, account);
14989
15035
  if (!planned) throw new Error(`${file}: command not found`);
14990
15036
  let leader = 0;
@@ -14994,6 +15040,7 @@ var Launcher = class {
14994
15040
  );
14995
15041
  tty.onRead = () => this.settling.reading(this.jobs.tcgetpgrp(tty, leader));
14996
15042
  tty.name = `/dev/tty${++this.terminals}`;
15043
+ if (this.owners) tty.owner = { uid: account.uid, gid: ttyGroup ?? account.gid, mode: TTY_MODE };
14997
15044
  tty.setSize(options.cols ?? 80, options.rows ?? 24);
14998
15045
  const fds = new FdTable();
14999
15046
  const stdio = tty.file();