kern-sandbox 0.2.12 → 0.2.14

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.
Files changed (2) hide show
  1. package/index.js +26 -2
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -36,7 +36,7 @@ const crypto = require("crypto");
36
36
  const zlib = require("zlib");
37
37
  const { spawn, spawnSync } = require("child_process");
38
38
 
39
- const VERSION = "0.2.12";
39
+ const VERSION = "0.2.14";
40
40
 
41
41
  const DEFAULT_IMAGE = "python:3.12-slim";
42
42
  const WORKSPACE = "/workspace"; // where the persistent workspace is mounted inside every box
@@ -1115,6 +1115,14 @@ function looksLikeStartupFailure(stderr) {
1115
1115
  "error: box:",
1116
1116
  "error: oci:",
1117
1117
  "error: image:",
1118
+ // REACHABLE EXACTLY WHEN A CALLER PASSES `profiles`, and missing until it was measured: a profile
1119
+ // name that is well formed but absent from `kern.toml` makes kern refuse before any box exists, and
1120
+ // without this marker the call came back `exitCode 1, fault null`, which a caller reading `fault`
1121
+ // cannot tell from their own code exiting 1.
1122
+ "error: config:",
1123
+ // The binding builds its own argv, so these mean IT got something wrong; either way the box never ran.
1124
+ "error: usage:",
1125
+ "error: invalid box name:",
1118
1126
  ];
1119
1127
  // The OOM sentence is skipped for a sharper reason than the benign notes: it is a report about a box
1120
1128
  // that RAN, and it is `kern:`-prefixed, so it used to satisfy this predicate. MEASURED, that is how a
@@ -2812,12 +2820,28 @@ class Kernel {
2812
2820
  "the kernel box was killed, and its memory cap was not enforced here (no cgroup delegation), so no memory limit was in force to attribute it to",
2813
2821
  rc,
2814
2822
  ];
2815
- if (this._sbx.memoryMb !== null)
2823
+ if (this._sbx.memoryMb !== null) {
2824
+ // A BINARY THAT DOES NOT REPORT THE SIGNAL CANNOT HAVE THIS SENTENCE PUT IN ITS MOUTH. MEASURED on
2825
+ // the released 0.9.32, which is what `install.sh` serves today: it writes two of the four teardown
2826
+ // bytes, so `workloadSignal` is null, and a cell that SEGFAULTED and a cell whose syscall the
2827
+ // seccomp filter refused both landed here and were told "an external kill", which is false for
2828
+ // both. The verdict cannot improve without the byte; the sentence can say so.
2829
+ if (kernWrotePayload && workloadSignal === null)
2830
+ return [
2831
+ "killed",
2832
+ "the kernel box was killed and the kernel reported no OOM against its memory cap. THIS kern " +
2833
+ "does not report which signal ended the box (it writes 2 of the 4 teardown bytes), so an " +
2834
+ "external kill, a crash in your own code and a syscall the sandbox refused are " +
2835
+ "indistinguishable from here: a newer kern separates them, and until then read the box's " +
2836
+ "stderr before concluding it was killed from outside",
2837
+ rc,
2838
+ ];
2816
2839
  return [
2817
2840
  "killed",
2818
2841
  "the kernel box was killed and the kernel reported no OOM against its memory cap: an external kill (`kern stop`, a signal, or the host running out of memory), not the box exceeding its own memory",
2819
2842
  rc,
2820
2843
  ];
2844
+ }
2821
2845
  return ["killed", "the kernel box exited", rc];
2822
2846
  }
2823
2847
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kern-sandbox",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "description": "kern is a fast, rootless sandbox and virtual resource runtime for any workload, including untrusted and AI-generated code; kern-sandbox is its Node/TypeScript binding. Run untrusted or agent-generated code (Python/JS/Bash) in a real, kernel-enforced box in single-digit milliseconds, with no cloud, no account and no VM.",
5
5
  "keywords": [
6
6
  "sandbox",