Files
reverse-engineering-anything/src/process/LinuxProcessStat.test.ts
T
gensokyo-devandClaude Opus 5.5 3f7d0d2d21 test(process): drive kernel thread exclusion through Linux procfs
Replace the simulated-host sweep test with one that parses PF_KTHREAD
from a controlled /proc/<pid>/stat record through the system ownership
host, with root-matching credentials and an ESRCH environ read. The
user-process control with identical facts stays fail-closed. Name the
task flag constants and correct the comments: the reported kernel
threads were live, not exiting.

Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 05:36:23 +01:00

151 lines
4.3 KiB
TypeScript

import { expect, it } from "vitest";
import { parseLinuxProcessStat } from "./LinuxProcessStat.js";
const statRecord = (
options: {
readonly pid?: string;
readonly command?: string;
readonly state?: string;
readonly flags?: string;
readonly parentPid?: string;
readonly processGroupId?: string;
readonly sessionId?: string;
readonly startTime?: string;
} = {},
): string => {
const fields = [
options.state ?? "S",
options.parentPid ?? "17",
options.processGroupId ?? "18",
options.sessionId ?? "19",
];
while (fields.length < 19) fields.push("0");
fields[6] = options.flags ?? "0";
fields.push(options.startTime ?? "987654");
return `${options.pid ?? "42"} (${options.command ?? "worker"}) ${fields.join(" ")}`;
};
it("parses command names containing parentheses and retains native relation facts", () => {
expect(
parseLinuxProcessStat(statRecord({ command: "worker ) old ) name" })),
).toEqual({
pid: 42,
name: "worker ) old ) name",
startTime: "987654",
lifecycle: "non-zombie",
parentPid: 17,
processGroupId: 18,
sessionId: 19,
kernelThread: false,
});
});
it("accepts zero parent, process-group, and session IDs as native facts", () => {
expect(
parseLinuxProcessStat(
statRecord({ parentPid: "0", processGroupId: "0", sessionId: "0" }),
),
).toMatchObject({ parentPid: 0, processGroupId: 0, sessionId: 0 });
});
it("retains identity when Linux teardown reports unavailable group and session IDs", () => {
// Linux v6.8 fs/proc/array.c: do_task_stat initializes pgid/sid to -1
// and only replaces them while lock_task_sighand succeeds.
expect(
parseLinuxProcessStat(
statRecord({
parentPid: "0",
processGroupId: "-1",
sessionId: "-1",
state: "X",
flags: "4",
}),
),
).toEqual({
pid: 42,
name: "worker",
startTime: "987654",
lifecycle: "dead",
parentPid: 0,
processGroupId: -1,
sessionId: -1,
kernelThread: false,
});
expect(
parseLinuxProcessStat(statRecord({ processGroupId: "-2" })),
).toBeUndefined();
expect(
parseLinuxProcessStat(statRecord({ sessionId: "-2" })),
).toBeUndefined();
});
it("distinguishes zombie lifecycle and rejects malformed or missing identity fields", () => {
expect(parseLinuxProcessStat(statRecord({ state: "Z" }))?.lifecycle).toBe(
"zombie",
);
expect(parseLinuxProcessStat("(worker) S 1 2 3")).toBeUndefined();
expect(parseLinuxProcessStat(statRecord({ pid: "0" }))).toBeUndefined();
expect(parseLinuxProcessStat(statRecord({ state: "??" }))).toBeUndefined();
expect(parseLinuxProcessStat(statRecord({ startTime: "not-a-number" }))).toBe(
undefined,
);
});
it.each(["R", "S", "D"])(
"retains PF_EXITING separately from terminal state %s",
(state) => {
expect(
parseLinuxProcessStat(statRecord({ state, flags: "4194316" }))?.lifecycle,
).toBe("exiting");
expect(
parseLinuxProcessStat(statRecord({ state, flags: "4194312" }))?.lifecycle,
).toBe("non-zombie");
},
);
it.each(["Z", "X", "x"])(
"recognizes terminal native state %s independently of flags",
(state) => {
expect(
parseLinuxProcessStat(statRecord({ state, flags: "invalid" }))?.lifecycle,
).toBe(state === "Z" ? "zombie" : "dead");
},
);
it.each(["invalid", "-1", "4.1", "9007199254740992"])(
"preserves identity and relations with unknown flags %s",
(flags) => {
expect(parseLinuxProcessStat(statRecord({ flags }))).toEqual({
pid: 42,
name: "worker",
startTime: "987654",
lifecycle: undefined,
parentPid: 17,
processGroupId: 18,
sessionId: 19,
kernelThread: undefined,
});
},
);
it("distinguishes a kernel thread from a process sharing its flags", () => {
// Field 9 task_flags: PF_KTHREAD is 0x00200000; PF_EXITING stays orthogonal.
expect(parseLinuxProcessStat(statRecord({ flags: "2097408" }))).toMatchObject(
{
kernelThread: true,
lifecycle: "non-zombie",
},
);
expect(parseLinuxProcessStat(statRecord({ flags: "2097156" }))).toMatchObject(
{
kernelThread: true,
lifecycle: "exiting",
},
);
expect(parseLinuxProcessStat(statRecord({ flags: "4" }))).toMatchObject({
kernelThread: false,
lifecycle: "exiting",
});
});