core/host: add meltdown_mitigation passthrough + migrate entrybleed
The kpti_enabled bool in struct skeletonkey_host flattens three
distinct sysfs states into one bit:
/sys/devices/system/cpu/vulnerabilities/meltdown content:
- 'Not affected' → CPU is Meltdown-immune; KPTI off; EntryBleed
doesn't apply (verdict: OK)
- 'Mitigation: PTI' → KPTI on (verdict: VULNERABLE)
- 'Vulnerable' → KPTI off but CPU not hardened (rare;
verdict: VULNERABLE conservatively)
- file unreadable → unknown (verdict: VULNERABLE conservatively)
kpti_enabled=true only captures 'Mitigation: PTI'; kpti_enabled=false
collapses 'Not affected', 'Vulnerable', and 'unreadable' into one
indistinguishable case. That meant entrybleed_detect() had to
re-open the sysfs file to recover the raw string.
Fix by also stashing the raw first line in
ctx->host->meltdown_mitigation[64]. kpti_enabled stays for callers
that only need the simple bool; new code that needs the nuance reads
the string. populate happens once at startup, like every other host
field.
entrybleed migration:
- reads ctx->host->meltdown_mitigation instead of opening sysfs
- removes the file-local read_first_line() helper (now dead code)
- same three-way verdict logic, but driven by a const char *
instead of a fresh fopen() each detect()
Test coverage:
- 3 new test rows on x86_64 fingerprints:
empty mitigation → VULNERABLE (conservative)
'Not affected' → OK
'Mitigation: PTI' → VULNERABLE
- 1 stub-path test row on non-x86_64 fingerprints (PRECOND_FAIL)
- registry coverage report: 30/31 modules now have direct tests
(up from 29/31; copy_fail is the only remaining untested module)
Verification:
- macOS: 33 kernel_range + 1 entrybleed-stub = 34 passes, 0 fails
- Linux (docker gcc:latest): 33 kernel_range + 54 detect = 87
passes, 0 fails. Up from 83 last commit.
This commit is contained in:
@@ -34,6 +34,7 @@ extern const struct skeletonkey_module dirtydecrypt_module;
|
||||
extern const struct skeletonkey_module fragnesia_module;
|
||||
extern const struct skeletonkey_module pack2theroot_module;
|
||||
extern const struct skeletonkey_module overlayfs_module;
|
||||
extern const struct skeletonkey_module entrybleed_module;
|
||||
extern const struct skeletonkey_module dirty_pipe_module;
|
||||
extern const struct skeletonkey_module dirty_cow_module;
|
||||
extern const struct skeletonkey_module ptrace_traceme_module;
|
||||
@@ -594,6 +595,41 @@ static void run_all(void)
|
||||
&nf_tables_module, &h_nf_tables_5_10_209,
|
||||
SKELETONKEY_OK);
|
||||
|
||||
/* ── entrybleed: meltdown_mitigation passthrough ────────────────
|
||||
* entrybleed reads ctx->host->meltdown_mitigation (raw sysfs line)
|
||||
* instead of re-opening /sys/.../meltdown. Test the three branches:
|
||||
* - empty string ("probe failed") → conservative VULNERABLE
|
||||
* - "Not affected" (Meltdown-immune CPU) → OK
|
||||
* - "Mitigation: PTI" (KPTI on, vulnerable) → VULNERABLE
|
||||
* The module is x86_64-only; on other arches the stub returns
|
||||
* PRECOND_FAIL regardless of meltdown status. We test the x86_64
|
||||
* branch via the synthetic host's `arch` field. */
|
||||
#if defined(__x86_64__) || defined(__amd64__)
|
||||
struct skeletonkey_host h_entry_no_data = h_kernel_6_12;
|
||||
h_entry_no_data.meltdown_mitigation[0] = '\0';
|
||||
run_one("entrybleed: meltdown probe unread → conservative VULNERABLE",
|
||||
&entrybleed_module, &h_entry_no_data,
|
||||
SKELETONKEY_VULNERABLE);
|
||||
|
||||
struct skeletonkey_host h_entry_immune = h_kernel_6_12;
|
||||
strcpy(h_entry_immune.meltdown_mitigation, "Not affected");
|
||||
run_one("entrybleed: meltdown=Not affected (immune CPU) → OK",
|
||||
&entrybleed_module, &h_entry_immune,
|
||||
SKELETONKEY_OK);
|
||||
|
||||
struct skeletonkey_host h_entry_kpti = h_kernel_6_12;
|
||||
strcpy(h_entry_kpti.meltdown_mitigation, "Mitigation: PTI");
|
||||
run_one("entrybleed: meltdown=Mitigation: PTI → VULNERABLE",
|
||||
&entrybleed_module, &h_entry_kpti,
|
||||
SKELETONKEY_VULNERABLE);
|
||||
#else
|
||||
/* On non-x86_64 dev / CI containers, the stubbed detect() returns
|
||||
* PRECOND_FAIL regardless of meltdown_mitigation contents. */
|
||||
run_one("entrybleed: non-x86_64 arch → PRECOND_FAIL (stub)",
|
||||
&entrybleed_module, &h_kernel_6_12,
|
||||
SKELETONKEY_PRECOND_FAIL);
|
||||
#endif
|
||||
|
||||
/* ── coverage report ─────────────────────────────────────────
|
||||
* Iterate the runtime registry (populated by skeletonkey_register_*
|
||||
* calls in main()) and warn for any module that was not touched
|
||||
|
||||
Reference in New Issue
Block a user