tamperward 2.30.3 → 2.30.5
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/cli/index.js +75 -42
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -14882,7 +14882,7 @@ function runCapturedProcessSync(executable, args, opts) {
|
|
|
14882
14882
|
rmSync6(stateDir, { recursive: true, force: true });
|
|
14883
14883
|
}
|
|
14884
14884
|
}
|
|
14885
|
-
var DIAGNOSTIC_TAIL_BYTES, EMPTY_STREAM, CAPTURE_SUPERVISOR;
|
|
14885
|
+
var DIAGNOSTIC_TAIL_BYTES, EMPTY_STREAM, CLEANUP_HELPERS_SRC, CAPTURE_SUPERVISOR;
|
|
14886
14886
|
var init_suite_diagnostics = __esm({
|
|
14887
14887
|
"src/suite-diagnostics.ts"() {
|
|
14888
14888
|
"use strict";
|
|
@@ -14894,40 +14894,32 @@ var init_suite_diagnostics = __esm({
|
|
|
14894
14894
|
truncated: false,
|
|
14895
14895
|
tail: ""
|
|
14896
14896
|
};
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
const
|
|
14902
|
-
const
|
|
14903
|
-
const
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
// Linux ordinary-exit hardening (#371): process-group ownership alone misses a
|
|
14910
|
-
// descendant that calls setsid(). Track the real descendant tree while the
|
|
14911
|
-
// suite is alive so a reparented session escape is still known when the main
|
|
14912
|
-
// child exits. This supplements, rather than replaces, group termination.
|
|
14913
|
-
const trackedDescendants = new Set();
|
|
14897
|
+
CLEANUP_HELPERS_SRC = String.raw`
|
|
14898
|
+
function readStat(pid) {
|
|
14899
|
+
try {
|
|
14900
|
+
const stat = fs.readFileSync('/proc/' + pid + '/stat', 'utf8');
|
|
14901
|
+
const fields = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
|
|
14902
|
+
const ppid = Number(fields[1]);
|
|
14903
|
+
const starttime = fields[19];
|
|
14904
|
+
if (!Number.isFinite(ppid) || starttime === undefined) return null;
|
|
14905
|
+
return { ppid: ppid, starttime: starttime };
|
|
14906
|
+
} catch (e) { return null; }
|
|
14907
|
+
}
|
|
14914
14908
|
|
|
14915
14909
|
function linuxDescendants(rootPid) {
|
|
14916
14910
|
if (process.platform !== 'linux' || !rootPid) return [];
|
|
14917
14911
|
const byParent = new Map();
|
|
14912
|
+
const startById = new Map();
|
|
14918
14913
|
let names = [];
|
|
14919
|
-
try { names = fs.readdirSync('/proc').filter((x) => /^\d+$/.test(x)); } catch { return []; }
|
|
14914
|
+
try { names = fs.readdirSync('/proc').filter((x) => /^\d+$/.test(x)); } catch (e) { return []; }
|
|
14920
14915
|
for (const name of names) {
|
|
14921
14916
|
const pid = Number(name);
|
|
14922
|
-
|
|
14923
|
-
|
|
14924
|
-
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
kids.push(pid);
|
|
14929
|
-
byParent.set(ppid, kids);
|
|
14930
|
-
} catch {}
|
|
14917
|
+
const st = readStat(pid);
|
|
14918
|
+
if (!st) continue;
|
|
14919
|
+
startById.set(pid, st.starttime);
|
|
14920
|
+
const kids = byParent.get(st.ppid) || [];
|
|
14921
|
+
kids.push(pid);
|
|
14922
|
+
byParent.set(st.ppid, kids);
|
|
14931
14923
|
}
|
|
14932
14924
|
const out = [];
|
|
14933
14925
|
const seen = new Set([rootPid]);
|
|
@@ -14937,16 +14929,56 @@ function linuxDescendants(rootPid) {
|
|
|
14937
14929
|
for (const pid of (byParent.get(parent) || [])) {
|
|
14938
14930
|
if (seen.has(pid)) continue;
|
|
14939
14931
|
seen.add(pid);
|
|
14940
|
-
out.push(pid);
|
|
14932
|
+
out.push({ pid: pid, starttime: startById.get(pid) });
|
|
14941
14933
|
stack.push(pid);
|
|
14942
14934
|
}
|
|
14943
14935
|
}
|
|
14944
14936
|
return out;
|
|
14945
14937
|
}
|
|
14946
14938
|
|
|
14939
|
+
function killableDescendants(tracked) {
|
|
14940
|
+
const out = [];
|
|
14941
|
+
for (const entry of tracked) {
|
|
14942
|
+
const pid = entry[0];
|
|
14943
|
+
const starttime = entry[1];
|
|
14944
|
+
const st = readStat(pid);
|
|
14945
|
+
if (st && st.starttime === starttime) out.push(pid);
|
|
14946
|
+
}
|
|
14947
|
+
return out;
|
|
14948
|
+
}
|
|
14949
|
+
|
|
14950
|
+
function cleanupPlan(child, cfg, platform, killable) {
|
|
14951
|
+
const live = !!child && child.exitCode === null && child.signalCode === null;
|
|
14952
|
+
return {
|
|
14953
|
+
signalGroup: !!(live && cfg.detached && platform !== 'win32'),
|
|
14954
|
+
signalMainChild: live,
|
|
14955
|
+
descendants: platform === 'linux' ? killable() : [],
|
|
14956
|
+
};
|
|
14957
|
+
}
|
|
14958
|
+
`;
|
|
14959
|
+
CAPTURE_SUPERVISOR = String.raw`
|
|
14960
|
+
const cp = require('node:child_process');
|
|
14961
|
+
const fs = require('node:fs');
|
|
14962
|
+
|
|
14963
|
+
const [configFile] = process.argv.slice(1);
|
|
14964
|
+
const cfg = JSON.parse(fs.readFileSync(configFile, 'utf8'));
|
|
14965
|
+
const CAP = Number(cfg.captureBytes);
|
|
14966
|
+
|
|
14967
|
+
const fresh = () => ({ total: 0, tail: Buffer.alloc(0) });
|
|
14968
|
+
const stdout = fresh();
|
|
14969
|
+
const stderr = fresh();
|
|
14970
|
+
|
|
14971
|
+
// Linux ordinary-exit hardening (#371): process-group ownership alone misses a
|
|
14972
|
+
// descendant that calls setsid(). Track the real descendant tree while the
|
|
14973
|
+
// suite is alive so a reparented session escape is still known when the main
|
|
14974
|
+
// child exits. This supplements, rather than replaces, group termination.
|
|
14975
|
+
// pid -> the /proc start-time observed for that pid, so cleanup can re-check
|
|
14976
|
+
// identity before signalling (a bare pid alone can be reused — #545).
|
|
14977
|
+
const trackedDescendants = new Map();
|
|
14978
|
+
${CLEANUP_HELPERS_SRC}
|
|
14947
14979
|
function trackDescendants() {
|
|
14948
14980
|
if (!child || !child.pid || process.platform !== 'linux') return;
|
|
14949
|
-
for (const
|
|
14981
|
+
for (const d of linuxDescendants(child.pid)) trackedDescendants.set(d.pid, d.starttime);
|
|
14950
14982
|
}
|
|
14951
14983
|
|
|
14952
14984
|
function append(state, chunk) {
|
|
@@ -14981,17 +15013,17 @@ let drainTimer = null;
|
|
|
14981
15013
|
function killOwned() {
|
|
14982
15014
|
if (!child || !child.pid) return;
|
|
14983
15015
|
trackDescendants();
|
|
14984
|
-
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
}
|
|
15016
|
+
// The main child and its detached group are signalled only while the child is
|
|
15017
|
+
// still reported live: after its exit event the pid can be reused, and both
|
|
15018
|
+
// child.kill() and kill(-pid) resolve the current bearer of that number (#545).
|
|
15019
|
+
// Descendants are the independently identity-checked set (deepest-first, which
|
|
15020
|
+
// is friendlier to short-lived process trees).
|
|
15021
|
+
const plan = cleanupPlan(child, cfg, process.platform, function () {
|
|
15022
|
+
return killableDescendants(Array.from(trackedDescendants).reverse());
|
|
15023
|
+
});
|
|
15024
|
+
if (plan.signalGroup) { try { process.kill(-child.pid, 'SIGKILL'); } catch {} }
|
|
15025
|
+
if (plan.signalMainChild) { try { child.kill('SIGKILL'); } catch {} }
|
|
15026
|
+
for (const pid of plan.descendants) { try { process.kill(pid, 'SIGKILL'); } catch {} }
|
|
14995
15027
|
}
|
|
14996
15028
|
|
|
14997
15029
|
function finish(extra) {
|
|
@@ -15974,7 +16006,7 @@ function verifyVerdictLine(verdict2, ctx) {
|
|
|
15974
16006
|
}
|
|
15975
16007
|
}
|
|
15976
16008
|
function runVerify(opts) {
|
|
15977
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
16009
|
+
const cwd = repoRoot(opts.cwd ?? process.cwd());
|
|
15978
16010
|
const colour = opts.silent ? false : colourEnabled(process.env, process.stdout);
|
|
15979
16011
|
const paintVerify = (s) => {
|
|
15980
16012
|
if (!s.startsWith("verify:")) return s;
|
|
@@ -16406,6 +16438,7 @@ var init_verify = __esm({
|
|
|
16406
16438
|
"src/cli/verify.ts"() {
|
|
16407
16439
|
"use strict";
|
|
16408
16440
|
init_policy_load();
|
|
16441
|
+
init_repo_context();
|
|
16409
16442
|
init_build();
|
|
16410
16443
|
init_trusted();
|
|
16411
16444
|
init_fingerprint();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.30.
|
|
3
|
+
"version": "2.30.5",
|
|
4
4
|
"description": "The deterministic agent-integrity gate. One ruleset, evaluated on the actual diff/commands as a verdict, enforced everywhere a change can be made.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "hexrift",
|