This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import type { RuntimeProfile } from "./runtime.ts";
|
||||
|
||||
export function agentCommand(
|
||||
profile: RuntimeProfile,
|
||||
command: string,
|
||||
args: string[],
|
||||
options: Omit<Deno.CommandOptions, "args" | "uid" | "gid"> = {},
|
||||
): Deno.Command {
|
||||
return new Deno.Command(command, {
|
||||
...options,
|
||||
args,
|
||||
uid: profile.uid,
|
||||
gid: profile.gid,
|
||||
});
|
||||
}
|
||||
|
||||
async function profileProcessIds(uid: number): Promise<number[]> {
|
||||
const ids: number[] = [];
|
||||
for await (const entry of Deno.readDir("/proc")) {
|
||||
if (!entry.isDirectory || !/^\d+$/.test(entry.name)) continue;
|
||||
const status = await Deno.readTextFile(`/proc/${entry.name}/status`).catch(
|
||||
() => null,
|
||||
);
|
||||
const owner = status?.match(/^Uid:\s+(\d+)/m)?.[1];
|
||||
if (owner !== undefined && Number(owner) === uid) {
|
||||
ids.push(Number(entry.name));
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
export async function killProfileProcesses(uid: number): Promise<void> {
|
||||
for (let attempt = 0; attempt < 100; attempt++) {
|
||||
const ids = await profileProcessIds(uid);
|
||||
if (ids.length === 0) return;
|
||||
for (const pid of ids) {
|
||||
try {
|
||||
Deno.kill(pid, "SIGKILL");
|
||||
} catch (error) {
|
||||
if (!(error instanceof Deno.errors.NotFound)) throw error;
|
||||
}
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
throw new Error(`profile UID ${uid} still owns processes after cleanup`);
|
||||
}
|
||||
|
||||
export async function readProfileFile(
|
||||
profile: RuntimeProfile,
|
||||
path: string,
|
||||
): Promise<string> {
|
||||
const stat = await Deno.lstat(path);
|
||||
if (
|
||||
!stat.isFile || stat.isSymlink || stat.uid !== profile.uid ||
|
||||
(stat.mode! & 0o077) !== 0
|
||||
) {
|
||||
throw new Error(`${path}: expected a profile-owned regular private file`);
|
||||
}
|
||||
return await Deno.readTextFile(path);
|
||||
}
|
||||
Reference in New Issue
Block a user