69 Commits

Author SHA1 Message Date
github-actions[bot]
83be8fd544 chore: fix build workflow
built from commit de853fc801
 dated 2026-04-08 23:00:40 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-08 21:02:02 +00:00
Stéphane Lesimple
9383287fc6 chore: delete FAQ.md from ./ in test-build (moved to doc/ in test) 2026-04-08 20:18:32 +00:00
github-actions[bot]
a2823830a6 chore: create doc/ in -build branch
built from commit 2b1389e5c667a3c10c8e47fca7cb14d81695165c
 dated 2026-04-08 21:57:03 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-08 20:10:38 +00:00
github-actions[bot]
6212de226a enh: when reading CPUID is unavailable (VM?), fallback to cpuinfo where applicable
built from commit 954eb13468
 dated 2026-04-06 18:58:36 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 cap_* variable <= cpuinfo flag

cap_ibrs              <= ibrs
cap_ibpb              <= ibpb
cap_stibp             <= stibp
cap_ssbd              <= ssbd / virt_ssbd
cap_l1df              <= flush_l1d
cap_md_clear          <= md_clear
cap_arch_capabilities <= arch_capabilities

Should fix #288
2026-04-06 17:00:15 +00:00
github-actions[bot]
f8873048fc enh: read/write_msr: clearer error messages
built from commit be91749d3a
 dated 2026-04-06 18:43:36 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 16:44:52 +00:00
