diff --git a/helm/mosaic-stack/files/openclaw-seed/extensions/diagnostic-policy.ts b/helm/mosaic-stack/files/openclaw-seed/extensions/diagnostic-policy.ts index a5b567b..cbd21f3 100644 --- a/helm/mosaic-stack/files/openclaw-seed/extensions/diagnostic-policy.ts +++ b/helm/mosaic-stack/files/openclaw-seed/extensions/diagnostic-policy.ts @@ -49,6 +49,23 @@ function nvidiaToolArgs(args: string[]) { return args.every(argument => /^(-[A-Za-z]+|--[A-Za-z][A-Za-z0-9_-]*(=[A-Za-z0-9_.,:-]+)?)$/.test(argument)); } +function lspci(args: string[]) { + let needsValue = false; + for (const argument of args) { + if (needsValue) { + if (argument.startsWith('-') || !/^[A-Za-z0-9_.:-]+$/.test(argument)) return false; + needsValue = false; + } else if (argument === '-s' || argument === '-d') { + needsValue = true; + } else if (argument.startsWith('-s') || argument.startsWith('-d')) { + if (!/^-[sd][A-Za-z0-9_.:-]+$/.test(argument)) return false; + } else if (!/^(-[Dknmvxbt]+|-[a-zA-Z]{2,})$/.test(argument)) { + return false; + } + } + return !needsValue; +} + const RULES: Record boolean> = { hostname: exact([], ['-f'], ['--fqdn'], ['-s'], ['--short'], ['-I'], ['--all-ip-addresses']), uname: flags(/^(-[asnrvmpio]+|--(all|kernel-name|nodename|kernel-release|kernel-version|machine|processor|hardware-platform|operating-system))$/), @@ -63,7 +80,7 @@ const RULES: Record boolean> = { vmstat: flags(/^(-[sDd]+|--(stats|disk-sum|disk))$/), iostat: flags(/^(-[cdxmkNyz]+|--(compact|dec|human|pretty))$/), mpstat: flags(/^(-[A-Za-z]+|--[A-Za-z][A-Za-z-]*)$/), - lspci: flags(/^(-[Dknmvx]+|-[a-zA-Z]{2,})$/), + lspci, ibstat: nvidiaToolArgs, ibstatus: nvidiaToolArgs, ibv_devinfo: nvidiaToolArgs, diff --git a/helm/mosaic-stack/tests/diagnostic-policy.test.mjs b/helm/mosaic-stack/tests/diagnostic-policy.test.mjs index 1954858..9b57583 100644 --- a/helm/mosaic-stack/tests/diagnostic-policy.test.mjs +++ b/helm/mosaic-stack/tests/diagnostic-policy.test.mjs @@ -17,6 +17,13 @@ test("allows bounded read-only diagnostic argv", () => { ["systemctl", "status", "slurmd", "--no-pager"], ["scontrol", "show", "nodes"], ["ibstat"], + ["lspci"], + ["lspci", "-s", "0000:01:00.0", "-vvv"], + ["lspci", "-s0000:01:00.0", "-vvv"], + ["lspci", "-vvv", "-s", "0000:01:00.0"], + ["lspci", "-d", "10de:", "-vvv"], + ["lspci", "-d10de:", "-vvv"], + ["lspci", "-t"], ]) assert.equal(isAllowedDiagnosticArgv(argv), true, argv.join(" ")); }); @@ -27,6 +34,10 @@ test("rejects mutation flags, arbitrary programs, paths, and shell syntax", () = ["systemctl", "restart", "slurmd"], ["journalctl", "--rotate"], ["dmesg", "-c"], + ["lspci", "-s"], + ["lspci", "-s", "-vvv"], + ["lspci", "-d"], + ["lspci", "-d", "-vvv"], ["ss", "-K"], ["scontrol", "update", "NodeName=n1", "State=DOWN"], ["cat", "/etc/shadow"],