github-actions[bot]
463e33d61c fix: CVE-2017-5715 (Spectre V2): Red Hat specific fix for RSB Filling (fixes #235)
built from commit d040c0ffc3
 dated 2026-04-06 17:40:59 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 15:42:13 +00:00
github-actions[bot]
4d1af90420 fix: better compatibility under busybox, silence buggy unzlma versions (fix #432)
built from commit fc34cb729b
 dated 2026-04-06 17:12:21 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 15:14:01 +00:00
github-actions[bot]
e8a3c7d7f5 fix: wrmsr: specify core number (closes #294)
built from commit fe5bf7c003
 dated 2026-04-06 17:01:17 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 15:02:33 +00:00
github-actions[bot]
8ae598802c enh: clearer kernel info section at the top of the script
built from commit ac09be87b5
 dated 2026-04-06 15:00:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 13:01:21 +00:00
github-actions[bot]
48a4c0e49c chore: add comment about is_intel/amd/hygon recursion
built from commit 730dd50024
 dated 2026-04-06 13:46:11 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 12:06:52 +00:00
github-actions[bot]
1557bbee42 doc: document Platypus (CVE-2020-8694 CVE-2020-8695) as out of scope (#384)
built from commit fe133e97e0205c7643d8648d0fbb19c67c65636a
 dated 2026-04-06 13:26:38 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 11:27:56 +00:00
github-actions[bot]
4530f39fae doc: document CVE-2020-24511 and CVE-2020-24512 as being out of scope along with rationale (#409)
built from commit 7b36ca50b860666a5ec605992b3ffe2308199290
 dated 2026-04-06 13:07:20 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 11:08:28 +00:00
github-actions[bot]
d247733496 fix: CPUs affected by MSBDS but not MDS (fix #351)
built from commit 716caae53f8ee8a6276a8fa0b9327b3ee3f4a3e0
 dated 2026-04-06 12:58:03 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 10:59:40 +00:00
github-actions[bot]
fc66ee567a doc: add CVE-2019-11157 (Plundervolt) to unsupported CVE list
built from commit 00386b80f6d0ef82def918e4cef1b5193c57966a
 dated 2026-04-06 12:38:57 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 10:40:10 +00:00
github-actions[bot]
072b98cefd fix: better detect kernel lockdown & no longer require cap_flush_cmd to deem CVE-2018-3615 as mitigated (fix #296)
built from commit c3b8c59a8c08a321fec1a6f30739c301ef6e6062
 dated 2026-04-06 12:29:26 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 10:30:36 +00:00
github-actions[bot]
bceb62f982 feat: implement check for MMIO Stale Data (CVE-2022-21123 CVE-2022-21125 CVE-2022-21166) (#437)
built from commit ee28c1107ec2255caeb85cf0c47a2d1b5034e7a5
 dated 2026-04-06 11:25:51 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 09:31:08 +00:00
github-actions[bot]
aacdd35c57 doc: add Blindside to unsupported list (#374)
built from commit 02ffdc7a405e1c5b59a64dc8891db8fde46cf824
 dated 2026-04-06 10:27:17 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 08:28:38 +00:00
github-actions[bot]
c0a389b086 doc: add CVE-2020-0549 (L1D Eviction Sampling, CacheOut) as unsupported
built from commit ef57f070db
 dated 2026-04-06 03:33:32 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 01:34:41 +00:00
github-actions[bot]
726f9e54f5 fix: CVE-2019-11135 (TAA) detect new 0x10F MSR for TSX-disabled CPUs (#414)
built from commit 0caabfc220
 dated 2026-04-06 03:23:56 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 01:25:09 +00:00
github-actions[bot]
11210ab772 fix: CVE-2024-3635[0,7] don't print lines about TSA CPUID bits under non-AMD
built from commit 6106dce8d8
 dated 2026-04-06 03:09:18 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 01:10:32 +00:00
github-actions[bot]
624aef4a46 feat: add CVE-2023-20588 (AMD DIV0 bug) (#473)
built from commit b71465ff74
 dated 2026-04-06 02:40:09 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 00:47:00 +00:00
github-actions[bot]
b6a7ee2345 doc: add CVE-2024-2201 (Native BHI) and TLBleed as unsupported
built from commit 2cfb4f5d20019825c1865af9868047877537c840
 dated 2026-04-06 02:23:52 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-06 00:25:24 +00:00
github-actions[bot]
5698711b3d fix: CVE-2020-0543 (SRBDS): microcode mitigation misdetected (#492)
built from commit 41251d8e51ec7fcff6025bf772ae8b6778d0c641
 dated 2026-04-06 00:58:49 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-05 23:00:02 +00:00
github-actions[bot]
e0f9aeab81 enh: detect IPBP return predictor bypass in Inception/SRSO ("PB-Inception") (#500)
built from commit 766441a1c730d15aa135ebe2be414d9b00ee11f8
 dated 2026-04-06 00:45:09 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 AMD Zen 1-3 CPUs don't flush return predictions on IBPB, allowing
cross-process Spectre attacks even with IBPB-on-entry active. The kernel
fix (v6.12+, backported) adds RSB fill after IBPB on affected CPUs.
Detect this gap by checking CPUID IBPB_RET bit and kernel ibpb_no_ret
bug flag, and flag systems relying on IBPB without the RSB fill fix.
2026-04-05 22:47:43 +00:00
github-actions[bot]
2f550ba8cd fix: don't default to 0x0 ucode when unknown
built from commit 9775d4762d97da696022ecb4dc3ef83f85318667
 dated 2026-04-06 00:38:55 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-05 22:40:17 +00:00
github-actions[bot]
3f60773ec4 enh: MDS FreeBSD: detect software mitigation as OK unless --paranoid (#503)
built from commit f5c42098c3
 dated 2026-04-06 00:17:32 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-05 22:18:42 +00:00
github-actions[bot]
acaf3b684f doc: update dev guidelines
built from commit bbdf54cf7f
 dated 2026-04-05 23:58:14 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-05 22:01:40 +00:00
github-actions[bot]
0ec51090ae fix: add rebleet to --variant
built from commit 75d053a0f1
 dated 2026-04-04 18:17:35 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 16:22:49 +00:00
github-actions[bot]
e9cb988409 fix: add rebleet to --variant
built from commit 1b3ef84bcf68508148673e878221b9c35a463d1f
 dated 2026-04-04 18:17:35 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 16:21:37 +00:00
github-actions[bot]
c147f3f7d4 retbl
built from commit 8e50dabb2d6d2e9299679c6ffcc8c69aa4756f7a
 dated 2026-04-04 18:17:35 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 16:19:20 +00:00
github-actions[bot]
065f19e313 enh: add known fixed ucode versions for CVE-2023-23583 (Reptar) and CVE-2024-45332 (BPI)
built from commit da7b9bd282
 dated 2026-04-04 17:50:04 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 15:51:28 +00:00
github-actions[bot]
1214e63687 chore: reorder CVE list in README.md
built from commit 5a29f5837c
 dated 2026-04-04 16:14:05 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 14:33:25 +00:00
github-actions[bot]
67be7eb116 chore: reorder CVE list in README.md
built from commit ad98a15c6578fc58d0f84e9a39ea9671f5ef561a
 dated 2026-04-04 16:14:05 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 14:16:02 +00:00
github-actions[bot]
b4db134e49 feat: implement CVE-2025-40300 (VMScape) and CVE-2024-45332 (BTI)
built from commit 6273344e62f9a56dc0dd834d1bd977c5af43a98d
 dated 2026-04-04 14:41:09 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 13:08:23 +00:00
github-actions[bot]
d7cd9e8b6b add a generated version of src/libs/003_intel_models.sh
built from commit 533943ed644da77239cb5dbaddd1c7cd7f977388
 dated 2026-04-04 14:20:18 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 12:24:10 +00:00
github-actions[bot]
a4c3900ef0 add a generated version of src/libs/003_intel_models.sh
built from commit a7e80c1d57b82f9971d0114cf67aa2fc7875ec76
 dated 2026-04-04 14:20:18 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-04 12:21:51 +00:00
github-actions[bot]
1d00acbc9a chore: don't include src/ generated files in build
built from commit a77cf8264f
 dated 2026-04-02 23:49:40 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 21:56:42 +00:00
github-actions[bot]
90a8a3057c chore: don't include src/ generated files in build
built from commit b7dc3efcd99cb66193db2729046bde4915dd026c
 dated 2026-04-02 23:49:40 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 21:54:17 +00:00
github-actions[bot]
40b7ae9098 chore: don't include src/ generated files in build
built from commit 35fd7603425d409d76ea4071ec3be5c38dbb1967
 dated 2026-04-02 23:49:40 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 21:50:52 +00:00
github-actions[bot]
27ac93dd39 doc: CVE-2018-3693 CVE-2019-1125 CVE-2019-15902 unsupported or already included
built from commit ae5493257e
 dated 2026-04-02 23:22:31 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 21:23:44 +00:00
github-actions[bot]
dab7bebd3c doc: CVE-2018-15572 is already implemented along Spectre V2
built from commit 47e202100a
 dated 2026-04-02 23:10:39 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 21:13:46 +00:00
github-actions[bot]
8f76537159 doc: CVE-2018-15572 is already implemented along Spectre V2
built from commit 9d9ca447dffc171be0b8d519c74fb163f161c06a
 dated 2026-04-02 23:10:39 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 21:11:59 +00:00
github-actions[bot]
fd7083cb08 doc: CVE-2018-9056 is out of scope (closes #169)
built from commit 0edb357894
 dated 2026-04-02 22:58:45 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 20:59:55 +00:00
github-actions[bot]
8ef4c71d36 enh: group results by 4 in the summary line at the end of the run
built from commit 86e0fae48a
 dated 2026-04-02 22:45:08 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 20:46:29 +00:00
github-actions[bot]
240d6db210 enh: rework VERSION adjust when we're cloned
built from commit cb3b9a37fa
 dated 2026-04-02 22:32:22 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 20:35:00 +00:00
github-actions[bot]
fbfdb89e7a chore: add proper header to all src/vulns/* files
built from commit 3ea8e213ec
 dated 2026-04-02 20:47:54 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 19:35:40 +00:00
github-actions[bot]
5c571bacc6 enh: CVE-2022-40982 (Downfall) overhaul
built from commit e7fa2f30cc
 dated 2026-04-02 19:55:25 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 - added `--kernel-config` support for all three Kconfig variants seen over all kernel versions up to now
- added `--kernel-map` support for `gds_select_mitigation` in `System.map`
- fixed the `--sysfs-only` mode
- added verbose information about remediation when `--explain` is used
- implemented `--paranoid mode`, requiring `GDS_MITIGATION_LOCKED` so that mitigation can't be disabled at runtime
- fixed offline mode (was wrongly looking at the system `dmesg`)
- better microcode status reporting (enabled, disabled, unsupported, unknown)
- fixed unknown (EOL) AVX-capable Intel family 6 CPUs now defaulting to affected
- fixed 2 missing known affected CPU models: INTEL_FAM6_SKYLAKE_L and INTEL_FAM6_SKYLAKE
- fixed case when we're running in a VM and the hypervisor doesn't let us read the MSR
2026-04-02 18:11:41 +00:00
github-actions[bot]
6f8112c700 enh: CVE-2022-40982 (Downfall) overhaul
built from commit c4c4ea8c0a5f2ffde852a22f26b9801bca61139a
 dated 2026-04-02 19:55:25 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 - added `--kernel-config` support for all three Kconfig variants seen over all kernel versions up to now
- added `--kernel-map` support for `gds_select_mitigation` in `System.map`
- fixed the `--sysfs-only` mode
- added verbose information about remediation when `--explain` is used
- implemented `--paranoid mode`, requiring `GDS_MITIGATION_LOCKED` so that mitigation can't be disabled at runtime
- fixed offline mode (was wrongly looking at the system `dmesg`)
- better microcode status reporting (enabled, disabled, unsupported, unknown)
- fixed unknown (EOL) AVX-capable Intel family 6 CPUs now defaulting to affected
- fixed 2 missing known affected CPU models: INTEL_FAM6_SKYLAKE_L and INTEL_FAM6_SKYLAKE
2026-04-02 18:03:22 +00:00
github-actions[bot]
f46c743cad chore: build: also add new files, handle github workflows
built from commit c799974038
 dated 2026-04-02 18:47:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 16:48:13 +00:00
github-actions[bot]
33bdd0688d chore: conditional workflows on all branches
built from commit 5e2af29e6a
 dated 2026-04-02 18:36:43 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 16:39:04 +00:00
github-actions[bot]
7f87ade3fe chore: conditional workflows on all branches
built from commit 44312e3ed385437674a56340b53ca59df291fc41
 dated 2026-04-02 18:36:43 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 16:38:01 +00:00
github-actions[bot]
e2d4d14e14 chore: add stalebot in dryrun
built from commit 5fc008f2d4
 dated 2026-04-02 13:13:19 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 11:36:58 +00:00
github-actions[bot]
ddf2f2c723 chore: add stalebot in dryrun
built from commit 5fc008f2d4
 dated 2026-04-02 13:13:19 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-02 11:14:30 +00:00
github-actions[bot]
fe376887ab enh: CVE-2017-5715; check for unprivileged eBPF for paranoid mode
built from commit e5c6d2d905
 dated 2026-04-01 20:37:54 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-01 20:39:36 +00:00
github-actions[bot]
7b41bcca2b chore: shellcheck fixes
built from commit ac327ce7c5
 dated 2026-04-01 20:10:29 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-01 20:11:58 +00:00
github-actions[bot]
151dd12e3e fix: cap_rdcl_no, cap_gds_no, cap_tsa_*_no were not setting the current CPU status as immune for their respective vulns
built from commit 278989d550
 dated 2026-04-01 00:47:41 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 22:48:56 +00:00
github-actions[bot]
15ea90f312 enh: draft rework of CVE-2017-5753 aka spectre v1
built from commit 4738e8f0ad
 dated 2026-04-01 00:22:07 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 22:23:17 +00:00
github-actions[bot]
5fd6a20ebb chore: readme: add a second table one about impact/mitigation, rework sections
built from commit c20369d9e3899b03280bf72893956f36844bc969
 dated 2026-03-31 22:57:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 22:09:49 +00:00
github-actions[bot]
e7df6a3e30 chore: readme: add a second table one about impact/mitigation
built from commit 4f16822bb11f5b8461647c228a7f2087d5716aea
 dated 2026-03-31 22:57:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 22:05:17 +00:00
github-actions[bot]
ba24551c56 chore: readme: add a second table one about impact/mitigation
built from commit 25a7e7089a3c14f0b2d1320995b08d9d941d8c51
 dated 2026-03-31 22:57:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 22:02:37 +00:00
github-actions[bot]
7c2699c01a chore: readme: add a second table one about impact/mitigation
built from commit 3e969c94e04e48f8db9dbb5603371e1180a4d32a
 dated 2026-03-31 22:57:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 21:53:12 +00:00
github-actions[bot]
6663b6422e chore: readme: add a second table one about impact/mitigation
built from commit b74adb0957c471014dce284b2b6bf8cad85edf38
 dated 2026-03-31 22:57:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 21:43:28 +00:00
github-actions[bot]
fe55c70658 chore: clearer CVE table in README.md
built from commit 9bbefb7bae40c7c240641b3f714691a76976c9c0
 dated 2026-03-31 22:57:00 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 21:01:37 +00:00
github-actions[bot]
d0822e1f9d chore: prepare for dev-build renaming to test-build
built from commit 295324a545
 dated 2026-03-31 19:34:52 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-31 17:53:45 +00:00
github-actions[bot]
10e5b5749e chore: set VERSION when building
built from commit efa07e7fd9
 dated 2026-03-30 23:46:13 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-30 22:22:20 +00:00
github-actions[bot]
4f7f83a40e chore: set VERSION when building
built from commit 88099e12bf082112a1579e2cd37f010c29463e9d
 dated 2026-03-30 23:46:13 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-30 21:51:45 +00:00
github-actions[bot]
4bbbd71564 update dev docs and refactor CVE list in readme
built from commit eabddf3d72
 dated 2026-03-30 23:24:18 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-30 21:39:55 +00:00
github-actions[bot]
c174a8b754 update dev docs and readme
built from commit f66cb22a6d4779162909ea1ae1139c80942b1ce8
 dated 2026-03-30 23:24:18 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-30 21:28:20 +00:00
github-actions[bot]
0f36203b5f chore: adjust workflow for dev-build
built from commit 254f8ece6de39214c5e25694b0fea8c2ddfbf511
 dated 2026-03-30 21:24:34 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-03-30 21:08:41 +00:00
10 changed files with 4443 additions and 390 deletions

View File

@@ -25,21 +25,81 @@ jobs:
mv spectre-meltdown-checker.sh dist/ mv spectre-meltdown-checker.sh dist/
- name: check direct execution - name: check direct execution
run: | run: |
set -x
expected=$(cat .github/workflows/expected_cve_count) expected=$(cat .github/workflows/expected_cve_count)
cd dist cd dist
nb=$(sudo ./spectre-meltdown-checker.sh --batch json | jq '.[]|.CVE' | wc -l)
json=$(sudo ./spectre-meltdown-checker.sh --batch json || true)
# Validate JSON is well-formed (and show it if not)
echo "$json" | jq . >/dev/null || {
echo "Invalid JSON produced by spectre-meltdown-checker.sh"
echo "$json"
exit 1
}
# Validate required keys exist
for key in meta system cpu cpu_microcode vulnerabilities; do
echo "$json" | jq -e ".$key" >/dev/null || {
echo "Missing top-level key: $key"
echo "$json" | jq .
exit 1
}
done
# Use -r to get raw scalars (no quotes)
fmtver=$(echo "$json" | jq -r '.meta.format_version // empty')
if [ "$fmtver" != "1" ]; then
echo "Unexpected format_version: $fmtver"
echo "$json" | jq .
exit 1
fi
run_as_root=$(echo "$json" | jq -r '.meta.run_as_root // empty')
if [ "$run_as_root" != "true" ]; then
echo "Expected run_as_root=true, got: $run_as_root"
echo "$json" | jq .
exit 1
fi
mocked=$(echo "$json" | jq -r '.meta.mocked // "false"')
if [ "$mocked" = "true" ]; then
echo "mocked=true must never appear in production"
echo "$json" | jq .
exit 1
fi
# Count CVEs robustly (as a number)
nb=$(echo "$json" | jq -r '[.vulnerabilities[].cve] | length')
if [ "$nb" -ne "$expected" ]; then if [ "$nb" -ne "$expected" ]; then
echo "Invalid number of CVEs reported: $nb instead of $expected" echo "Invalid number of CVEs reported: $nb instead of $expected"
echo "$json" | jq '.vulnerabilities[].cve'
exit 1 exit 1
else else
echo "OK $nb CVEs reported" echo "OK $nb CVEs reported"
fi fi
# Validate json-terse backward compatibility
nb_terse=$(sudo ./spectre-meltdown-checker.sh --batch json-terse | jq -r 'map(.CVE) | length')
if [ "$nb_terse" -ne "$expected" ]; then
echo "json-terse backward compat broken: $nb_terse CVEs instead of $expected"
exit 1
else
echo "OK json-terse backward compat: $nb_terse CVEs"
fi
- name: check docker compose run execution - name: check docker compose run execution
run: | run: |
expected=$(cat .github/workflows/expected_cve_count) expected=$(cat .github/workflows/expected_cve_count)
cd dist cd dist
docker compose build docker compose build
nb=$(docker compose run --rm spectre-meltdown-checker --batch json | jq '.[]|.CVE' | wc -l) json=$(docker compose run --rm spectre-meltdown-checker --batch json || true)
echo "$json" | jq . > /dev/null
fmtver=$(echo "$json" | jq '.meta.format_version')
if [ "$fmtver" != "1" ]; then
echo "Unexpected format_version: $fmtver"
exit 1
fi
nb=$(echo "$json" | jq '.vulnerabilities[].cve' | wc -l)
if [ "$nb" -ne "$expected" ]; then if [ "$nb" -ne "$expected" ]; then
echo "Invalid number of CVEs reported: $nb instead of $expected" echo "Invalid number of CVEs reported: $nb instead of $expected"
exit 1 exit 1
@@ -51,7 +111,14 @@ jobs:
expected=$(cat .github/workflows/expected_cve_count) expected=$(cat .github/workflows/expected_cve_count)
cd dist cd dist
docker build -t spectre-meltdown-checker . docker build -t spectre-meltdown-checker .
nb=$(docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/modules:/lib/modules:ro spectre-meltdown-checker --batch json | jq '.[]|.CVE' | wc -l) json=$(docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/modules:/lib/modules:ro spectre-meltdown-checker --batch json || true)
echo "$json" | jq . > /dev/null
fmtver=$(echo "$json" | jq '.meta.format_version')
if [ "$fmtver" != "1" ]; then
echo "Unexpected format_version: $fmtver"
exit 1
fi
nb=$(echo "$json" | jq '.vulnerabilities[].cve' | wc -l)
if [ "$nb" -ne "$expected" ]; then if [ "$nb" -ne "$expected" ]; then
echo "Invalid number of CVEs reported: $nb instead of $expected" echo "Invalid number of CVEs reported: $nb instead of $expected"
exit 1 exit 1
@@ -92,15 +159,19 @@ jobs:
fi fi
- name: create a pull request to ${{ github.ref_name }}-build - name: create a pull request to ${{ github.ref_name }}-build
run: | run: |
# all the files in dist/* and .github/* must be moved as is to the -build branch root, move them out for now:
tmpdir=$(mktemp -d) tmpdir=$(mktemp -d)
mv ./dist/* .github $tmpdir/ mv ./dist/* .github $tmpdir/
rm -rf ./dist rm -rf ./dist
git fetch origin ${{ github.ref_name }}-build git fetch origin ${{ github.ref_name }}-build
git checkout -f ${{ github.ref_name }}-build git checkout -f ${{ github.ref_name }}-build
rm -rf doc/
mv $tmpdir/* . mv $tmpdir/* .
rm -rf src/ rm -rf src/ scripts/ img/
mkdir -p .github mkdir -p .github
rsync -vaP --delete $tmpdir/.github/ .github/ rsync -vaP --delete $tmpdir/.github/ .github/
git add --all git add --all
echo =#=#= DIFF CACHED echo =#=#= DIFF CACHED
git diff --cached git diff --cached

View File

@@ -1 +1 @@
26 31

View File

@@ -22,12 +22,17 @@ CVE | Name | Aliases
[CVE-2019-11091](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11091) | Microarchitectural Data Sampling Uncacheable Memory | MDSUM, RIDL [CVE-2019-11091](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11091) | Microarchitectural Data Sampling Uncacheable Memory | MDSUM, RIDL
[CVE-2019-11135](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11135) | TSX Asynchronous Abort | TAA, ZombieLoad V2 [CVE-2019-11135](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11135) | TSX Asynchronous Abort | TAA, ZombieLoad V2
[CVE-2020-0543](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-0543) | Special Register Buffer Data Sampling | SRBDS, CROSSTalk [CVE-2020-0543](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-0543) | Special Register Buffer Data Sampling | SRBDS, CROSSTalk
[CVE-2022-21123](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21123) | Shared Buffers Data Read | SBDR, MMIO Stale Data
[CVE-2022-21125](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21125) | Shared Buffers Data Sampling | SBDS, MMIO Stale Data
[CVE-2022-21166](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21166) | Device Register Partial Write | DRPW, MMIO Stale Data
[CVE-2022-29900](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-29900) | Arbitrary Speculative Code Execution with Return Instructions | Retbleed (AMD) [CVE-2022-29900](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-29900) | Arbitrary Speculative Code Execution with Return Instructions | Retbleed (AMD)
[CVE-2022-29901](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-29901) | Arbitrary Speculative Code Execution with Return Instructions | Retbleed (Intel), RSBA [CVE-2022-29901](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-29901) | Arbitrary Speculative Code Execution with Return Instructions | Retbleed (Intel), RSBA
[CVE-2022-40982](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-40982) | Gather Data Sampling | Downfall, GDS [CVE-2022-40982](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-40982) | Gather Data Sampling | Downfall, GDS
[CVE-2023-20569](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20569) | Return Address Security | Inception, SRSO [CVE-2023-20569](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20569) | Return Address Security | Inception, SRSO
[CVE-2023-20588](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20588) | AMD Division by Zero Speculative Data Leak | DIV0
[CVE-2023-20593](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20593) | Cross-Process Information Leak | Zenbleed [CVE-2023-20593](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20593) | Cross-Process Information Leak | Zenbleed
[CVE-2023-23583](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-23583) | Redundant Prefix Issue | Reptar [CVE-2023-23583](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-23583) | Redundant Prefix Issue | Reptar
[CVE-2023-28746](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-28746) | Register File Data Sampling | RFDS
[CVE-2024-28956](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-28956) | Indirect Target Selection | ITS [CVE-2024-28956](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-28956) | Indirect Target Selection | ITS
[CVE-2024-36350](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-36350) | Transient Scheduler Attack, Store Queue | TSA-SQ [CVE-2024-36350](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-36350) | Transient Scheduler Attack, Store Queue | TSA-SQ
[CVE-2024-36357](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-36357) | Transient Scheduler Attack, L1 | TSA-L1 [CVE-2024-36357](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-36357) | Transient Scheduler Attack, L1 | TSA-L1
@@ -56,12 +61,17 @@ CVE-2018-12207 (iTLB Multihit, No eXcuses) | ✅ | ✅ | ☠️ | ✅ | Hypervis
CVE-2019-11091 (MDSUM, RIDL) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update CVE-2019-11091 (MDSUM, RIDL) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2019-11135 (TAA, ZombieLoad V2) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update CVE-2019-11135 (TAA, ZombieLoad V2) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2020-0543 (SRBDS, CROSSTalk) | 💥 (2) | 💥 (2) | 💥 (2) | 💥 (2) | Microcode + kernel update CVE-2020-0543 (SRBDS, CROSSTalk) | 💥 (2) | 💥 (2) | 💥 (2) | 💥 (2) | Microcode + kernel update
CVE-2022-21123 (SBDR, MMIO Stale Data) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2022-21125 (SBDS, MMIO Stale Data) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2022-21166 (DRPW, MMIO Stale Data) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2022-29900 (Retbleed AMD) | 💥 | ✅ | 💥 | ✅ | Kernel update (+ microcode for IBPB) CVE-2022-29900 (Retbleed AMD) | 💥 | ✅ | 💥 | ✅ | Kernel update (+ microcode for IBPB)
CVE-2022-29901 (Retbleed Intel, RSBA) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update (eIBRS or IBRS) CVE-2022-29901 (Retbleed Intel, RSBA) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update (eIBRS or IBRS)
CVE-2022-40982 (Downfall, GDS) | 💥 | 💥 | 💥 | 💥 | Microcode update (or disable AVX) CVE-2022-40982 (Downfall, GDS) | 💥 | 💥 | 💥 | 💥 | Microcode update (or disable AVX)
CVE-2023-20569 (Inception, SRSO) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update CVE-2023-20569 (Inception, SRSO) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update
CVE-2023-20588 (DIV0) | 💥 | 💥 (1) | 💥 | 💥 (1) | Kernel update (+ disable SMT)
CVE-2023-20593 (Zenbleed) | 💥 | 💥 | 💥 | 💥 | Microcode update (or kernel workaround) CVE-2023-20593 (Zenbleed) | 💥 | 💥 | 💥 | 💥 | Microcode update (or kernel workaround)
CVE-2023-23583 (Reptar) | ☠️ | ☠️ | ☠️ | ☠️ | Microcode update CVE-2023-23583 (Reptar) | ☠️ | ☠️ | ☠️ | ☠️ | Microcode update
CVE-2023-28746 (RFDS) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update
CVE-2024-28956 (ITS) | 💥 | ✅ | 💥 (4) | ✅ | Microcode + kernel update CVE-2024-28956 (ITS) | 💥 | ✅ | 💥 (4) | ✅ | Microcode + kernel update
CVE-2024-36350 (TSA-SQ) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update CVE-2024-36350 (TSA-SQ) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2024-36357 (TSA-L1) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update CVE-2024-36357 (TSA-L1) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
@@ -141,6 +151,10 @@ On CPUs with Intel TSX, a transactional abort can leave data from the line fill
Certain special CPU instructions (RDRAND, RDSEED, EGETKEY) read data through a shared staging buffer that is accessible across all cores via speculative execution. An attacker running code on any core can observe the output of these instructions from a victim on a different core, including extracting cryptographic keys from SGX enclaves (a complete ECDSA key was demonstrated). This is notable as one of the first cross-core speculative execution attacks. Mitigation requires a microcode update that serializes access to the staging buffer, plus a kernel update to manage the mitigation. Performance impact is low, mainly affecting workloads that heavily use RDRAND/RDSEED. Certain special CPU instructions (RDRAND, RDSEED, EGETKEY) read data through a shared staging buffer that is accessible across all cores via speculative execution. An attacker running code on any core can observe the output of these instructions from a victim on a different core, including extracting cryptographic keys from SGX enclaves (a complete ECDSA key was demonstrated). This is notable as one of the first cross-core speculative execution attacks. Mitigation requires a microcode update that serializes access to the staging buffer, plus a kernel update to manage the mitigation. Performance impact is low, mainly affecting workloads that heavily use RDRAND/RDSEED.
**CVE-2022-21123, CVE-2022-21125, CVE-2022-21166 — Processor MMIO Stale Data (SBDR, SBDS, DRPW)**
A class of MMIO (Memory-Mapped I/O) vulnerabilities where stale data from CPU internal fill buffers can be inferred through side-channel attacks during MMIO operations. Three sub-vulnerabilities are covered: Shared Buffers Data Read (SBDR, CVE-2022-21123), Shared Buffers Data Sampling (SBDS, CVE-2022-21125), and Device Register Partial Write (DRPW, CVE-2022-21166). Affected Intel CPUs include Haswell through Rocket Lake server and client processors, plus Tremont Atom cores. Mitigation requires a microcode update providing the FB_CLEAR capability (VERW instruction clears fill buffers) plus a kernel update (Linux 5.19+) that invokes VERW at kernel/user transitions and VM entry/exit. When SMT is enabled, sibling threads can still exploit the vulnerability even with mitigations active. Performance impact is low, as the VERW mechanism is shared with the existing MDS mitigation.
**CVE-2022-29900 — Arbitrary Speculative Code Execution with Return Instructions (Retbleed AMD)** **CVE-2022-29900 — Arbitrary Speculative Code Execution with Return Instructions (Retbleed AMD)**
On AMD processors from families 0x15 through 0x17 (Bulldozer through Zen 2) and Hygon family 0x18, an attacker can exploit return instructions to redirect speculative execution and leak kernel memory, bypassing retpoline mitigations that were effective against Spectre V2. Unlike Spectre V2 which targets indirect jumps and calls, Retbleed specifically targets return instructions, which were previously considered safe. Mitigation requires a kernel update providing either the untrained return thunk (safe RET) or IBPB-on-entry mechanism, plus a microcode update providing IBPB support on Zen 1/2. On Zen 1/2, SMT should be disabled for full protection when using IBPB-based mitigation. Performance impact is medium. On AMD processors from families 0x15 through 0x17 (Bulldozer through Zen 2) and Hygon family 0x18, an attacker can exploit return instructions to redirect speculative execution and leak kernel memory, bypassing retpoline mitigations that were effective against Spectre V2. Unlike Spectre V2 which targets indirect jumps and calls, Retbleed specifically targets return instructions, which were previously considered safe. Mitigation requires a kernel update providing either the untrained return thunk (safe RET) or IBPB-on-entry mechanism, plus a microcode update providing IBPB support on Zen 1/2. On Zen 1/2, SMT should be disabled for full protection when using IBPB-based mitigation. Performance impact is medium.
@@ -157,6 +171,10 @@ The AVX GATHER instructions can leak data from previously used vector registers
On AMD Zen 1 through Zen 4 processors, an attacker can manipulate the return address predictor to redirect speculative execution on return instructions, leaking kernel memory. Mitigation requires both a kernel update (providing SRSO safe-return sequences or IBPB-on-entry) and a microcode update (providing SBPB on Zen 3/4, or IBPB support on Zen 1/2 — which additionally requires SMT to be disabled). Performance impact ranges from low to significant depending on the chosen mitigation and CPU generation. On AMD Zen 1 through Zen 4 processors, an attacker can manipulate the return address predictor to redirect speculative execution on return instructions, leaking kernel memory. Mitigation requires both a kernel update (providing SRSO safe-return sequences or IBPB-on-entry) and a microcode update (providing SBPB on Zen 3/4, or IBPB support on Zen 1/2 — which additionally requires SMT to be disabled). Performance impact ranges from low to significant depending on the chosen mitigation and CPU generation.
**CVE-2023-20588 — AMD Division by Zero Speculative Data Leak (DIV0)**
On AMD Zen 1 processors, a #DE (divide-by-zero) exception can leave stale quotient data from a previous division in the divider unit, observable by a subsequent division via speculative side channels. This can leak data across any privilege boundary, including between SMT sibling threads sharing the same physical core. Mitigation requires a kernel update (Linux 6.5+) that adds a dummy division (`amd_clear_divider()`) on every exit to userspace and before VMRUN, preventing stale data from persisting. No microcode update is needed. Disabling SMT provides additional protection because the kernel mitigation does not cover cross-SMT-thread leaks. Performance impact is negligible.
**CVE-2023-20593 — Cross-Process Information Leak (Zenbleed)** **CVE-2023-20593 — Cross-Process Information Leak (Zenbleed)**
A bug in AMD Zen 2 processors causes the VZEROUPPER instruction to incorrectly zero register files during speculative execution, leaving stale data from other processes observable in vector registers. This can leak data across any privilege boundary, including from the kernel and other processes, at rates up to 30 KB/s per core. Mitigation is available either through a microcode update that fixes the bug, or through a kernel workaround that sets the FP_BACKUP_FIX bit (bit 9) in the DE_CFG MSR, disabling the faulty optimization. Either approach alone is sufficient. Performance impact is negligible. A bug in AMD Zen 2 processors causes the VZEROUPPER instruction to incorrectly zero register files during speculative execution, leaving stale data from other processes observable in vector registers. This can leak data across any privilege boundary, including from the kernel and other processes, at rates up to 30 KB/s per core. Mitigation is available either through a microcode update that fixes the bug, or through a kernel workaround that sets the FP_BACKUP_FIX bit (bit 9) in the DE_CFG MSR, disabling the faulty optimization. Either approach alone is sufficient. Performance impact is negligible.
@@ -165,6 +183,10 @@ A bug in AMD Zen 2 processors causes the VZEROUPPER instruction to incorrectly z
A bug in Intel processors causes unexpected behavior when executing instructions with specific redundant REX prefixes. Depending on the circumstances, this can result in a system crash (MCE), unpredictable behavior, or potentially privilege escalation. Any software running on an affected CPU can trigger the bug. Mitigation requires a microcode update. Performance impact is low. A bug in Intel processors causes unexpected behavior when executing instructions with specific redundant REX prefixes. Depending on the circumstances, this can result in a system crash (MCE), unpredictable behavior, or potentially privilege escalation. Any software running on an affected CPU can trigger the bug. Mitigation requires a microcode update. Performance impact is low.
**CVE-2023-28746 — Register File Data Sampling (RFDS)**
On certain Intel Atom and hybrid processors (Goldmont, Goldmont Plus, Tremont, Gracemont, and the Atom cores of Alder Lake and Raptor Lake), the register file can retain stale data from previous operations that is accessible via speculative execution, allowing an attacker to infer data across privilege boundaries. Mitigation requires both a microcode update (providing the RFDS_CLEAR capability) and a kernel update (CONFIG_MITIGATION_RFDS, Linux 6.9+) that uses the VERW instruction to clear the register file on privilege transitions. CPUs with the RFDS_NO capability bit are not affected. Performance impact is low.
**CVE-2024-28956 — Indirect Target Selection (ITS)** **CVE-2024-28956 — Indirect Target Selection (ITS)**
On certain Intel processors (Skylake-X stepping 6+, Kaby Lake, Comet Lake, Ice Lake, Tiger Lake, Rocket Lake), an attacker can train the indirect branch predictor to speculatively execute a targeted gadget in the kernel, bypassing eIBRS protections. The Branch Target Buffer (BTB) uses only partial address bits to index indirect branch targets, allowing user-space code to influence kernel-space speculative execution. Some affected CPUs (Ice Lake, Tiger Lake, Rocket Lake) are only vulnerable to native user-to-kernel attacks, not guest-to-host (VMX) attacks. Mitigation requires both a microcode update (IPU 2025.1 / microcode-20250512+, which fixes IBPB to fully flush indirect branch predictions) and a kernel update (CONFIG_MITIGATION_ITS, Linux 6.15+) that aligns branch/return thunks or uses RSB stuffing. Performance impact is low. On certain Intel processors (Skylake-X stepping 6+, Kaby Lake, Comet Lake, Ice Lake, Tiger Lake, Rocket Lake), an attacker can train the indirect branch predictor to speculatively execute a targeted gadget in the kernel, bypassing eIBRS protections. The Branch Target Buffer (BTB) uses only partial address bits to index indirect branch targets, allowing user-space code to influence kernel-space speculative execution. Some affected CPUs (Ice Lake, Tiger Lake, Rocket Lake) are only vulnerable to native user-to-kernel attacks, not guest-to-host (VMX) attacks. Mitigation requires both a microcode update (IPU 2025.1 / microcode-20250512+, which fixes IBPB to fully flush indirect branch predictions) and a kernel update (CONFIG_MITIGATION_ITS, Linux 6.15+) that aligns branch/return thunks or uses RSB stuffing. Performance impact is low.
@@ -192,17 +214,17 @@ A race condition in the branch predictor update mechanism of Intel processors (C
Several transient execution CVEs are not covered by this tool, for various reasons (duplicates, only Several transient execution CVEs are not covered by this tool, for various reasons (duplicates, only
affecting non-supported hardware or OS, theoretical with no known exploitation, etc.). affecting non-supported hardware or OS, theoretical with no known exploitation, etc.).
The complete list along with the reason for each exclusion is available in the The complete list along with the reason for each exclusion is available in the
[UNSUPPORTED_CVE_LIST.md](https://github.com/speed47/spectre-meltdown-checker/blob/source/UNSUPPORTED_CVE_LIST.md) file. [UNSUPPORTED_CVE_LIST.md](doc/UNSUPPORTED_CVE_LIST.md) file.
## Scope ## Scope
Supported operating systems: Supported operating systems:
- Linux (all versions, flavors and distros) - Linux (all versions, flavors and distros)
- FreeBSD, NetBSD, DragonFlyBSD and derivatives (others BSDs are [not supported](FAQ.md#which-bsd-oses-are-supported)) - FreeBSD, NetBSD, DragonFlyBSD and derivatives (others BSDs are [not supported](doc/FAQ.md#which-bsd-oses-are-supported))
For Linux systems, the tool will detect mitigations, including backported non-vanilla patches, regardless of the advertised kernel version number and the distribution (such as Debian, Ubuntu, CentOS, RHEL, Fedora, openSUSE, Arch, ...), it also works if you've compiled your own kernel. More information [here](FAQ.md#how-does-this-script-work). For Linux systems, the tool will detect mitigations, including backported non-vanilla patches, regardless of the advertised kernel version number and the distribution (such as Debian, Ubuntu, CentOS, RHEL, Fedora, openSUSE, Arch, ...), it also works if you've compiled your own kernel. More information [here](doc/FAQ.md#how-does-this-script-work).
Other operating systems such as MacOS, Windows, ESXi, etc. [will never be supported](FAQ.md#why-is-my-os-not-supported). Other operating systems such as MacOS, Windows, ESXi, etc. [will never be supported](doc/FAQ.md#why-is-my-os-not-supported).
Supported architectures: Supported architectures:
- `x86` (32 bits) - `x86` (32 bits)
@@ -214,7 +236,29 @@ Supported architectures:
What is the purpose of this tool? Why was it written? How can it be useful to me? How does it work? What can I expect from it? What is the purpose of this tool? Why was it written? How can it be useful to me? How does it work? What can I expect from it?
All these questions (and more) have detailed answers in the [FAQ](FAQ.md), please have a look! All these questions (and more) have detailed answers in the [FAQ](doc/FAQ.md), please have a look!
## Operating modes
The script supports four operating modes, depending on whether you want to inspect the running kernel, a kernel image, the CPU hardware, or a combination.
| Mode | Flag | CPU hardware | Running kernel | Kernel image | Use case |
|------|------|:---:|:---:|:---:|----------|
| **Live** *(default)* | *(none)* | Yes | Yes | auto-detect | Day-to-day auditing of the current system |
| **No-runtime** | `--no-runtime` | Yes | No | required | Check a different kernel against this CPU (e.g. pre-deployment) |
| **No-hardware** | `--no-hw` | No | No | required | Pure static analysis of a kernel image for another system or architecture |
| **Hardware-only** | `--hw-only` | Yes | No | No | Quickly check CPU affectedness without inspecting any kernel |
In **Live** mode (the default), the script inspects both the CPU and the running kernel.
You can optionally pass `--kernel`, `--config`, or `--map` to point the script at files it couldn't auto-detect.
In **No-runtime** mode, the script still reads the local CPU (CPUID, MSRs, microcode) but skips all running-kernel artifacts (`/sys`, `/proc`, `dmesg`).
Use this when you have a kernel image from another system but want to evaluate it against the current CPU.
In **No-hardware** mode, both CPU inspection and running-kernel artifacts are skipped entirely.
This is useful for cross-architecture analysis, for example inspecting an ARM kernel image on an x86 workstation.
In **Hardware-only** mode, the script only reports CPU information and per-CVE hardware affectedness, without inspecting any kernel.
## Running the script ## Running the script
@@ -266,15 +310,6 @@ docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/m
## Example of script output ## Example of script output
- Intel Haswell CPU running under Ubuntu 16.04 LTS - AMD EPYC-Milan running under Debian Trixie
![haswell](https://user-images.githubusercontent.com/218502/108764885-6dcfc380-7553-11eb-81ac-4d19060a3acf.png)
- AMD Ryzen running under OpenSUSE Tumbleweed
![ryzen](https://user-images.githubusercontent.com/218502/108764896-70321d80-7553-11eb-9dd2-fad2a0a1a737.png)
- Batch mode (JSON flavor)
![batch](https://user-images.githubusercontent.com/218502/108764902-71634a80-7553-11eb-9678-fd304995fa64.png)
![alt text](https://raw.githubusercontent.com/speed47/spectre-meltdown-checker/refs/heads/test/img/smc_amd_epyc_milan.jpg)

View File

@@ -85,7 +85,7 @@ However I see a few reasons why this script might still be useful to you, and th
- The script can be pointed at a kernel image, and will deep dive into it, telling you if this kernel will mitigate vulnerabilities that might be present on your system. This is a good way to verify before booting a new kernel, that it'll mitigate the vulnerabilities you expect it to, especially if you modified a few config options around these topics. - The script can be pointed at a kernel image, and will deep dive into it, telling you if this kernel will mitigate vulnerabilities that might be present on your system. This is a good way to verify before booting a new kernel, that it'll mitigate the vulnerabilities you expect it to, especially if you modified a few config options around these topics.
- The script will also work regardless of the custom patches that might be integrated in the kernel you're running (or you're pointing it to, in offline mode), and completely ignores the advertised kernel version, to tell whether a given kernel mitigates vulnerabilities. This is especially useful for non-vanilla kernel, where patches might be backported, sometimes silently (this has already happened, too). - The script will also work regardless of the custom patches that might be integrated in the kernel you're running (or you're pointing it to, in no-runtime mode), and completely ignores the advertised kernel version, to tell whether a given kernel mitigates vulnerabilities. This is especially useful for non-vanilla kernel, where patches might be backported, sometimes silently (this has already happened, too).
- Educational purposes: the script gives interesting insights about a vulnerability, and how the different parts of the system work together to mitigate it. - Educational purposes: the script gives interesting insights about a vulnerability, and how the different parts of the system work together to mitigate it.

298
doc/UNSUPPORTED_CVE_LIST.md Normal file
View File

@@ -0,0 +1,298 @@
# Unsupported CVEs
This document lists transient execution CVEs that have been evaluated and determined to be **out of scope** for this tool. See the [Which rules are governing the support of a CVE in this tool?](dist/FAQ.md#which-rules-are-governing-the-support-of-a-cve-in-this-tool) section in the FAQ for the general policy.
CVEs are grouped by reason for exclusion:
- [Already covered by an existing CVE check](#already-covered-by-an-existing-cve-check) — subvariants or subsets whose mitigations are already detected under a parent CVE.
- [No kernel or microcode mitigations to check](#no-kernel-or-microcode-mitigations-to-check) — no fix has been issued, or the mitigation is not detectable by this tool.
- [Not a transient/speculative execution vulnerability](#not-a-transientspeculative-execution-vulnerability) — wrong vulnerability class entirely.
---
# Already covered by an existing CVE check
These CVEs are subvariants or subsets of vulnerabilities already implemented in the tool. Their mitigations are detected as part of the parent CVE's checks.
## CVE-2018-3693 — Bounds Check Bypass Store (Spectre v1.1)
- **Issue:** [#236](https://github.com/speed47/spectre-meltdown-checker/issues/236)
- **Red Hat advisory:** [Speculative Store Bypass / Bounds Check Bypass (CVE-2018-3693)](https://access.redhat.com/solutions/3523601)
- **CVSS:** 5.6 (Medium)
- **Covered by:** CVE-2017-5753 (Spectre V1)
A subvariant of Spectre V1 where speculative store operations can write beyond validated buffer boundaries before the bounds check resolves, allowing an attacker to alter cache state and leak information via side channels.
**Why out of scope:** The mitigations are identical to CVE-2017-5753 (Spectre V1): `lfence` instructions after bounds checks and `array_index_nospec()` barriers in kernel code. There is no separate sysfs entry, no new CPU feature flag, and no distinct microcode change. This tool's existing CVE-2017-5753 checks already detect these mitigations (`__user pointer sanitization`, `usercopy/swapgs barriers`), so CVE-2018-3693 is fully covered as part of Spectre V1.
## CVE-2018-15572 — SpectreRSB (Return Stack Buffer)
- **Issue:** [#224](https://github.com/speed47/spectre-meltdown-checker/issues/224)
- **Research paper:** [Spectre Returns! Speculation Attacks using the Return Stack Buffer (WOOT'18)](https://arxiv.org/abs/1807.07940)
- **Kernel fix:** [commit fdf82a7856b3](https://github.com/torvalds/linux/commit/fdf82a7856b32d905c39afc85e34364491e46346) (Linux 4.18.1)
- **CVSS:** 6.5 (Medium)
- **Covered by:** CVE-2017-5715 (Spectre V2)
The `spectre_v2_select_mitigation` function in the Linux kernel before 4.18.1 did not always fill the RSB upon a context switch, allowing userspace-to-userspace SpectreRSB attacks on Skylake+ CPUs where an empty RSB falls back to the BTB.
**Why out of scope:** This CVE is a Spectre V2 mitigation gap (missing RSB filling on context switch), not a distinct hardware vulnerability. It is already fully covered by this tool's CVE-2017-5715 (Spectre V2) checks, which detect whether the kernel performs RSB filling on CPUs vulnerable to RSB underflow (Skylake+ and RSBA-capable CPUs). A missing RSB fill is flagged as a caveat ("RSB filling missing on Skylake+") in the Spectre V2 verdict.
## CVE-2019-1125 — Spectre SWAPGS gadget
- **Issue:** [#301](https://github.com/speed47/spectre-meltdown-checker/issues/301)
- **Kernel fix:** [commit 18ec54fdd6d1](https://github.com/torvalds/linux/commit/18ec54fdd6d18d92025af097cd042a75cf0ea24c) (Linux 5.3)
- **CVSS:** 5.6 (Medium)
- **Covered by:** CVE-2017-5753 (Spectre V1)
A Spectre V1 subvariant where the `SWAPGS` instruction can be speculatively executed on x86 CPUs, allowing an attacker to leak kernel memory via a side channel on the GS segment base value.
**Why out of scope:** This is a Spectre V1 subvariant whose mitigation (SWAPGS barriers) shares the same sysfs entry as CVE-2017-5753. This tool's existing CVE-2017-5753 checks already detect SWAPGS barriers: a mitigated kernel reports `"Mitigation: usercopy/swapgs barriers and __user pointer sanitization"`, while a kernel lacking the fix reports `"Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers"`. CVE-2019-1125 is therefore fully covered as part of Spectre V1.
## CVE-2021-26341 — AMD Straight-Line Speculation (direct branches)
- **Bulletin:** [AMD-SB-1026](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-1026.html)
- **Affected CPUs:** AMD Zen 1, Zen 2
- **CVSS:** 6.5 (Medium)
- **Covered by:** CVE-0000-0001 (SLS supplementary check)
AMD Zen 1/Zen 2 CPUs may transiently execute instructions beyond unconditional direct branches (JMP, CALL), potentially allowing information disclosure via side channels.
**Why out of scope:** This is the AMD-specific direct-branch subset of the broader Straight-Line Speculation (SLS) class. The kernel mitigates it via `CONFIG_MITIGATION_SLS` (formerly `CONFIG_SLS`), which enables the GCC flag `-mharden-sls=all` to insert INT3 after unconditional control flow instructions. Since this is a compile-time-only mitigation with no sysfs interface, no MSR, and no per-CVE CPU feature flag, it cannot be checked using the standard CVE framework. A supplementary SLS check is available via `--extra` mode, which covers this CVE's mitigation as well.
## CVE-2020-13844 — ARM Straight-Line Speculation
- **Advisory:** [ARM Developer Security Update (June 2020)](https://developer.arm.com/Arm%20Security%20Center/Speculative%20Processor%20Vulnerability)
- **Affected CPUs:** Cortex-A32, A34, A35, A53, A57, A72, A73, and broadly all speculative Armv8-A cores
- **CVSS:** 5.5 (Medium)
- **Covered by:** CVE-0000-0001 (SLS supplementary check)
ARM processors may speculatively execute instructions past unconditional control flow changes (RET, BR, BLR). GCC and Clang support `-mharden-sls=all` for aarch64, but the Linux kernel never merged the patches to enable it: a `CONFIG_HARDEN_SLS_ALL` series was submitted in 2021 but rejected upstream.
**Why out of scope:** This is the ARM-specific subset of the broader Straight-Line Speculation (SLS) class. The supplementary SLS check available via `--extra` mode detects affected ARM CPU models and reports that no kernel mitigation is currently available.
## CVE-2024-2201 — Native BHI (Branch History Injection without eBPF)
- **Issue:** [#491](https://github.com/speed47/spectre-meltdown-checker/issues/491)
- **Research:** [InSpectre Gadget / Native BHI (VUSec)](https://www.vusec.net/projects/native-bhi/)
- **Intel advisory:** [Branch History Injection (Intel)](https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html)
- **Affected CPUs:** Intel CPUs with eIBRS (Ice Lake+, 10th gen+, and virtualized Intel guests)
- **CVSS:** 4.7 (Medium)
- **Covered by:** CVE-2017-5715 (Spectre V2)
VUSec researchers demonstrated that the original BHI mitigation (disabling unprivileged eBPF) was insufficient: 1,511 native kernel gadgets exist that allow exploiting Branch History Injection without eBPF, leaking arbitrary kernel memory at ~3.5 kB/sec on Intel CPUs.
**Why out of scope:** CVE-2024-2201 is not a new hardware vulnerability — it is the same BHI hardware bug as CVE-2022-0002, but proves that eBPF restriction alone was never sufficient. The required mitigations are identical: `BHI_DIS_S` hardware control (MSR `IA32_SPEC_CTRL` bit 10), software BHB clearing loop at syscall entry and VM exit, or retpoline with RRSBA disabled. These are all already detected by this tool's CVE-2017-5715 (Spectre V2) checks, which parse the `BHI:` suffix from `/sys/devices/system/cpu/vulnerabilities/spectre_v2` and check for `CONFIG_MITIGATION_SPECTRE_BHI` in no-runtime mode. No new sysfs entry, MSR, kernel config option, or boot parameter was introduced for this CVE.
## CVE-2020-0549 — L1D Eviction Sampling (CacheOut)
- **Issue:** [#341](https://github.com/speed47/spectre-meltdown-checker/issues/341)
- **Advisory:** [INTEL-SA-00329](https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/l1d-eviction-sampling.html)
- **Affected CPUs:** Intel Skylake through 10th gen (Tiger Lake+ not affected)
- **CVSS:** 6.5 (Medium)
- **Covered by:** CVE-2018-12126 / CVE-2018-12127 / CVE-2018-12130 / CVE-2019-11091 (MDS) and CVE-2018-3646 (L1TF)
An Intel-specific data leakage vulnerability where L1 data cache evictions can be exploited in combination with MDS or TAA side channels to leak data across security boundaries.
**Why out of scope:** The June 2020 microcode update that addresses this CVE does not introduce any new MSR bits or CPUID flags — it reuses the existing MD_CLEAR (`CPUID.7.0:EDX[10]`) and L1D_FLUSH (`MSR_IA32_FLUSH_CMD`, 0x10B) infrastructure already deployed for MDS and L1TF. The Linux kernel has no dedicated sysfs entry in `/sys/devices/system/cpu/vulnerabilities/` for this CVE; instead, it provides an opt-in per-task L1D flush via `prctl(PR_SPEC_L1D_FLUSH)` and the `l1d_flush=on` boot parameter, which piggyback on the same L1D flush mechanism checked by the existing L1TF and MDS vulnerability modules. In practice, a system with up-to-date microcode and MDS/L1TF mitigations in place is already protected against L1D Eviction Sampling.
## CVE-2025-20623 — Shared Microarchitectural Predictor State (10th Gen Intel)
- **Advisory:** [INTEL-SA-01247](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-01247.html)
- **Affected CPUs:** Intel 10th Generation Core Processors only
- **CVSS:** 5.6 (Medium)
- **Covered by:** CVE-2024-45332 (BPI)
Shared microarchitectural predictor state on 10th generation Intel CPUs may allow information disclosure.
**Why out of scope:** Very narrow scope (single CPU generation). Mitigated by the same microcode update as CVE-2024-45332 (BPI) and handled through the existing Spectre V2 framework. No dedicated sysfs entry or kernel mitigation beyond what BPI already provides.
## CVE-2025-24495 — Lion Cove BPU Initialization
- **Advisory:** [INTEL-SA-01322](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-01322.html)
- **Research:** [Training Solo (VUSec)](https://www.vusec.net/projects/training-solo/)
- **Affected CPUs:** Intel Core Ultra with Lion Cove core only (Lunar Lake, Arrow Lake)
- **CVSS:** 6.8 (Medium, CVSS v4)
- **Covered by:** CVE-2024-28956 (ITS)
A branch predictor initialization issue specific to Intel's Lion Cove microarchitecture, discovered as part of the "Training Solo" research.
**Why out of scope:** This is a subset of the ITS (Indirect Target Selection) vulnerability (CVE-2024-28956). It shares the same sysfs entry (`/sys/devices/system/cpu/vulnerabilities/indirect_target_selection`) and kernel mitigation framework. Since ITS (CVE-2024-28956) is implemented in this tool, Lion Cove BPU is already covered automatically.
---
# No kernel or microcode mitigations to check
These CVEs are real vulnerabilities, but no kernel or microcode fix has been issued, the mitigation is delegated to individual software, or the fix is not detectable by this tool.
## CVE-2018-9056 — BranchScope
- **Issue:** [#169](https://github.com/speed47/spectre-meltdown-checker/issues/169)
- **Research paper:** [BranchScope (ASPLOS 2018)](http://www.cs.ucr.edu/~nael/pubs/asplos18.pdf)
- **Red Hat bug:** [#1561794](https://bugzilla.redhat.com/show_bug.cgi?id=1561794)
- **CVSS:** 5.6 (Medium)
A speculative execution attack exploiting the directional branch predictor, allowing an attacker to infer data by manipulating the shared branch prediction state (pattern history table). Initially demonstrated on Intel processors.
**Why out of scope:** No kernel or microcode mitigations have been issued. Red Hat closed their tracking bug as "CLOSED CANTFIX", concluding that "this is a hardware processor issue, not a Linux kernel flaw" and that "it is specific to a target software which uses sensitive information in branching expressions." The mitigation responsibility falls on individual software to avoid using sensitive data in conditional branches, which is out of the scope of this tool.
## CVE-2019-15902 — Spectre V1 backport regression
- **Issue:** [#304](https://github.com/speed47/spectre-meltdown-checker/issues/304)
- **CVSS:** 5.6 (Medium)
A backporting mistake in Linux stable/longterm kernel versions (4.4.x through 4.4.190, 4.9.x through 4.9.190, 4.14.x through 4.14.141, 4.19.x through 4.19.69, and 5.2.x through 5.2.11) swapped two code lines in `ptrace_get_debugreg()`, placing the `array_index_nospec()` call after the array access instead of before, reintroducing a Spectre V1 vulnerability.
**Why out of scope:** This is a kernel bug (bad backport), not a hardware vulnerability. The flawed code is not detectable on a running kernel without hardcoding kernel version ranges, which is against this tool's design principles. As the tool author noted: "it's going to be almost impossible to detect it on a running kernel."
## CVE-2020-12965 — Transient Execution of Non-Canonical Accesses (SLAM)
- **Issue:** [#478](https://github.com/speed47/spectre-meltdown-checker/issues/478)
- **Bulletin:** [AMD-SB-1010](https://www.amd.com/en/corporate/product-security/bulletin/amd-sb-1010)
- **Research paper:** [SLAM (VUSec)](https://www.vusec.net/projects/slam/)
- **CVSS:** 7.5 (High)
AMD CPUs may transiently execute non-canonical loads and stores using only the lower 48 address bits, potentially resulting in data leakage. The SLAM research (2023) demonstrated that this could be exploited on existing AMD Zen+/Zen2 CPUs and could also affect future CPUs with Intel LAM, AMD UAI, or ARM TBI features.
**Why out of scope:** AMD's mitigation guidance is for software vendors to "analyze their code for any potential vulnerabilities" and insert LFENCE or use existing speculation mitigation techniques in their own code. No microcode or kernel-level mitigations have been issued. The responsibility falls on individual software, not on the kernel or firmware, leaving nothing for this script to check.
## CVE-2020-24511 — Domain-Type Confusion (IBRS Scope)
- **Issue:** [#409](https://github.com/speed47/spectre-meltdown-checker/issues/409)
- **Advisory:** [INTEL-SA-00464](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00464.html)
- **Affected CPUs:** Intel Skylake through Comet Lake (different steppings; see advisory for details)
- **CVSS:** 6.5 (Medium)
Improper isolation of shared resources in some Intel processors allows an authenticated user to potentially enable information disclosure via local access. Specifically, the Indirect Branch Restricted Speculation (IBRS) mitigation may not be fully applied after certain privilege-level transitions, allowing residual branch predictions to cross security boundaries.
**Why out of scope:** The mitigation is exclusively a microcode update (released June 2021) with no corresponding Linux kernel sysfs entry in `/sys/devices/system/cpu/vulnerabilities/`, no new CPUID bit, no new MSR, and no kernel configuration option. The only way to detect the fix would be to maintain a per-CPU-stepping minimum microcode version lookup table, which is brittle and high-maintenance. Additionally, Intel dropped microcode support for Sandy Bridge and Ivy Bridge in the same timeframe, leaving those generations permanently unpatched with no mitigation path available.
## CVE-2020-24512 — Observable Timing Discrepancy (Trivial Data Value)
- **Issue:** [#409](https://github.com/speed47/spectre-meltdown-checker/issues/409)
- **Advisory:** [INTEL-SA-00464](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00464.html)
- **Affected CPUs:** Intel Skylake through Tiger Lake (broad scope; see advisory for details)
- **CVSS:** 2.8 (Low)
Observable timing discrepancy in some Intel processors allows an authenticated user to potentially enable information disclosure via local access. Certain cache optimizations treat "trivial data value" cache lines (e.g., all-zero lines) differently from non-trivial lines, creating a timing side channel that can distinguish memory content patterns.
**Why out of scope:** Like CVE-2020-24511, this is a microcode-only fix with no Linux kernel sysfs entry, no CPUID bit, no MSR, and no kernel configuration option. Detection would require a per-CPU-stepping microcode version lookup table. The vulnerability has low severity (CVSS 2.8) and practical exploitation is limited. Intel dropped microcode support for Sandy Bridge and Ivy Bridge, leaving those generations permanently vulnerable.
## CVE-2021-26318 — AMD Prefetch Attacks through Power and Time
- **Issue:** [#412](https://github.com/speed47/spectre-meltdown-checker/issues/412)
- **Bulletin:** [AMD-SB-1017](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-1017.html)
- **Research paper:** [AMD Prefetch Attacks through Power and Time (USENIX Security '22)](https://www.usenix.org/conference/usenixsecurity22/presentation/lipp)
- **CVSS:** 5.5 (Medium)
The x86 PREFETCH instruction on AMD CPUs leaks timing and power information, enabling a microarchitectural KASLR bypass from unprivileged userspace. The researchers demonstrated kernel address space layout recovery and kernel memory leakage at ~52 B/s using Spectre gadgets.
**Why out of scope:** AMD acknowledged the research but explicitly stated they are "not recommending any mitigations at this time," as the attack leaks kernel address layout information (KASLR bypass) but does not directly leak kernel data across address space boundaries. KPTI was never enabled on AMD by default in the Linux kernel as a result. No microcode, kernel, or sysfs mitigations have been issued, leaving nothing for this script to check.
## CVE-2024-7881 — ARM Prefetcher Privilege Escalation
- **Affected CPUs:** Specific ARM cores only
- **CVSS:** 5.1 (Medium)
The prefetch engine on certain ARM cores can fetch data from privileged memory locations. Mitigation is disabling the affected prefetcher via the `CPUACTLR6_EL1[41]` register bit.
**Why out of scope:** ARM-specific with very narrow scope and no Linux sysfs integration. The mitigation is a per-core register tweak, not a kernel or microcode update detectable by this tool.
## CVE-2024-36348 — AMD Transient Scheduler Attack (UMIP bypass)
- **Bulletin:** [AMD-SB-7029](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7029.html)
- **CVSS:** 3.8 (Low)
A transient execution vulnerability in some AMD processors may allow a user process to speculatively infer CPU configuration registers even when UMIP is enabled.
**Why out of scope:** AMD has determined that "leakage of CPU Configuration does not result in leakage of sensitive information" and has marked this CVE as "No fix planned" across all affected product lines. No microcode or kernel mitigations have been issued, leaving nothing for this script to check.
## CVE-2024-36349 — AMD Transient Scheduler Attack (TSC_AUX leak)
- **Bulletin:** [AMD-SB-7029](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7029.html)
- **CVSS:** 3.8 (Low)
A transient execution vulnerability in some AMD processors may allow a user process to infer TSC_AUX even when such a read is disabled.
**Why out of scope:** AMD has determined that "leakage of TSC_AUX does not result in leakage of sensitive information" and has marked this CVE as "No fix planned" across all affected product lines. No microcode or kernel mitigations have been issued, leaving nothing for this script to check.
## No CVE — BlindSide (Speculative Probing)
- **Issue:** [#374](https://github.com/speed47/spectre-meltdown-checker/issues/374)
- **Research paper:** [Speculative Probing: Hacking Blind in the Spectre Era (VUSec, ACM CCS 2020)](https://www.vusec.net/projects/blindside/)
- **Red Hat advisory:** [Article 5394291](https://access.redhat.com/articles/5394291)
- **Affected CPUs:** All CPUs vulnerable to Spectre V2 (BTB-based speculative execution)
An attack technique that combines a pre-existing kernel memory corruption bug (e.g., a heap buffer overflow) with speculative execution to perform "Speculative BROP" (Blind Return-Oriented Programming). Instead of crashing the system when probing invalid addresses, BlindSide performs the probing speculatively: faults are suppressed in the speculative domain, and information is leaked via cache timing side channels. This allows an attacker to silently derandomize kernel memory layout and bypass KASLR/FGKASLR without triggering any fault.
**Why out of scope:** BlindSide is an exploitation technique, not a discrete hardware vulnerability: no CVE was assigned. Red Hat explicitly states it is "not a new flaw, but a new attack." It requires a pre-existing kernel memory corruption bug as a prerequisite, and the speculative execution aspect leverages the same BTB behavior as Spectre V2 (CVE-2017-5715). No dedicated microcode update, kernel config, MSR, CPUID bit, or sysfs entry exists for BlindSide. The closest hardware mitigations (IBPB, IBRS, STIBP, Retpoline) are already covered by this tool's Spectre V2 checks.
## No CVE — TLBleed (TLB side-channel)
- **Issue:** [#231](https://github.com/speed47/spectre-meltdown-checker/issues/231)
- **Research paper:** [Defeating Cache Side-channel Protections with TLB Attacks (VUSec, USENIX Security '18)](https://www.vusec.net/projects/tlbleed/)
- **Red Hat blog:** [Temporal side-channels and you: Understanding TLBleed](https://www.redhat.com/en/blog/temporal-side-channels-and-you-understanding-tlbleed)
- **Affected CPUs:** Intel CPUs with Hyper-Threading (demonstrated on Skylake, Coffee Lake, Broadwell Xeon)
A timing side-channel attack exploiting the shared Translation Lookaside Buffer (TLB) on Intel hyperthreaded CPUs. By using machine learning to analyze TLB hit/miss timing patterns, an attacker co-located on the same physical core can extract cryptographic keys (demonstrated with 99.8% success rate on a 256-bit EdDSA key). OpenBSD disabled Hyper-Threading by default in response.
**Why out of scope:** No CVE was ever assigned — Intel explicitly declined to request one. Intel stated the attack is "not related to Spectre or Meltdown" and has no plans to issue a microcode fix, pointing to existing constant-time coding practices in cryptographic software as the appropriate defense. No Linux kernel mitigation was ever merged. Red Hat's guidance was limited to operational advice (disable SMT, use CPU pinning) rather than a software fix. The only OS-level response was OpenBSD disabling Hyper-Threading by default. With no CVE, no microcode update, and no kernel mitigation, there is nothing for this script to check.
---
# Not a transient/speculative execution vulnerability
These are hardware flaws but not side-channel or speculative execution issues. They fall outside the vulnerability class this tool is designed to detect.
## CVE-2019-11157 — Plundervolt (VoltJockey)
- **Issue:** [#335](https://github.com/speed47/spectre-meltdown-checker/issues/335)
- **Advisory:** [INTEL-SA-00289](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00289.html)
- **Research:** [Plundervolt (plundervolt.com)](https://plundervolt.com/)
- **Affected CPUs:** Intel Core 6th10th gen (Skylake through Comet Lake) with SGX
- **CVSS:** 7.1 (High)
A voltage fault injection attack where a privileged attacker (ring 0) uses the software-accessible voltage scaling interface to undervolt the CPU during SGX enclave computations, inducing predictable bit flips that compromise enclave integrity and confidentiality. Intel's microcode fix locks down the voltage/frequency scaling MSRs to prevent software-initiated undervolting.
**Why out of scope:** Not a transient or speculative execution vulnerability — this is a fault injection attack exploiting voltage manipulation, with no side-channel or speculative execution component. It requires ring 0 access and targets SGX enclaves specifically. While Intel issued a microcode update that locks voltage controls, there is no Linux kernel sysfs entry, no CPUID flag, and no kernel-side mitigation to detect. The fix is purely a microcode-level lockdown of voltage scaling registers, which is not exposed in any standard interface this tool can query.
## CVE-2020-8694 / CVE-2020-8695 — Platypus (RAPL Power Side Channel)
- **Issue:** [#384](https://github.com/speed47/spectre-meltdown-checker/issues/384)
- **Advisory:** [INTEL-SA-00389](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00389.html)
- **Research:** [PLATYPUS (platypusattack.com)](https://platypusattack.com/)
- **Affected CPUs:** Intel Core (Sandy Bridge+), Intel Xeon (Sandy Bridge-EP+)
- **CVSS:** 5.6 (Medium) / 6.5 (Medium)
A software-based power side-channel attack exploiting Intel's Running Average Power Limit (RAPL) interface. By monitoring energy consumption reported through the `powercap` sysfs interface or the `MSR_RAPL_POWER_UNIT` / `MSR_PKG_ENERGY_STATUS` MSRs, an unprivileged attacker can statistically distinguish instructions and operands, recover AES-NI keys from SGX enclaves, and break kernel ASLR.
**Why out of scope:** Not a transient or speculative execution vulnerability — this is a power analysis side-channel attack with no speculative execution component. The mitigations (microcode update restricting RAPL energy reporting to privileged access, and kernel restricting the `powercap` sysfs interface) are not exposed via `/sys/devices/system/cpu/vulnerabilities/`. There is no dedicated sysfs vulnerability entry, no CPUID flag, and no kernel configuration option for this tool to check.
## CVE-2023-31315 — SinkClose (AMD SMM Lock Bypass)
- **Issue:** [#499](https://github.com/speed47/spectre-meltdown-checker/issues/499)
- **Bulletin:** [AMD-SB-7014](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7014.html)
- **Research:** [AMD SinkClose (IOActive, DEF CON 32)](https://www.ioactive.com/resources/amd-sinkclose-universal-ring-2-privilege-escalation)
- **Affected CPUs:** AMD Zen 15 (EPYC, Ryzen, Threadripper, Embedded)
- **CVSS:** 7.5 (High)
Improper validation in a model-specific register (MSR) allows a program with ring 0 (kernel) access to modify System Management Mode (SMM) configuration while SMI lock is enabled, escalating privileges from ring 0 to ring -2 (SMM). AMD provides two mitigation paths: BIOS/AGESA firmware updates (all product lines) and hot-loadable microcode updates (EPYC server processors only).
**Why out of scope:** Not a transient or speculative execution vulnerability — this is a privilege escalation via MSR manipulation, with no side-channel component. It requires ring 0 access as a prerequisite, fundamentally different from Spectre/Meltdown-class attacks where unprivileged code can leak data across privilege boundaries. There is no Linux kernel sysfs entry and no kernel-side mitigation. Although AMD provides hot-loadable microcode for some EPYC processors, the client and embedded product lines are mitigated only through BIOS firmware updates, which this tool cannot detect.
## CVE-2024-56161 — EntrySign (AMD Microcode Signature Bypass)
- **Affected CPUs:** AMD Zen 1-5
- **CVSS:** 7.2 (High)
A weakness in AMD's microcode signature verification (AES-CMAC hash) allows loading arbitrary unsigned microcode with administrator privileges.
**Why out of scope:** This is a microcode integrity/authentication issue, not a speculative execution vulnerability. It does not involve transient execution side channels and is outside the scope of this tool.
## CVE-2025-29943 — StackWarp (AMD SEV-SNP)
- **Affected CPUs:** AMD Zen 1-5
- **CVSS:** Low
Exploits a synchronization failure in the AMD stack engine via an undocumented MSR bit, targeting AMD SEV-SNP confidential VMs. Requires hypervisor-level (ring 0) access.
**Why out of scope:** Not a transient/speculative execution side channel. This is an architectural attack on AMD SEV-SNP confidential computing that requires hypervisor access, which is outside the threat model of this tool.

391
doc/batch_json.md Normal file
View File

@@ -0,0 +1,391 @@
# JSON Output Format
`--batch json` emits a single, self-contained JSON object that describes the
scan environment and the result of every CVE check. You can feed it to your
monitoring system, to a SIEM, to a time-series database, you name it.
```sh
sudo ./spectre-meltdown-checker.sh --batch json | jq .
```
## Top-level schema
```
{
"meta": { ... }, // Run metadata and flags
"system": { ... }, // Kernel and host context
"cpu": { ... }, // CPU hardware identification
"cpu_microcode": { ... }, // Microcode version and status
"vulnerabilities": [ ... ] // One object per checked CVE
}
```
`format_version` in `meta` is an integer that will be incremented on
backward-incompatible schema changes. The current value is **1**.
## Section reference
### `meta`
Run metadata. Always present.
| Field | Type | Values | Meaning |
|---|---|---|---|
| `script_version` | string | e.g. `"25.30.0250400123"` | Script version |
| `format_version` | integer | `1` | JSON schema version; incremented on breaking changes |
| `timestamp` | string | ISO 8601 UTC, e.g. `"2025-04-07T12:00:00Z"` | When the scan started |
| `os` | string | e.g. `"Linux"`, `"FreeBSD"` | Output of `uname -s` |
| `mode` | string | `"live"` / `"no-runtime"` / `"no-hw"` / `"hw-only"` | Operating mode (see [modes](README.md#operating-modes)) |
| `run_as_root` | boolean | | Whether the script ran as root. Non-root scans skip MSR reads and may miss mitigations |
| `reduced_accuracy` | boolean | | Kernel image, config, or System.map was missing; some checks fall back to weaker heuristics |
| `paranoid` | boolean | | `--paranoid` mode: stricter criteria (e.g. requires SMT disabled, IBPB always-on) |
| `sysfs_only` | boolean | | `--sysfs-only`: only the kernel's own sysfs report was used, not independent detection |
| `extra` | boolean | | `--extra`: additional experimental checks were enabled |
| `mocked` | boolean | | One or more CPU values were overridden for testing. Results do **not** reflect the real system |
**Example:**
```json
"meta": {
"script_version": "25.30.025040123",
"format_version": 1,
"timestamp": "2025-04-07T12:00:00Z",
"os": "Linux",
"mode": "live",
"run_as_root": true,
"reduced_accuracy": false,
"paranoid": false,
"sysfs_only": false,
"extra": false,
"mocked": false
}
```
**Important flags for fleet operators:**
- `run_as_root: false` means the scan was incomplete. Treat results as lower
confidence. Alert separately: results may be missing or wrong.
- `sysfs_only: true` means the script trusted the kernel's self-report without
independent verification. Some older kernels misreport their mitigation
status. Do not use `--sysfs-only` for production fleet monitoring.
- `paranoid: true` raises the bar: only compare `vulnerable` counts across
hosts with the same `paranoid` value.
- `mocked: true` must never appear on a production host. If it does, every
downstream result is fabricated.
---
### `system`
Kernel and host environment. Always present.
| Field | Type | Values | Meaning |
|---|---|---|---|
| `kernel_release` | string \| null | e.g. `"6.1.0-21-amd64"` | Output of `uname -r` (null in no-runtime, no-hw, and hw-only modes) |
| `kernel_version` | string \| null | e.g. `"#1 SMP Debian …"` | Output of `uname -v` (null in no-runtime, no-hw, and hw-only modes) |
| `kernel_arch` | string \| null | e.g. `"x86_64"` | Output of `uname -m` (null in no-runtime, no-hw, and hw-only modes) |
| `kernel_image` | string \| null | e.g. `"/boot/vmlinuz-6.1.0-21-amd64"` | Path passed via `--kernel`, or null if not specified |
| `kernel_config` | string \| null | | Path passed via `--config`, or null |
| `kernel_version_string` | string \| null | | Kernel version banner extracted from the image |
| `kernel_cmdline` | string \| null | | Kernel command line from `/proc/cmdline` (live mode) or the image |
| `cpu_count` | integer \| null | | Number of logical CPUs detected |
| `smt_enabled` | boolean \| null | | Whether SMT (HyperThreading) is currently active; null if undeterminable |
| `hypervisor_host` | boolean \| null | | Whether this machine is detected as a VM host (running KVM, Xen, VMware, etc.) |
| `hypervisor_host_reason` | string \| null | | Human-readable explanation of why `hypervisor_host` was set |
**`hypervisor_host`** materially changes the risk profile of several CVEs.
L1TF (CVE-2018-3646) and MDS (CVE-2018-12126/12130/12127) are significantly
more severe on hypervisor hosts because they can be exploited across VM
boundaries by a malicious guest. Prioritise remediation where
`hypervisor_host: true`.
---
### `cpu`
CPU hardware identification. `null` when `--no-hw` is active.
The object uses `arch` as a discriminator: `"x86"` for Intel/AMD/Hygon CPUs,
`"arm"` for ARM/Cavium/Phytium. Arch-specific fields live under a matching
sub-object (`cpu.x86` or `cpu.arm`), so consumers never see irrelevant null
fields from the other architecture.
#### Common fields
| Field | Type | Values | Meaning |
|---|---|---|---|
| `arch` | string | `"x86"` / `"arm"` | CPU architecture family; determines which sub-object is present |
| `vendor` | string \| null | e.g. `"GenuineIntel"`, `"ARM"` | CPU vendor string |
| `friendly_name` | string \| null | e.g. `"Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz"` | Human-readable CPU model |
#### `cpu.x86` (present when `arch == "x86"`)
| Field | Type | Values | Meaning |
|---|---|---|---|
| `family` | integer \| null | | CPU family number |
| `model` | integer \| null | | CPU model number |
| `stepping` | integer \| null | | CPU stepping number |
| `cpuid` | string \| null | hex, e.g. `"0x000906ed"` | Full CPUID leaf 1 EAX value |
| `platform_id` | integer \| null | | Intel platform ID (from MSR 0x17); null on AMD |
| `hybrid` | boolean \| null | | Whether this is a hybrid CPU (P-cores + E-cores, e.g. Alder Lake) |
| `codename` | string \| null | e.g. `"Coffee Lake"` | Intel CPU codename; null on AMD |
| `capabilities` | object | | CPU feature flags (see below) |
#### `cpu.arm` (present when `arch == "arm"`)
| Field | Type | Values | Meaning |
|---|---|---|---|
| `part_list` | string \| null | e.g. `"0xd0b 0xd05"` | Space-separated ARM part numbers across cores (big.LITTLE may have several) |
| `arch_list` | string \| null | e.g. `"8 8"` | Space-separated ARM architecture levels across cores |
| `capabilities` | object | | ARM-specific capability flags (currently empty; reserved for future use) |
#### `cpu.x86.capabilities`
Each capability is a **tri-state**: `true` (present), `false` (absent), or
`null` (not applicable or could not be read, e.g. when not root or on AMD for
Intel-specific features).
| Capability | Meaning |
|---|---|
| `spec_ctrl` | SPEC_CTRL MSR (Intel: ibrs + ibpb via WRMSR; required for many mitigations) |
| `ibrs` | Indirect Branch Restricted Speculation |
| `ibpb` | Indirect Branch Prediction Barrier |
| `ibpb_ret` | IBPB on return (enhanced form) |
| `stibp` | Single Thread Indirect Branch Predictors |
| `ssbd` | Speculative Store Bypass Disable |
| `l1d_flush` | L1D cache flush instruction |
| `md_clear` | VERW clears CPU buffers (MDS mitigation) |
| `arch_capabilities` | IA32_ARCH_CAPABILITIES MSR is present |
| `rdcl_no` | Not susceptible to RDCL (Meltdown-like attacks) |
| `ibrs_all` | Enhanced IBRS always-on mode supported |
| `rsba` | RSB may use return predictions from outside the RSB |
| `l1dflush_no` | Not susceptible to L1D flush side-channel |
| `ssb_no` | Not susceptible to Speculative Store Bypass |
| `mds_no` | Not susceptible to MDS |
| `taa_no` | Not susceptible to TSX Asynchronous Abort |
| `pschange_msc_no` | Page-size-change MSC not susceptible |
| `tsx_ctrl_msr` | TSX_CTRL MSR is present |
| `tsx_ctrl_rtm_disable` | RTM disabled via TSX_CTRL |
| `tsx_ctrl_cpuid_clear` | CPUID HLE/RTM bits cleared via TSX_CTRL |
| `gds_ctrl` | GDS_CTRL MSR present (GDS mitigation control) |
| `gds_no` | Not susceptible to Gather Data Sampling |
| `gds_mitg_dis` | GDS mitigation disabled |
| `gds_mitg_lock` | GDS mitigation locked |
| `rfds_no` | Not susceptible to Register File Data Sampling |
| `rfds_clear` | VERW clears register file stale data |
| `its_no` | Not susceptible to Indirect Target Selection |
| `sbdr_ssdp_no` | Not susceptible to SBDR/SSDP |
| `fbsdp_no` | Not susceptible to FBSDP |
| `psdp_no` | Not susceptible to PSDP |
| `fb_clear` | Fill buffer cleared on idle/C6 |
| `rtm` | Restricted Transactional Memory (TSX RTM) present |
| `tsx_force_abort` | TSX_FORCE_ABORT MSR present |
| `tsx_force_abort_rtm_disable` | RTM disabled via TSX_FORCE_ABORT |
| `tsx_force_abort_cpuid_clear` | CPUID RTM cleared via TSX_FORCE_ABORT |
| `sgx` | Software Guard Extensions present |
| `srbds` | SRBDS affected |
| `srbds_on` | SRBDS mitigation active |
| `amd_ssb_no` | AMD: not susceptible to Speculative Store Bypass |
| `hygon_ssb_no` | Hygon: not susceptible to Speculative Store Bypass |
| `ipred` | Indirect Predictor Barrier support |
| `rrsba` | Restricted RSB Alternate (Intel Retbleed mitigation) |
| `bhi` | Branch History Injection mitigation support |
| `tsa_sq_no` | Not susceptible to TSA-SQ |
| `tsa_l1_no` | Not susceptible to TSA-L1 |
| `verw_clear` | VERW clears CPU buffers |
| `autoibrs` | AMD AutoIBRS (equivalent to enhanced IBRS on Intel) |
| `sbpb` | Selective Branch Predictor Barrier (AMD Inception mitigation) |
| `avx2` | AVX2 supported (relevant to Downfall / GDS) |
| `avx512` | AVX-512 supported (relevant to Downfall / GDS) |
---
### `cpu_microcode`
Microcode version and status. `null` under the same conditions as `cpu`.
| Field | Type | Values | Meaning |
|---|---|---|---|
| `installed_version` | string \| null | hex, e.g. `"0xf4"` | Currently running microcode revision |
| `latest_version` | string \| null | hex | Latest known-good version in the firmware database; null if CPU is not in the database |
| `microcode_up_to_date` | boolean \| null | | Whether `installed_version == latest_version`; null if either is unavailable |
| `is_blacklisted` | boolean | | Whether the installed microcode is known to cause instability and must be rolled back |
| `message` | string \| null | | Human-readable note from the firmware database (e.g. changelog excerpt) |
| `db_source` | string \| null | | Which database was used (e.g. `"Intel-SA"`, `"MCExtractor"`) |
| `db_info` | string \| null | | Database revision or date |
**`is_blacklisted: true`** means the installed microcode is known to cause
system instability or incorrect behaviour. Treat this as a P1 incident: roll
back to the previous microcode immediately.
**`microcode_up_to_date: false`** means a newer microcode is available. This
does not necessarily mean the system is vulnerable (the current microcode may
still include all required mitigations), but warrants investigation.
---
### `vulnerabilities`
Array of CVE check results. One object per checked CVE, in check order.
Empty array (`[]`) if no CVEs were checked (unusual; would require `--cve`
with an unknown CVE ID).
| Field | Type | Values | Meaning |
|---|---|---|---|
| `cve` | string | e.g. `"CVE-2017-5753"` | CVE identifier |
| `name` | string | e.g. `"SPECTRE VARIANT 1"` | Short key name used in batch formats |
| `aliases` | string \| null | e.g. `"Spectre Variant 1, bounds check bypass"` | Full name including all known aliases |
| `cpu_affected` | boolean | | Whether this CPU's hardware design is affected by this CVE |
| `status` | string | `"OK"` / `"VULN"` / `"UNK"` | Check outcome (see below) |
| `vulnerable` | boolean \| null | `false` / `true` / `null` | `false`=OK, `true`=VULN, `null`=UNK |
| `info` | string | | Human-readable description of the specific mitigation state or reason |
| `sysfs_status` | string \| null | `"OK"` / `"VULN"` / `"UNK"` / null | Status as reported by the kernel via `/sys/devices/system/cpu/vulnerabilities/`; null if sysfs was not consulted for this CVE |
| `sysfs_message` | string \| null | | Raw text from the sysfs file (e.g. `"Mitigation: PTI"`); null if sysfs was not consulted |
#### Status values
| `status` | `vulnerable` | Meaning |
|---|---|---|
| `"OK"` | `false` | CPU is unaffected by design, or all required mitigations are in place |
| `"VULN"` | `true` | CPU is affected and mitigations are missing or insufficient |
| `"UNK"` | `null` | The script could not determine the status (missing kernel info, insufficient privileges, or no detection logic for this platform) |
#### `cpu_affected` explained
`cpu_affected: false` with `status: "OK"` means the CPU hardware is
architecturally immune, no patch was ever needed.
`cpu_affected: true` with `status: "OK"` means the hardware has the weakness
but all required mitigations (kernel, microcode, or both) are in place.
This distinction matters for fleet auditing: filter on `cpu_affected: true` to
see only systems where mitigation effort was actually required and confirmed.
#### `sysfs_status` vs `status`
`sysfs_status` is the raw kernel self-report. `status` is the script's
independent assessment, which may differ:
- The script may **upgrade** a sysfs `"VULN"` to `"OK"` when it detects a
silent backport that the kernel doesn't know about.
- The script may **downgrade** a sysfs `"OK"` to `"VULN"` when it detects an
incomplete mitigation the kernel doesn't flag (e.g. L1TF on a hypervisor
host with SMT still enabled, or TSA in `user` mode on a VMM host).
- `sysfs_status` is `null` when the kernel has no sysfs entry for this CVE
(older kernels, or CVEs not yet tracked by the kernel).
Always use `status` / `vulnerable` for alerting. Use `sysfs_status` for
diagnostics and audit trails.
**Example:**
```json
{
"cve": "CVE-2017-5715",
"name": "SPECTRE VARIANT 2",
"aliases": "Spectre Variant 2, branch target injection",
"cpu_affected": true,
"status": "OK",
"vulnerable": false,
"info": "Full generic retpoline is mitigating the vulnerability",
"sysfs_status": "OK",
"sysfs_message": "Mitigation: Retpolines; IBPB: conditional; IBRS_FW; STIBP: conditional; RSB filling; PBRSB-eIBRS: Not affected; BHI: Not affected"
}
```
---
## Exit codes
The script exits with:
| Code | Meaning |
|---|---|
| `0` | All checked CVEs are `OK` |
| `2` | At least one CVE is `VULN` |
| `3` | No CVEs are `VULN`, but at least one is `UNK` |
These exit codes are the same in all batch modes and in interactive mode.
Use them in combination with the JSON body for reliable alerting.
---
## Caveats and edge cases
**No-runtime mode (`--no-runtime`)**
`system.kernel_release`, `kernel_version`, and `kernel_arch` are null (those
come from `uname`, which reports the running kernel, not the inspected one).
`meta.mode: "no-runtime"` signals this. `system.kernel_image` and
`system.kernel_version_string` carry the inspected image path and banner
instead.
**No-hardware mode (`--no-hw`)**
`cpu` and `cpu_microcode` are null. CVE checks that rely on hardware
capability detection (`cap_*` flags, MSR reads) will report `status: "UNK"`.
`cpu_affected` will be `false` for all CVEs (cannot determine affection without
hardware info). `meta.mode: "no-hw"` signals this.
**Hardware-only mode (`--hw-only`)**
Only CPU information and per-CVE affectedness are reported. No kernel
inspection is performed, so vulnerability mitigations are not checked.
`meta.mode: "hw-only"` signals this.
**`--sysfs-only`**
The script trusts the kernel's sysfs report without running independent
detection. `meta.sysfs_only: true` flags this. Some older kernels misreport
their status. Do not use for production fleet monitoring.
**`--paranoid`**
Enables defense-in-depth checks beyond the security community consensus.
A `status: "OK"` under `paranoid: true` means a higher bar was met. Do not
compare results across hosts with different `paranoid` values.
**`reduced_accuracy`**
Set when the kernel image, config file, or System.map could not be read.
Some checks fall back to weaker heuristics and may report `"UNK"` for CVEs
that are actually mitigated.
**Non-x86 architectures (ARM, ARM64)**
On ARM, `cpu.arch` is `"arm"` and the `cpu.arm` sub-object carries `part_list`
and `arch_list`. The x86-specific sub-object is absent (no null noise).
`cpu.arm.capabilities` is currently empty; ARM-specific flags will be added
there as needed.
**`mocked: true`**
Must never appear on a production host. If it does, the results are
fabricated and every downstream alert is unreliable.
---
## Schema stability
`meta.format_version` is incremented on backward-incompatible changes (field
removal or type change). Additive changes (new fields) do not increment the
version; consumers must tolerate unknown fields.
Recommended practice: check `format_version == 1` at parse time and reject
or alert on any other value until you have tested compatibility with the new
version.
---
## Migration from `json-terse`
The legacy `--batch json-terse` format emits a flat array of objects:
```json
[
{"NAME": "SPECTRE VARIANT 1", "CVE": "CVE-2017-5753", "VULNERABLE": false, "INFOS": "..."},
...
]
```
It carries no system, CPU, or microcode context. It has no sysfs data. It
uses uppercase field names.
To migrate:
1. Replace `--batch json-terse` with `--batch json`.
2. The equivalent of the old `VULNERABLE` field is `vulnerabilities[].vulnerable`.
3. The equivalent of the old `INFOS` field is `vulnerabilities[].info`.
4. The equivalent of the old `NAME` field is `vulnerabilities[].name`.
5. The old format is still available as `--batch json-terse` for transition
periods.

382
doc/batch_json.schema.json Normal file
View File

@@ -0,0 +1,382 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/speed47/spectre-meltdown-checker/dist/batch_json.schema.json",
"title": "spectre-meltdown-checker --batch json output",
"description": "Schema for the comprehensive JSON output produced by spectre-meltdown-checker.sh --batch json. format_version 1.",
"type": "object",
"required": ["meta", "system", "cpu", "cpu_microcode", "vulnerabilities"],
"additionalProperties": false,
"properties": {
"meta": {
"description": "Run metadata and option flags.",
"type": "object",
"required": [
"script_version", "format_version", "timestamp", "os", "mode",
"run_as_root", "reduced_accuracy", "paranoid", "sysfs_only",
"extra", "mocked"
],
"additionalProperties": false,
"properties": {
"script_version": {
"description": "Script version string, e.g. '25.30.0250400123'.",
"type": ["string", "null"]
},
"format_version": {
"description": "JSON schema version. Incremented on backward-incompatible changes. Current value: 1.",
"type": "integer",
"const": 1
},
"timestamp": {
"description": "ISO 8601 UTC timestamp of when the scan started, e.g. '2025-04-07T12:00:00Z'.",
"type": ["string", "null"]
},
"os": {
"description": "Operating system name from uname -s, e.g. 'Linux', 'FreeBSD'.",
"type": ["string", "null"]
},
"mode": {
"description": "Operating mode: 'live' (default), 'no-runtime' (--no-runtime), 'no-hw' (--no-hw), or 'hw-only' (--hw-only).",
"type": "string",
"enum": ["live", "no-runtime", "no-hw", "hw-only"]
},
"run_as_root": {
"description": "Whether the script ran as root. Non-root scans skip MSR reads and may produce incomplete or inaccurate results.",
"type": "boolean"
},
"reduced_accuracy": {
"description": "True when the kernel image, config, or System.map was missing. Some checks fall back to weaker heuristics.",
"type": ["boolean", "null"]
},
"paranoid": {
"description": "True when --paranoid was set: stricter criteria (e.g. requires SMT disabled, IBPB always-on).",
"type": "boolean"
},
"sysfs_only": {
"description": "True when --sysfs-only was set: the script trusted the kernel's own sysfs report without independent detection.",
"type": "boolean"
},
"extra": {
"description": "True when --extra was set: additional experimental checks were enabled.",
"type": "boolean"
},
"mocked": {
"description": "True when one or more CPU values were overridden for testing. Results do NOT reflect the real system.",
"type": ["boolean", "null"]
}
}
},
"system": {
"description": "Kernel and host environment context.",
"type": ["object", "null"],
"required": [
"kernel_release", "kernel_version", "kernel_arch",
"kernel_image", "kernel_config", "kernel_version_string",
"kernel_cmdline", "cpu_count", "smt_enabled",
"hypervisor_host", "hypervisor_host_reason"
],
"additionalProperties": false,
"properties": {
"kernel_release": {
"description": "Output of uname -r (live mode only), e.g. '6.1.0-21-amd64'. Null in other modes.",
"type": ["string", "null"]
},
"kernel_version": {
"description": "Output of uname -v (live mode only), e.g. '#1 SMP Debian …'. Null in other modes.",
"type": ["string", "null"]
},
"kernel_arch": {
"description": "Output of uname -m (live mode only), e.g. 'x86_64'. Null in other modes.",
"type": ["string", "null"]
},
"kernel_image": {
"description": "Path to the kernel image passed via --kernel. Null in live mode.",
"type": ["string", "null"]
},
"kernel_config": {
"description": "Path to the kernel config passed via --config. Null if not provided.",
"type": ["string", "null"]
},
"kernel_version_string": {
"description": "Kernel version banner extracted from the image. Null if unavailable.",
"type": ["string", "null"]
},
"kernel_cmdline": {
"description": "Kernel command line from /proc/cmdline (live mode) or the image. Null if unavailable.",
"type": ["string", "null"]
},
"cpu_count": {
"description": "Number of logical CPUs detected (max core ID + 1). Null if undeterminable.",
"type": ["integer", "null"],
"minimum": 1
},
"smt_enabled": {
"description": "Whether SMT (HyperThreading) is currently enabled. Null if the script could not determine the state.",
"type": ["boolean", "null"]
},
"hypervisor_host": {
"description": "Whether this machine is detected as a VM host (running KVM, Xen, VMware, etc.). Null if undeterminable.",
"type": ["boolean", "null"]
},
"hypervisor_host_reason": {
"description": "Human-readable explanation of why hypervisor_host was set. Null if hypervisor_host is false or null.",
"type": ["string", "null"]
}
}
},
"cpu": {
"description": "CPU hardware identification. Null when --no-hw is active. Contains an 'arch' discriminator ('x86' or 'arm') and a matching arch-specific sub-object with identification fields and capabilities.",
"oneOf": [
{ "type": "null" },
{
"type": "object",
"description": "x86 CPU (Intel, AMD, Hygon).",
"required": ["arch", "vendor", "friendly_name", "x86"],
"additionalProperties": false,
"properties": {
"arch": { "type": "string", "const": "x86" },
"vendor": {
"description": "CPU vendor string: 'GenuineIntel', 'AuthenticAMD', or 'HygonGenuine'.",
"type": ["string", "null"]
},
"friendly_name": {
"description": "Human-readable CPU model from /proc/cpuinfo, e.g. 'Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz'.",
"type": ["string", "null"]
},
"x86": {
"type": "object",
"required": ["family", "model", "stepping", "cpuid", "platform_id", "hybrid", "codename", "capabilities"],
"additionalProperties": false,
"properties": {
"family": {
"description": "CPU family number.",
"type": ["integer", "null"]
},
"model": {
"description": "CPU model number.",
"type": ["integer", "null"]
},
"stepping": {
"description": "CPU stepping number.",
"type": ["integer", "null"]
},
"cpuid": {
"description": "Full CPUID leaf 1 EAX value as a hex string, e.g. '0x000906ed'.",
"type": ["string", "null"],
"pattern": "^0x[0-9a-f]+$"
},
"platform_id": {
"description": "Intel platform ID from MSR 0x17. Null on AMD.",
"type": ["integer", "null"]
},
"hybrid": {
"description": "Whether this is a hybrid CPU (P-cores + E-cores, e.g. Alder Lake). Null if undeterminable.",
"type": ["boolean", "null"]
},
"codename": {
"description": "Intel CPU codename, e.g. 'Coffee Lake'. Null on AMD.",
"type": ["string", "null"]
},
"capabilities": {
"description": "CPU feature flags detected via CPUID and MSR reads. Each value is true (present), false (absent), or null (not applicable or could not be read).",
"type": "object",
"additionalProperties": false,
"properties": {
"spec_ctrl": { "type": ["boolean", "null"], "description": "SPEC_CTRL MSR present (Intel; enables IBRS + IBPB via WRMSR)" },
"ibrs": { "type": ["boolean", "null"], "description": "Indirect Branch Restricted Speculation" },
"ibpb": { "type": ["boolean", "null"], "description": "Indirect Branch Prediction Barrier" },
"ibpb_ret": { "type": ["boolean", "null"], "description": "IBPB on return (enhanced form)" },
"stibp": { "type": ["boolean", "null"], "description": "Single Thread Indirect Branch Predictors" },
"ssbd": { "type": ["boolean", "null"], "description": "Speculative Store Bypass Disable" },
"l1d_flush": { "type": ["boolean", "null"], "description": "L1D cache flush instruction" },
"md_clear": { "type": ["boolean", "null"], "description": "VERW clears CPU buffers (MDS mitigation)" },
"arch_capabilities": { "type": ["boolean", "null"], "description": "IA32_ARCH_CAPABILITIES MSR is present" },
"rdcl_no": { "type": ["boolean", "null"], "description": "Not susceptible to RDCL (Meltdown-like attacks)" },
"ibrs_all": { "type": ["boolean", "null"], "description": "Enhanced IBRS always-on mode supported" },
"rsba": { "type": ["boolean", "null"], "description": "RSB may use return predictions from outside the RSB" },
"l1dflush_no": { "type": ["boolean", "null"], "description": "Not susceptible to L1D flush side-channel" },
"ssb_no": { "type": ["boolean", "null"], "description": "Not susceptible to Speculative Store Bypass" },
"mds_no": { "type": ["boolean", "null"], "description": "Not susceptible to MDS" },
"taa_no": { "type": ["boolean", "null"], "description": "Not susceptible to TSX Asynchronous Abort" },
"pschange_msc_no": { "type": ["boolean", "null"], "description": "Page-size-change MSC not susceptible" },
"tsx_ctrl_msr": { "type": ["boolean", "null"], "description": "TSX_CTRL MSR is present" },
"tsx_ctrl_rtm_disable": { "type": ["boolean", "null"], "description": "RTM disabled via TSX_CTRL" },
"tsx_ctrl_cpuid_clear": { "type": ["boolean", "null"], "description": "CPUID HLE/RTM bits cleared via TSX_CTRL" },
"gds_ctrl": { "type": ["boolean", "null"], "description": "GDS_CTRL MSR present" },
"gds_no": { "type": ["boolean", "null"], "description": "Not susceptible to Gather Data Sampling" },
"gds_mitg_dis": { "type": ["boolean", "null"], "description": "GDS mitigation disabled" },
"gds_mitg_lock": { "type": ["boolean", "null"], "description": "GDS mitigation locked" },
"rfds_no": { "type": ["boolean", "null"], "description": "Not susceptible to Register File Data Sampling" },
"rfds_clear": { "type": ["boolean", "null"], "description": "VERW clears register file stale data" },
"its_no": { "type": ["boolean", "null"], "description": "Not susceptible to Indirect Target Selection" },
"sbdr_ssdp_no": { "type": ["boolean", "null"], "description": "Not susceptible to SBDR/SSDP" },
"fbsdp_no": { "type": ["boolean", "null"], "description": "Not susceptible to FBSDP" },
"psdp_no": { "type": ["boolean", "null"], "description": "Not susceptible to PSDP" },
"fb_clear": { "type": ["boolean", "null"], "description": "Fill buffer cleared on idle/C6" },
"rtm": { "type": ["boolean", "null"], "description": "Restricted Transactional Memory (TSX RTM) present" },
"tsx_force_abort": { "type": ["boolean", "null"], "description": "TSX_FORCE_ABORT MSR present" },
"tsx_force_abort_rtm_disable": { "type": ["boolean", "null"], "description": "RTM disabled via TSX_FORCE_ABORT" },
"tsx_force_abort_cpuid_clear": { "type": ["boolean", "null"], "description": "CPUID RTM cleared via TSX_FORCE_ABORT" },
"sgx": { "type": ["boolean", "null"], "description": "Software Guard Extensions present" },
"srbds": { "type": ["boolean", "null"], "description": "SRBDS affected" },
"srbds_on": { "type": ["boolean", "null"], "description": "SRBDS mitigation active" },
"amd_ssb_no": { "type": ["boolean", "null"], "description": "AMD: not susceptible to Speculative Store Bypass" },
"hygon_ssb_no": { "type": ["boolean", "null"], "description": "Hygon: not susceptible to Speculative Store Bypass" },
"ipred": { "type": ["boolean", "null"], "description": "Indirect Predictor Barrier support" },
"rrsba": { "type": ["boolean", "null"], "description": "Restricted RSB Alternate (Intel Retbleed mitigation)" },
"bhi": { "type": ["boolean", "null"], "description": "Branch History Injection mitigation support" },
"tsa_sq_no": { "type": ["boolean", "null"], "description": "Not susceptible to TSA-SQ" },
"tsa_l1_no": { "type": ["boolean", "null"], "description": "Not susceptible to TSA-L1" },
"verw_clear": { "type": ["boolean", "null"], "description": "VERW clears CPU buffers" },
"autoibrs": { "type": ["boolean", "null"], "description": "AMD AutoIBRS (equivalent to enhanced IBRS on Intel)" },
"sbpb": { "type": ["boolean", "null"], "description": "Selective Branch Predictor Barrier (AMD Inception mitigation)" },
"avx2": { "type": ["boolean", "null"], "description": "AVX2 supported (relevant to Downfall / GDS)" },
"avx512": { "type": ["boolean", "null"], "description": "AVX-512 supported (relevant to Downfall / GDS)" }
}
}
}
}
}
},
{
"type": "object",
"description": "ARM CPU (ARM, Cavium, Phytium).",
"required": ["arch", "vendor", "friendly_name", "arm"],
"additionalProperties": false,
"properties": {
"arch": { "type": "string", "const": "arm" },
"vendor": {
"description": "CPU vendor string: 'ARM', 'CAVIUM', or 'PHYTIUM'.",
"type": ["string", "null"]
},
"friendly_name": {
"description": "Human-readable CPU model, e.g. 'ARM v8 model 0xd0b'.",
"type": ["string", "null"]
},
"arm": {
"type": "object",
"required": ["part_list", "arch_list", "capabilities"],
"additionalProperties": false,
"properties": {
"part_list": {
"description": "Space-separated list of ARM part numbers detected across cores, e.g. '0xd0b 0xd05' (big.LITTLE).",
"type": ["string", "null"]
},
"arch_list": {
"description": "Space-separated list of ARM architecture levels detected across cores, e.g. '8 8'.",
"type": ["string", "null"]
},
"capabilities": {
"description": "ARM-specific CPU capability flags. Currently empty; reserved for future use.",
"type": "object",
"additionalProperties": false,
"properties": {}
}
}
}
}
}
]
},
"cpu_microcode": {
"description": "Microcode version and firmware database status. Null under the same conditions as cpu.",
"type": ["object", "null"],
"required": [
"installed_version", "latest_version", "microcode_up_to_date",
"is_blacklisted", "message", "db_source", "db_info"
],
"additionalProperties": false,
"properties": {
"installed_version": {
"description": "Currently running microcode revision as a hex string, e.g. '0xf4'. Null if unreadable.",
"type": ["string", "null"],
"pattern": "^0x[0-9a-f]+$"
},
"latest_version": {
"description": "Latest known-good microcode version from the firmware database, as a hex string. Null if the CPU is not in the database.",
"type": ["string", "null"],
"pattern": "^0x[0-9a-f]+$"
},
"microcode_up_to_date": {
"description": "True when installed_version equals latest_version. Null if either is unavailable.",
"type": ["boolean", "null"]
},
"is_blacklisted": {
"description": "True when the installed microcode is known to cause instability and must be rolled back immediately.",
"type": "boolean"
},
"message": {
"description": "Human-readable note from the firmware database (e.g. changelog excerpt). Null if absent.",
"type": ["string", "null"]
},
"db_source": {
"description": "Which firmware database was used, e.g. 'Intel-SA', 'MCExtractor'. Null if unavailable.",
"type": ["string", "null"]
},
"db_info": {
"description": "Firmware database revision or date string. Null if unavailable.",
"type": ["string", "null"]
}
}
},
"vulnerabilities": {
"description": "Array of CVE check results, one per checked CVE, in check order.",
"type": "array",
"items": {
"type": "object",
"required": [
"cve", "name", "aliases", "cpu_affected",
"status", "vulnerable", "info",
"sysfs_status", "sysfs_message"
],
"additionalProperties": false,
"properties": {
"cve": {
"description": "CVE identifier, e.g. 'CVE-2017-5753'. May be 'CVE-0000-0001' for non-CVE checks such as SLS.",
"type": "string",
"pattern": "^CVE-[0-9]{4}-[0-9]+$"
},
"name": {
"description": "Short key name used across batch formats, e.g. 'SPECTRE VARIANT 1'.",
"type": "string"
},
"aliases": {
"description": "Full name including all known aliases, e.g. 'Spectre Variant 1, bounds check bypass'. Null if not in the registry.",
"type": ["string", "null"]
},
"cpu_affected": {
"description": "Whether this CPU's hardware design is affected by this CVE. False when hardware is architecturally immune.",
"type": "boolean"
},
"status": {
"description": "Check outcome: 'OK'=not vulnerable or unaffected, 'VULN'=vulnerable, 'UNK'=could not determine.",
"type": "string",
"enum": ["OK", "VULN", "UNK"]
},
"vulnerable": {
"description": "Boolean encoding of status: false=OK, true=VULN, null=UNK.",
"type": ["boolean", "null"]
},
"info": {
"description": "Human-readable description of the specific mitigation state or reason for the verdict.",
"type": "string"
},
"sysfs_status": {
"description": "Status as reported by the kernel via /sys/devices/system/cpu/vulnerabilities/. Null if sysfs was not consulted for this CVE (older kernels, or CVE not tracked by the kernel).",
"type": ["string", "null"],
"enum": ["OK", "VULN", "UNK", null]
},
"sysfs_message": {
"description": "Raw text from the sysfs vulnerability file, e.g. 'Mitigation: PTI'. Null if sysfs was not consulted.",
"type": ["string", "null"]
}
}
}
}
}
}

149
doc/batch_nrpe.md Normal file
View File

@@ -0,0 +1,149 @@
# NRPE Output Format
`--batch nrpe` produces output that conforms to the
[Nagios Plugin Development Guidelines](https://nagios-plugins.org/doc/guidelines.html),
making it directly consumable by Nagios, Icinga, Zabbix (via NRPE), and
compatible monitoring stacks.
```sh
sudo ./spectre-meltdown-checker.sh --batch nrpe
```
## Output structure
The plugin emits one mandatory status line followed by optional long output:
```
STATUS: summary | checked=N vulnerable=N unknown=N
NOTE: ... ← context notes (when applicable)
[CRITICAL] CVE-XXXX-YYYY (NAME): description
[UNKNOWN] CVE-XXXX-YYYY (NAME): description
```
### Line 1 (status line)
Always present. Parsed by every Nagios-compatible monitoring system.
```
STATUS: summary | perfdata
```
| Field | Values | Meaning |
|---|---|---|
| `STATUS` | `OK` / `CRITICAL` / `UNKNOWN` | Overall check outcome (see below) |
| `summary` | human-readable string | Count and CVE IDs of affected checks |
| `perfdata` | `checked=N vulnerable=N unknown=N` | Machine-readable counters for graphing |
#### Status values
| Status | Exit code | Condition |
|---|---|---|
| `OK` | `0` | All CVE checks passed |
| `CRITICAL` | `2` | At least one CVE is vulnerable |
| `UNKNOWN` | `3` | No VULN found, but at least one check is inconclusive **or** the script was not run as root and found apparent vulnerabilities (see below) |
#### Summary format
| Condition | Summary |
|---|---|
| All OK | `All N CVE checks passed` |
| VULN only | `N/T CVE(s) vulnerable: CVE-A CVE-B ...` |
| VULN + UNK | `N/T CVE(s) vulnerable: CVE-A CVE-B ..., M inconclusive` |
| UNK only | `N/T CVE checks inconclusive` |
| Non-root + VULN | `N/T CVE(s) appear vulnerable (unconfirmed, not root): CVE-A ...` |
### Lines 2+ (long output)
Shown in the detail/extended info view of most monitoring frontends.
Never parsed by the monitoring core; safe to add or reorder.
#### Context notes
Printed before per-CVE details when applicable:
| Note | Condition |
|---|---|
| `NOTE: paranoid mode active, stricter mitigation requirements applied` | `--paranoid` was used |
| `NOTE: hypervisor host detected (reason); L1TF/MDS severity is elevated` | System is a VM host (KVM, Xen, VMware…) |
| `NOTE: not a hypervisor host` | System is confirmed not a VM host |
| `NOTE: not running as root; MSR reads skipped, results may be incomplete` | Script ran without root privileges |
#### Per-CVE detail lines
One line per non-OK CVE. VULN entries (`[CRITICAL]`) appear before UNK
entries (`[UNKNOWN]`); within each group the order follows the CVE registry.
```
[CRITICAL] CVE-XXXX-YYYY (SHORT NAME): mitigation status description
[UNKNOWN] CVE-XXXX-YYYY (SHORT NAME): reason check was inconclusive
```
## Exit codes
| Code | Nagios meaning | Condition |
|---|---|---|
| `0` | OK | All checked CVEs are mitigated or hardware-unaffected |
| `2` | CRITICAL | At least one CVE is vulnerable (script ran as root) |
| `3` | UNKNOWN | At least one check inconclusive, or apparent VULN found without root |
| `255` | - | Script error (bad arguments, unsupported platform) |
Exit code `1` (WARNING) is not used; there is no "degraded but acceptable"
state for CPU vulnerability mitigations.
## Non-root behaviour
Running without root privileges skips MSR reads and limits access to some
kernel interfaces. When the script finds apparent vulnerabilities without root:
- The status word becomes `UNKNOWN` instead of `CRITICAL`
- The exit code is `3` instead of `2`
- The summary says `appear vulnerable (unconfirmed, not root)`
- A `NOTE: not running as root` line is added to the long output
**Recommendation:** always run with `sudo` for authoritative results. A
`CRITICAL` from a root-run scan is a confirmed vulnerability; an `UNKNOWN`
from a non-root scan is a signal to investigate further.
## Hypervisor hosts
When `NOTE: hypervisor host detected` is present, L1TF (CVE-2018-3646) and
MDS (CVE-2018-12126/12130/12127) carry significantly higher risk because
they can be exploited across VM boundaries by a malicious guest. Prioritise
remediation on these hosts.
## Examples
**All mitigated (root):**
```
OK: All 31 CVE checks passed | checked=31 vulnerable=0 unknown=0
NOTE: not a hypervisor host
```
Exit: `0`
**Two CVEs vulnerable (root):**
```
CRITICAL: 2/31 CVE(s) vulnerable: CVE-2018-3615 CVE-2019-11135 | checked=31 vulnerable=2 unknown=0
NOTE: not a hypervisor host
[CRITICAL] CVE-2018-3615 (L1TF SGX): your CPU supports SGX and the microcode is not up to date
[CRITICAL] CVE-2019-11135 (TAA): Your kernel doesn't support TAA mitigation, update it
```
Exit: `2`
**Apparent vulnerabilities, non-root scan:**
```
UNKNOWN: 2/31 CVE(s) appear vulnerable (unconfirmed, not root): CVE-2018-3615 CVE-2019-11135 | checked=31 vulnerable=2 unknown=0
NOTE: not a hypervisor host
NOTE: not running as root; MSR reads skipped, results may be incomplete
[CRITICAL] CVE-2018-3615 (L1TF SGX): your CPU supports SGX and the microcode is not up to date
[CRITICAL] CVE-2019-11135 (TAA): Your kernel doesn't support TAA mitigation, update it
```
Exit: `3`
**Inconclusive checks, paranoid mode, VMM host:**
```
UNKNOWN: 3/31 CVE checks inconclusive | checked=31 vulnerable=0 unknown=3
NOTE: paranoid mode active, stricter mitigation requirements applied
NOTE: hypervisor host detected (kvm); L1TF/MDS severity is elevated
[UNKNOWN] CVE-2018-3646 (L1TF VMM): SMT is enabled on a hypervisor host, not mitigated under paranoid mode
```
Exit: `3`

377
doc/batch_prometheus.md Normal file
View File

@@ -0,0 +1,377 @@
# Prometheus Batch Mode
`--batch prometheus` emits Prometheus text-format metrics that can be fed into any
Prometheus-compatible monitoring stack. It is designed for **fleet-scale security
monitoring**: run the script periodically on every host, push the output to a
Prometheus Pushgateway (or drop it into a node_exporter textfile directory), then
alert and dashboard from Prometheus/Grafana like any other infrastructure metric.
---
## Quick start
### Pushgateway (recommended for cron/batch fleet scans)
```sh
#!/bin/sh
PUSHGATEWAY="http://pushgateway.internal:9091"
INSTANCE=$(hostname -f)
spectre-meltdown-checker.sh --batch prometheus \
| curl --silent --show-error --data-binary @- \
"${PUSHGATEWAY}/metrics/job/smc/instance/${INSTANCE}"
```
Run this as root via cron or a systemd timer on every host. The Pushgateway
retains the last pushed value, so Prometheus scrapes it on its own schedule.
A stale-data alert (`smc_last_scan_timestamp_seconds`) catches hosts that stopped
reporting.
### node_exporter textfile collector
```sh
#!/bin/sh
TEXTFILE_DIR="/var/lib/node_exporter/textfile_collector"
TMP="${TEXTFILE_DIR}/smc.prom.$$"
spectre-meltdown-checker.sh --batch prometheus > "$TMP"
mv "$TMP" "${TEXTFILE_DIR}/smc.prom"
```
The atomic `mv` prevents node_exporter from reading a partially written file.
node_exporter must be started with `--collector.textfile.directory` pointing at
`TEXTFILE_DIR`.
---
## Metric reference
All metric names are prefixed `smc_` (spectre-meltdown-checker). All metrics
are **gauges**: they represent the state at the time of the scan, not a running
counter.
---
### `smc_build_info`
Script metadata. Always value `1`; all data is in labels.
| Label | Values | Meaning |
|---|---|---|
| `version` | string | Script version (e.g. `25.30.0250400123`) |
| `mode` | `live` / `offline` | `live` = running on the active kernel; `offline` = inspecting a kernel image |
| `run_as_root` | `true` / `false` | Whether the script ran as root. Non-root scans skip MSR reads and may miss mitigations |
| `paranoid` | `true` / `false` | `--paranoid` mode: stricter criteria (e.g. requires SMT disabled) |
| `sysfs_only` | `true` / `false` | `--sysfs-only` mode: only the kernel's own sysfs report was used, not independent detection |
| `reduced_accuracy` | `true` / `false` | Kernel information was incomplete (no kernel image, config, or map); some checks may be less precise |
| `mocked` | `true` / `false` | Debug/test mode: CPU values were overridden. Results do **not** reflect the real system |
**Example:**
```
smc_build_info{version="25.30.0250400123",mode="live",run_as_root="true",paranoid="false",sysfs_only="false",reduced_accuracy="false",mocked="false"} 1
```
**Important labels for fleet operators:**
- `run_as_root="false"` means the scan was incomplete. Treat those results as
lower confidence and alert separately.
- `sysfs_only="true"` means the script trusted the kernel's self-report without
independent verification. The kernel may be wrong about its own mitigation
status (known to happen on older kernels).
- `paranoid="true"` raises the bar: a host with `paranoid="true"` and
`vulnerable_count=0` is held to a higher standard than one with `paranoid="false"`.
Do not compare counts across hosts with different `paranoid` values.
- `mocked="true"` must never appear on a production host; if it does, the results
are fabricated and every downstream alert is unreliable.
---
### `smc_system_info`
Operating system and kernel metadata. Always value `1`.
Absent in offline mode when neither `uname -r` nor `uname -m` is available.
| Label | Values | Meaning |
|---|---|---|
| `kernel_release` | string | Output of `uname -r` (live mode only) |
| `kernel_arch` | string | Output of `uname -m` (live mode only) |
| `hypervisor_host` | `true` / `false` | Whether this machine is detected as a hypervisor host (running KVM, Xen, VMware, etc.) |
**Example:**
```
smc_system_info{kernel_release="5.15.0-100-generic",kernel_arch="x86_64",hypervisor_host="false"} 1
```
**`hypervisor_host`** materially changes the risk profile of several CVEs.
L1TF (CVE-2018-3646) and MDS (CVE-2018-12126/12130/12127) are significantly more
severe on hypervisor hosts because they can be exploited across VM boundaries by
a malicious guest. Always prioritise remediation on hosts where
`hypervisor_host="true"`.
---
### `smc_cpu_info`
CPU hardware and microcode metadata. Always value `1`. Absent when `--no-hw`
is used.
| Label | Values | Meaning |
|---|---|---|
| `vendor` | string | CPU vendor (e.g. `Intel`, `AuthenticAMD`) |
| `model` | string | CPU friendly name from `/proc/cpuinfo` |
| `family` | integer string | CPU family number |
| `model_id` | integer string | CPU model number |
| `stepping` | integer string | CPU stepping number |
| `cpuid` | hex string | Full CPUID value (e.g. `0x000906ed`); absent on some ARM CPUs |
| `codename` | string | Intel CPU codename (e.g. `Coffee Lake`); absent on AMD and ARM |
| `smt` | `true` / `false` | Whether SMT (HyperThreading) is currently enabled |
| `microcode` | hex string | Installed microcode version (e.g. `0xf4`) |
| `microcode_latest` | hex string | Latest known-good microcode version from the firmware database |
| `microcode_up_to_date` | `true` / `false` | Whether `microcode == microcode_latest` |
| `microcode_blacklisted` | `true` / `false` | Whether the installed microcode is known to cause problems and should be rolled back |
**Example:**
```
smc_cpu_info{vendor="Intel",model="Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz",family="6",model_id="158",stepping="13",cpuid="0x000906ed",codename="Coffee Lake",smt="true",microcode="0xf4",microcode_latest="0xf4",microcode_up_to_date="true",microcode_blacklisted="false"} 1
```
**Microcode labels:**
- `microcode_up_to_date="false"` means a newer microcode is available in the
firmware database. This does not necessarily mean the system is vulnerable
(the current microcode may still provide all required mitigations), but it
warrants investigation.
- `microcode_blacklisted="true"` means the installed microcode is known to
cause system instability or incorrect behaviour and must be rolled back
immediately. Treat this as a P1 incident.
- `microcode_latest` may be absent if the CPU is not in the firmware database
(very new, very old, or exotic CPUs).
**`smt`** affects the risk level of several CVEs (MDS, L1TF). For those CVEs,
full mitigation requires disabling SMT in addition to kernel and microcode updates.
The script accounts for this in its status assessment; use this label to audit
which hosts still have SMT enabled.
---
### `smc_vulnerability_status`
One time series per CVE. The **numeric value** encodes the check result:
| Value | Meaning |
|---|---|
| `0` | Not vulnerable (CPU is unaffected by design, or all required mitigations are in place) |
| `1` | Vulnerable (mitigations are missing or insufficient) |
| `2` | Unknown (the script could not determine the status, e.g. due to missing kernel info or insufficient privileges) |
| Label | Values | Meaning |
|---|---|---|
| `cve` | CVE ID string | The CVE identifier (e.g. `CVE-2017-5753`) |
| `name` | string | Human-readable CVE name and aliases (e.g. `Spectre Variant 1, bounds check bypass`) |
| `cpu_affected` | `true` / `false` | Whether this CPU's hardware design is concerned by this CVE |
**Example:**
```
smc_vulnerability_status{cve="CVE-2017-5753",name="Spectre Variant 1, bounds check bypass",cpu_affected="true"} 0
smc_vulnerability_status{cve="CVE-2017-5715",name="Spectre Variant 2, branch target injection",cpu_affected="true"} 1
smc_vulnerability_status{cve="CVE-2022-29900",name="Retbleed, arbitrary speculative code execution with return instructions (AMD)",cpu_affected="false"} 0
```
**`cpu_affected` explained:**
A value of `0` with `cpu_affected="false"` means the CPU hardware is architecturally
immune to this CVE, no patch was needed or applied.
A value of `0` with `cpu_affected="true"` means the CPU has the hardware weakness
but all required mitigations (kernel, microcode, or both) are in place.
This distinction is important when auditing a fleet: if you need to verify that
all at-risk systems are patched, filter on `cpu_affected="true"` to exclude
hardware-immune systems from the analysis.
---
### `smc_vulnerable_count`
Number of CVEs with status `1` (vulnerable) in this scan. Value is `0` when
no CVEs are vulnerable.
---
### `smc_unknown_count`
Number of CVEs with status `2` (unknown) in this scan. A non-zero value
typically means the scan lacked sufficient privileges or kernel information.
Treat unknown the same as vulnerable for alerting purposes.
---
### `smc_last_scan_timestamp_seconds`
Unix timestamp (seconds since epoch) when the scan completed. Use this to
detect hosts that have stopped reporting.
---
## Alerting rules
```yaml
groups:
- name: spectre_meltdown_checker
rules:
# Fire when any CVE is confirmed vulnerable
- alert: SMCVulnerable
expr: smc_vulnerable_count > 0
for: 0m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} has {{ $value }} vulnerable CVE(s)"
description: >
Run spectre-meltdown-checker.sh interactively on {{ $labels.instance }}
for remediation guidance.
# Fire when status is unknown (usually means scan ran without root)
- alert: SMCUnknown
expr: smc_unknown_count > 0
for: 0m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has {{ $value }} CVE(s) with unknown status"
description: >
Ensure the checker runs as root on {{ $labels.instance }}.
# Fire when a host stops reporting (scan not run in 8 days)
- alert: SMCScanStale
expr: time() - smc_last_scan_timestamp_seconds > 8 * 86400
for: 0m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has not reported scan results in 8 days"
# Fire when installed microcode is known-bad
- alert: SMCMicrocodeBlacklisted
expr: smc_cpu_info{microcode_blacklisted="true"} == 1
for: 0m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} is running blacklisted microcode"
description: >
The installed microcode ({{ $labels.microcode }}) is known to cause
instability. Roll back to the previous version immediately.
# Fire when scan ran without root (results may be incomplete)
- alert: SMCScanNotRoot
expr: smc_build_info{run_as_root="false"} == 1
for: 0m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} scan ran without root privileges"
# Fire when mocked data is detected on a production host
- alert: SMCScanMocked
expr: smc_build_info{mocked="true"} == 1
for: 0m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} scan results are mocked and unreliable"
```
---
## Useful PromQL queries
```promql
# All vulnerable CVEs across the fleet
smc_vulnerability_status == 1
# Vulnerable CVEs on hosts that are also hypervisor hosts (highest priority)
smc_vulnerability_status == 1
* on(instance) group_left(hypervisor_host)
smc_system_info{hypervisor_host="true"}
# Vulnerable CVEs on affected CPUs only (excludes hardware-immune systems)
smc_vulnerability_status{cpu_affected="true"} == 1
# Fleet-wide: how many hosts are vulnerable to each CVE
count by (cve, name) (smc_vulnerability_status == 1)
# Hosts with outdated microcode, with CPU model context
smc_cpu_info{microcode_up_to_date="false"}
# Hosts with SMT still enabled (relevant for MDS/L1TF remediation)
smc_cpu_info{smt="true"}
# For a specific CVE: hosts affected by hardware but fully mitigated
smc_vulnerability_status{cve="CVE-2018-3646", cpu_affected="true"} == 0
# Proportion of fleet that is fully clean (no vulnerable, no unknown)
(
count(smc_vulnerable_count == 0 and smc_unknown_count == 0)
/
count(smc_vulnerable_count >= 0)
)
# Hosts where scan ran without root, results less reliable
smc_build_info{run_as_root="false"}
# Hosts with sysfs_only mode, independent detection was skipped
smc_build_info{sysfs_only="true"}
# Vulnerable CVEs joined with kernel release for patch tracking
smc_vulnerability_status == 1
* on(instance) group_left(kernel_release)
smc_system_info
# Vulnerable CVEs joined with CPU model and microcode version
smc_vulnerability_status == 1
* on(instance) group_left(vendor, model, microcode, microcode_up_to_date)
smc_cpu_info
```
---
## Caveats and edge cases
**Offline mode (`--kernel`)**
`smc_system_info` will have no `kernel_release` or `kernel_arch` labels (those
come from `uname`, which reports the running kernel, not the inspected one).
`mode="offline"` in `smc_build_info` signals this. Offline mode is primarily
useful for pre-deployment auditing, not fleet runtime monitoring.
**`--no-hw`**
`smc_cpu_info` is not emitted. CPU and microcode labels are absent from all
queries. CVE checks that rely on hardware capability detection (`cap_*` flags,
MSR reads) will report `unknown` status.
**`--sysfs-only`**
The script trusts the kernel's sysfs report (`/sys/devices/system/cpu/vulnerabilities/`)
without running its own independent detection. Some older kernels are known to
misreport their mitigation status. `sysfs_only="true"` in `smc_build_info`
flags this condition. Do not use `--sysfs-only` for production fleet monitoring.
**`--paranoid`**
Enables defense-in-depth checks beyond the security community consensus (e.g.
requires SMT to be disabled, IBPB always-on). A host is only `vulnerable_count=0`
under `paranoid` if it meets this higher bar. Do not compare `vulnerable_count`
across hosts with different `paranoid` values.
**`reduced_accuracy`**
Set when the kernel image, config file, or System.map could not be read. Some
checks fall back to weaker heuristics and may report `unknown` for CVEs that are
actually mitigated. This typically happens when the script runs without root or
on a kernel with an inaccessible image.
**Label stability**
Prometheus identifies time series by their full label set. If a script upgrade
adds or renames a label (e.g. a new `smc_cpu_info` label is added for a new CVE),
Prometheus will create a new time series and the old one will become stale. Plan
for this in long-retention dashboards by using `group_left` joins rather than
hardcoding label matchers.

File diff suppressed because it is too large Load Diff