Compare commits

..

649 Commits

Author SHA1 Message Date
github-actions[bot] cf156a2ee5 doc: update output formats doc + normalize json to bool
built from commit e2d110a3b5
 dated 2026-04-20 12:47:43 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-20 10:56:59 +00:00
github-actions[bot] 4eb0d04808 chore: remove from test branch workflows that must live on master
built from commit 1bb33d5cf2
 dated 2026-04-20 12:53:36 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-20 10:55:20 +00:00
github-actions[bot] 50845adbfb doc: CVE-2018-3665 (Lazy FP State Restore (LazyFP)), unsupported
built from commit 6732eb141b
 dated 2026-04-19 12:49:17 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-19 10:50:48 +00:00
github-actions[bot] 7eaa794980 enh: add FPDSS check for AMD Zen1/Zen+ (CVE-2025-54505)
built from commit 048ce5b6a2
 dated 2026-04-18 10:56:21 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-18 15:20:22 +00:00
github-actions[bot] 7e5eee74ac fix: remove useless checks under ARM for CVE-2023-28746
built from commit 48454a5344
 dated 2026-04-10 19:50:15 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-10 17:51:49 +00:00
github-actions[bot] 9bef6ec533 enh: use g_mode to explicitly save/load the current running mode
built from commit e67c9e4265
 dated 2026-04-10 19:26:46 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-10 17:29:38 +00:00
github-actions[bot] f587d9355e enh: guard x86/arm specific checks in kernel/cpu for the proper arch
built from commit c64d4bb481
 dated 2026-04-10 18:37:32 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-10 16:40:49 +00:00
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
speed47 61cc0f3a35 update: fwdb from v347+i20251110+615b to v349+i20260227+615b, 50 microcode changes 2026-03-28 01:52:17 +00:00
Stéphane Lesimple a20641fbad fix: handle non-numeric ARM CPU architecture values
Some old ARM processors (e.g., ARM926EJ-S) report CPU architecture
with suffix in /proc/cpuinfo (e.g., "5TEJ" for ARMv5TEJ).

This caused an "integer expression expected" error when comparing
against numeric values. Extract the numeric prefix before integer comparisons.

Fixes #505.
2026-01-25 12:57:41 +01:00
Stéphane Lesimple d550ea8c85 fix: harmless 'dmesg: write error' that could happen on some systems
Fixes #519.
2026-01-25 11:53:13 +01:00
Stéphane Lesimple 8e33a1dbf2 fix: set cpu_* vars to a default value
On ARM64 systems, /proc/cpuinfo uses different field names (CPU implementer,
CPU variant, CPU part, CPU revision) instead of x86-style fields (cpu family,
model, stepping). This left these variables empty, causing printf to fail
with 'invalid number' errors when formatting them as hex values.

Fixes #520.
2026-01-25 11:38:50 +01:00
speed47 68b4617fd4 update: fwdb from v345+i20251110+4df2 to v347+i20251110+615b, 2 microcode changes 2026-01-01 11:48:36 +01:00
speed47 9fed5ceb33 update: fwdb from v344+i20250811+1523 to v345+i20251110+4df2, 45 microcode changes 2025-11-23 12:38:27 +01:00
Stéphane Lesimple 72bce72fe8 chore: really fix autoupdate workflow to avoid useless PRs 2025-10-31 19:53:59 +01:00
Stéphane Lesimple 5f18e67f6f chore: fix autoupdate workflow 2025-10-30 23:57:05 +01:00
Gabriel Francisco a8466b74fe fix CVE-2017-5715 reporting when IBRS_FW is enabled 2025-10-27 08:42:51 +01:00
speed47 b99be2363c update: fwdb from v296+i20240514+988c to v344+i20250811+1523, 128 microcode changes 2025-10-26 22:08:07 +01:00
Stéphane Lesimple ee4cfd00b8 chore: add autoupdate workflow for fwdb 2025-10-25 20:48:38 +02:00
Stéphane Lesimple c2c60e0161 chore: fix recent shellcheck warnings 2025-10-25 20:48:38 +02:00
Jörg Sommer bae43d8370 Replace head -1 by head -n1
The info page of GNU head says:

> For compatibility 'head' also supports an obsolete option syntax
> '-[NUM][bkm][cqv]', [...] Scripts intended for standard hosts should use
> '-c NUM' or '-n NUM' instead.

At least busybox's head does not support the `-NUM` syntax.
2025-10-25 20:45:24 +02:00
Stéphane Lesimple 34c6095912 fix: Linux 6.9+ changed some config options names (#490)
Issue #490 is about retpoline but other options have also changed,
as reported by a comment on the issue, this commit fixes these
other options:

Breno Leitao (10):
      x86/bugs: Rename CONFIG_GDS_FORCE_MITIGATION => CONFIG_MITIGATION_GDS_FORCE
      x86/bugs: Rename CONFIG_CPU_IBPB_ENTRY       => CONFIG_MITIGATION_IBPB_ENTRY
      x86/bugs: Rename CONFIG_CALL_DEPTH_TRACKING  => CONFIG_MITIGATION_CALL_DEPTH_TRACKING
      x86/bugs: Rename CONFIG_PAGE_TABLE_ISOLATION => CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
      x86/bugs: Rename CONFIG_RETPOLINE            => CONFIG_MITIGATION_RETPOLINE
      x86/bugs: Rename CONFIG_SLS                  => CONFIG_MITIGATION_SLS
      x86/bugs: Rename CONFIG_CPU_UNRET_ENTRY      => CONFIG_MITIGATION_UNRET_ENTRY
      x86/bugs: Rename CONFIG_CPU_IBRS_ENTRY       => CONFIG_MITIGATION_IBRS_ENTRY
      x86/bugs: Rename CONFIG_CPU_SRSO             => CONFIG_MITIGATION_SRSO
      x86/bugs: Rename CONFIG_RETHUNK              => CONFIG_MITIGATION_RETHUNK
2024-08-04 15:15:45 +02:00
Stéphane Lesimple e806e4bc41 chore: docker compose v2
The `docker-compose` command has been replaced by `docker compose`.
The "version" tag has also been deprecated in docker-compose.yml.
2024-08-04 13:53:36 +02:00
Ivan Zahariev 388d44edbd Fix Retpoline detection for Linux 6.9+ (issue #490) 2024-08-04 13:41:01 +02:00
Stéphane Lesimple bd0c7c94b5 fix: typo introduced by #483, fixes #486 2024-05-18 13:01:48 +02:00
Stéphane Lesimple d70e4c2974 fwdb: update to v296+i20240514+988c 2024-05-18 13:01:48 +02:00
Stéphane Lesimple 4e29fb5a21 fix: ucode_platformid_mask is hexa (fixes #485) 2024-02-15 17:27:12 +01:00
Stephane Lesimple 0f2edb1a71 feat: blacklist some more microcodes (fixes #475) 2024-01-09 18:54:39 +01:00
Stephane Lesimple 8ac2539a2a fix: microcode check now supports pf_mask (fixes #482) 2024-01-09 17:05:18 +01:00
Stéphane Lesimple 97f4d5f2bc feat(reptar): add detection and mitigation of Reptar 2024-01-09 15:38:16 +01:00
Stéphane Lesimple 9b7b09ada3 fix(inception): continued mitigation detection 2023-08-25 18:50:53 +02:00
Sébastien Mériot c94811e63d fix(inception): Zen1/2 results based on kernel mitigations 2023-08-25 18:50:53 +02:00
Sébastien Mériot 3e67047c73 feat(inception): README 2023-08-25 18:50:53 +02:00
Sébastien Mériot ecee75716e feat(inception): kernel checks + sbpb support detection 2023-08-25 18:50:53 +02:00
Sébastien Mériot fb6933dc64 feat(inception): Zen1/2 IBPB and SMT checks 2023-08-25 18:50:53 +02:00
Stéphane Lesimple dc6921a1ac feat(inception): handle sysfs interface 2023-08-25 18:50:53 +02:00
Sébastien Mériot 3167762cfd feat(inception): start supporting AMD inception 2023-08-25 18:50:53 +02:00
Stéphane Lesimple 44223c5308 fix: bsd: kernel version detection 2023-08-11 18:41:35 +02:00
Stéphane Lesimple dbe208fc48 enh: downfall: detect kernel mitigation without sysfs 2023-08-11 18:10:27 +02:00
Stéphane Lesimple aca4e2a9b1 enh: move root warning to the bottom 2023-08-11 18:10:27 +02:00
Sébastien Mériot c1c1ac4dbb feat(downfall): detection of the kernel mitigation relying on dmesg 2023-08-10 11:14:40 +02:00
Stéphane Lesimple ba0daa6769 feat: downfall: add kernel soft mitigation support check 2023-08-10 11:14:40 +02:00
Sébastien Mériot 227c0aab1e feat(downfall): add downfall checks 2023-08-10 11:14:40 +02:00
Stéphane Lesimple 8ba3751cf7 fwdb: update to latest Intel ucode versions 2023-08-09 10:35:08 +02:00
Stéphane Lesimple d013c0a7d2 doc: add kernel src as additional ucode version source 2023-08-01 10:22:15 +02:00
Stéphane Lesimple cbe8ba10ce fix: inteldb: cpuid 0x00090660 and 0x000A0680 2023-07-30 13:21:38 +02:00
Stéphane Lesimple 9c2587bca5 enh: when CPUID can't be read, built it by ourselves 2023-07-30 12:21:12 +02:00
Stéphane Lesimple 2a5ddc87bf feat: add Intel known affected processors DB 2023-07-30 12:21:12 +02:00
Stéphane Lesimple 2ef6c1c80e enh: factorize file download func 2023-07-28 20:03:16 +02:00
Stéphane Lesimple 3c224018f4 chore: update disclaimer and FAQ 2023-07-28 20:03:16 +02:00
Stéphane Lesimple b8f8c81d51 release v0.46 2023-07-26 18:07:02 +02:00
Stéphane Lesimple f34dd5fa7b enh: assume CPU is immune to Zenbleed regardless of vendor except AMD
This contradicts our usual "if we don't know, consider vulnerable" motto,
but as this vuln is extremely specific (which is not the case for the Spectre
range of vulnerabilities, for example), this is the correct approach here.
2023-07-26 17:54:44 +02:00
Stéphane Lesimple c0869d7341 enh: zenbleed: give a manual mitigation in --explain 2023-07-26 16:38:02 +02:00
Stéphane Lesimple e99a548dcc fix: fms2cpuid was incorrect for families > 0xF 2023-07-26 14:33:11 +02:00
Stéphane Lesimple 3d475dfaec feat: fwdb: add linux-firmware as AMD source, update fwdb accordingly 2023-07-26 13:57:05 +02:00
Stéphane Lesimple cba5010c2a chore: fix typo 2023-07-26 13:57:05 +02:00
Stéphane Lesimple c5661f098f enh: add --explain text for Zenbleed 2023-07-26 10:56:45 +02:00
Stéphane Lesimple 6844c01242 enh: add zenbleed support to the --variant option 2023-07-26 10:46:38 +02:00
ShadowCurse 0811f28ac6 fix: arm is not affected by zenbleed 2023-07-25 19:59:59 +02:00
Stéphane Lesimple 9bb79a18eb feat: add Zenbleed (CVE-2023-20593) and update fwdb to v270+i20230614 2023-07-25 17:54:59 +02:00
George Cherian 0d93c6ffb4 feat: arm: add Neoverse-N2 and Neoverse-V2
Signed-off-by: George Cherian <george.cherian@marvell.com>
2023-06-18 12:19:02 +02:00
Stéphane Lesimple 6a61df200e update: fwdb to v266+i20230512 2023-05-13 10:27:03 +02:00
ShadowCurse e4b313fe79 feat: arm: add Neoverse-V1 2023-04-22 11:17:06 +02:00
Stéphane Lesimple a2843575be fix: docker: adding missing utils (fixes #433) 2023-02-24 21:35:55 +01:00
Hilton Chain 60c71ccb7a Add support for Guix System kernel. 2023-02-24 20:58:45 +01:00
Stéphane Lesimple 48abeb5950 fix: bad exitcode with --update-fwdb due to trap exit 2023-02-24 20:57:43 +01:00
Stéphane Lesimple 3c988cc73a fix: rewrite SQL to be sqlite3 >= 3.41 compatible
closes #443
2023-02-24 20:54:40 +01:00
glitsj16 bea5cfc3b8 Fix typo: /devnull file created in filesystem 2023-02-24 19:42:16 +01:00
Stéphane Lesimple b68ebe67f2 fix: fwdb: ignore MCEdb versions where an official Intel version exists (fixes #430) 2022-03-30 09:10:55 +02:00
Stéphane Lesimple a6c943d38f release v0.45 2022-03-27 12:41:17 +02:00
Stéphane Lesimple dd162301ff chore: update fwdb to v222+i20220208 2022-03-27 12:38:44 +02:00
Stéphane Lesimple 5f6471d9a4 feat: set default TMPDIR for Android (#415) 2022-03-27 12:31:05 +02:00
Stéphane Lesimple 2a5b965b98 feat: add --allow-msr-write, no longer write by default (#385), detect when writing is denied 2022-03-24 12:37:19 +01:00
Stéphane Lesimple ee266d43b7 chore: fix indentation 2022-03-21 22:22:33 +01:00
Stéphane Lesimple b61baa90df feat: bsd: for unimplemented CVEs, at least report when CPU is not affected 2022-03-21 22:22:33 +01:00
Stéphane Lesimple a98d92f8bc chore: wording: model not vulnerable -> model not affected 2022-03-21 22:22:33 +01:00
Stéphane Lesimple b7c8c4115a feat: implement detection for MCEPSC under BSD 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 4e7c52767d chore: update Intel Family 6 models 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 8473d9ba6b chore: ensure vars are set before being dereferenced (set -u compat) 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 0af4830224 fix: is_ucode_blacklisted: fix some model names 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 81a4329d71 feat: add --cpu, apply changes to (read|write)_msr, update fwdb to v221+i20220208 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 3679776f3c chore: only attempt to load msr and cpuid module once 2022-03-21 22:22:33 +01:00
Stéphane Lesimple ba131fcd2f chore: read_cpuid: use named constants 2022-03-21 22:22:33 +01:00
Stéphane Lesimple ae6bc31c2c feat: hw check: add IPRED, RRSBA, BHI features check 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 6d7a6b3666 feat: add subleaf != 0 support for read_cpuid 2022-03-21 22:22:33 +01:00
Stéphane Lesimple 16f2160be5 chore: fwdb: update to v220+i20220208 2022-03-17 19:39:39 +01:00
Aditya-Tolikar 7cad9301b3 typo
'A' is more 'X' *than 'B'.
Previously: 'A' is more 'X' that 'B'.
2022-03-17 19:26:12 +01:00
Stéphane Lesimple 580549812a fix: retpoline: detection on 5.15.28+ (#420) 2022-03-17 19:25:24 +01:00
Stéphane Lesimple a485c7882a doc: readme: make the FAQ entry more visible 2021-05-25 13:22:54 +02:00
Stéphane Lesimple 7d13f7a0ef doc: add an FAQ entry about CVE support 2021-05-25 13:17:03 +02:00
Stéphane Lesimple 226b2375ab chore: speculative execution -> transient execution 2021-05-25 12:39:51 +02:00
Stéphane Lesimple 052a3e66d1 doc: more FAQ and README 2021-05-25 12:31:30 +02:00
Stéphane Lesimple 05d862709d fix: has_vmm false positive with pcp
Fix by matching the full procname with pgrep (-x),
so that the 'pmdakvm' process doesn't match.

Closes #394
2021-05-25 12:31:07 +02:00
Stéphane Lesimple 3846913899 fix: refuse to run under MacOS and ESXi 2021-05-24 22:42:23 +02:00
Stéphane Lesimple a87ace1f98 doc: add an FAQ.md and update the README.md accordingly 2021-05-24 22:27:46 +02:00
Stéphane Lesimple 0ba71a443e fix: mcedb: v191 changed the MCE table format
Also update the builtin db to v191+i20210217

Closes #400
2021-05-24 12:55:44 +02:00
Stéphane Lesimple 3a486e9985 arm64: variant 4: detect ssbd mitigation from kernel img, system.map or kconfig 2021-04-02 15:38:31 +02:00
Stéphane Lesimple 23564cda5d fix: variant4: added case where prctl ssbd status is tagged as 'unknown' 2021-04-02 15:38:31 +02:00
Stéphane Lesimple 0ea21d09bd fix: extract_kernel: don't overwrite kernel_err if already set
Fixes #395
2021-04-02 15:33:02 +02:00
Stéphane Lesimple 08e30e156d chore: readme: framapic is gone, host the screenshots on GitHub 2021-02-22 21:22:11 +01:00
Zhiyuan Dai 6d35e780f4 arm64: phytium: Add CPU Implementer Phytium
This patch adds 0x70 check for phytium implementer id in function
parse_cpu_details. Also adds that Phytium Soc is not vulnerable to variant 3/3a
2021-01-13 19:14:09 +01:00
Stéphane Lesimple 4ec3154be0 chore: replace 'Vulnerable to' by 'Affected by' in the hw section
This seems to be less confusing, suggested by #356
2020-11-10 18:56:25 +01:00
Stéphane Lesimple 843f26630d feat: arm: add Cortex A77 and Neoverse-N1 (fixes #371) 2020-11-10 18:36:42 +01:00
Stéphane Lesimple 7fc2ec65b9 bump to v0.44 2020-11-09 18:41:43 +01:00
Stéphane Lesimple c8cdfd54da chore: fwdb: update to v165.20201021+i20200616 2020-11-08 21:25:18 +01:00
Stéphane Lesimple f0c33c7a32 fix: fwdb: use the commit date as the intel fwdb version
fixes #379
2020-11-08 21:25:18 +01:00
Stéphane Lesimple 9e874397da chore: fwdb: update to v163.20200930+i20200904 2020-10-05 20:06:49 +02:00
Stéphane Lesimple 76cb73f3cb fix: fwdb: update Intel's repository URL 2020-10-05 20:06:49 +02:00
Stéphane Lesimple 90f23d286e chore: update fwdb to v160.20200912+i20200722 2020-09-14 21:45:09 +02:00
Stéphane Lesimple e41e311a7f feat: add zstd kernel decompression (#370) 2020-09-14 21:42:55 +02:00
Stéphane Lesimple 1f75f01630 fwdb: update MCEdb to v148 & Intel firmwares to 2020-04-27 2020-06-13 18:11:12 +02:00
Stéphane Lesimple 14a53b19da chore: add CVE to the README 2020-06-10 00:07:14 +02:00
Stéphane Lesimple d8f0ddd7a5 chore: fix indentation 2020-06-10 00:07:14 +02:00
Agata Gruza 62d3448a54 Added support for SRBDS related vulnerabilities 2020-06-10 00:07:14 +02:00
Stéphane Lesimple cb6d139629 chore: tests: now expect 15 CVEs instead of 14 (fix) 2020-06-09 22:56:25 +02:00
Stéphane Lesimple 7e2db09ed9 chore: tests: now expect 15 CVEs instead of 14 2020-06-09 22:51:50 +02:00
Stéphane Lesimple 33cf1cde79 enh: arm: add experimental support for binary arm images 2020-06-06 17:29:32 +02:00
Stéphane Lesimple 4a3006e196 fix: arm64: cve-2017-5753: kernels 4.19+ use a different nospec macro 2020-06-06 17:29:32 +02:00
Stéphane Lesimple 36f98eff95 fwdb: update MCEdb to v147 & Intel firmwares to 2020-04-27 2020-05-31 13:03:58 +02:00
xaitax fa7b8f9567 Typo 2020-05-08 16:17:09 +02:00
Stéphane Lesimple 3beefc2587 enh: rsb filling: no longer need the 'strings' tool to check for kernel support in live mode 2020-03-10 22:29:54 +01:00
Stéphane Lesimple 27c36fdb80 fwdb: update to v135.20200303+i20200205 2020-03-10 22:29:39 +01:00
Matt Christian 3d21dae168 Fixes for FreeBSD to parse CPU info. 2020-02-06 19:56:35 +01:00
Stéphane Lesimple 7d2a510146 chore: update fwdb to v132.20200108+i20191124 2020-02-01 18:58:25 +01:00
Stéphane Lesimple a1a35c9b35 chore: github: add check run on pull requests 2020-01-10 13:19:36 +01:00
Stéphane Lesimple eec77e1ab9 fix: fwdb update: remove Intel extract tempdir on exit 2019-12-10 20:21:52 +01:00
Stéphane Lesimple 5633d374de fix: has_vmm: ignore kernel threads when looking for a hypervisor (fixes #278) 2019-12-10 19:10:45 +01:00
Stéphane Lesimple a343bccb49 bump to v0.43 2019-12-08 15:37:17 +01:00
Stéphane Lesimple 1f604c119b fix var typo 2019-12-08 15:25:54 +01:00
Stéphane Lesimple bfed3187a6 fix: variant3a: Silvermont CPUs are not vulnerable to variant 3a 2019-12-08 14:39:31 +01:00
Stéphane Lesimple 0cd7e1164f feat: detect vanilla 5.4+ locked down mode 2019-12-06 23:03:36 +01:00
Stéphane Lesimple 71129d6b48 fix: tsx: rtm feature bit is in EBX(11) 2019-12-02 19:07:10 +01:00
Stéphane Lesimple 6e799e8b01 fix: mcepsc: fix logic error on non-speculative CPUs that prevented detection of MCEPSC immunity 2019-11-25 23:03:04 +01:00
Stéphane Lesimple 4993b04922 fix: taa: CPUs having TAA_NO bit set are not vulnerable 2019-11-25 21:14:54 +01:00
Stéphane Lesimple 4fc2afe1bc feat: add TSX_CTRL MSR detection in hardware info 2019-11-25 20:58:49 +01:00
Stéphane Lesimple bd47275501 feat: add detection of iTLB Multihit vuln/mitigation (CVE-2018-12207) 2019-11-25 19:13:09 +01:00
Stéphane Lesimple 8ddf6b2d6d enh: replace shell wildcard by a find to avoid potiental error (list of args too long) 2019-11-24 17:26:13 +01:00
Stéphane Lesimple 16b6490ffc chore: avoid ${var:-]} syntax, badly confusing vim's syntax highlighter 2019-11-24 17:26:13 +01:00
Stéphane Lesimple 18df38fae6 fix: sgx: on locked down kernels, fallback to CPUID bit for detection
on locked down kernels (Fedora / Red Hat feature that prevents writing
to MSRs from userspace, even if root), we can't write to FLUSH_CMD MSR
to verify that it's present. So fallback to checking the existence of
the L1D flush CPUID feature bit to infer that the microcode has been
updated in a recent enough version that also mitigates SGX (fixes for
both issues have been included in the same microcode updates for all
Intel CPUs)
2019-11-24 17:26:01 +01:00
Stéphane Lesimple a306757c22 fix: detect Red Hat locked down kernels (impacts MSR writes) 2019-11-24 17:26:01 +01:00
Stéphane Lesimple e01f97ee75 fix: fwdb: don't use local db if it's older than our builtin version 2019-11-24 17:25:41 +01:00
Stéphane Lesimple fa7f814f4f chore: rename mcedb cmdline parameters to fwdb 2019-11-24 17:25:41 +01:00
Stéphane Lesimple bb32a16a86 update fwdb to v130.20191104+i20191027 2019-11-24 17:25:41 +01:00
Stéphane Lesimple 8c84c0ba17 enh: fwdb: use both Intel GitHub repo and MCEdb to build our database 2019-11-24 17:25:41 +01:00
Stéphane Lesimple 6abe1bc62b enh: kernel decompression: better tolerance over missing tools
fixes #297
2019-11-23 16:43:00 +01:00
Stéphane Lesimple 5ca7fe91ff fix: pteinv: don't check kernel image if not available 2019-11-23 14:01:56 +01:00
Stéphane Lesimple 4ba68fba74 fix: silence useless error from grep (fixes #322) 2019-11-23 13:51:00 +01:00
Stéphane Lesimple 59ad312773 fix: msr: fix msr module detection under Ubuntu 19.10 (fixes #316) 2019-11-19 22:35:08 +01:00
Stéphane Lesimple 418533c47e chore: remove LICENSE file, SPDX id is enough 2019-11-18 11:28:20 -08:00
Stéphane Lesimple 3e757b6177 chore: add github check workflow 2019-11-18 11:28:20 -08:00
Stéphane Lesimple f724f94085 enh: kernel: autodetect customized arch kernels from cmdline 2019-11-17 13:36:52 -08:00
Stéphane Lesimple dcf540888d enh: mock: implement reading from /proc/cmdline 2019-11-17 13:36:52 -08:00
Stéphane Lesimple 9911c243b2 feat: use --live with --kernel/--config/--map to override file detection in live mode 2019-11-17 13:36:52 -08:00
Stéphane Lesimple cb279a49ec enh(taa): more complete version 2019-11-13 01:07:10 +01:00
Stéphane Lesimple c100ce4c0d mcedb: update from v112 to v130 2019-11-12 21:19:03 +01:00
Stéphane Lesimple 4741b06160 fix: batch mode for TAA 2019-11-12 21:16:21 +01:00
Stéphane Lesimple e0a1c2ec77 fix shellcheck warnings 2019-11-12 20:06:12 +01:00
Agata Gruza c18b88d745 Fixing typo 2019-11-12 19:40:47 +01:00
Agata Gruza d623524342 Added support for TAA related vulnerabilities 2019-11-12 19:40:47 +01:00
Stéphane Lesimple f5ec320fe5 enh: rework the vuln logic of MDS with --paranoid (fixes #307) 2019-09-22 04:02:33 +02:00
Stéphane Lesimple cc224c0522 fix: mocking value for read_msr
we were returning the mocking value before actually setting it.
also remove spaces around the returned value (no behavior change)
2019-09-22 01:38:18 +02:00
Corey Wright 0518604fe6 Use kernel_err to avoid misreporting missing Linux kernel image
When checking for CVE-2017-5715 (i.e. `check_CVE_2017_5715_linux()`),
if we can't inspect (with `readelf`) or decompress the Linux kernel
image, then we report there is no kernel image (i.e. `we need the
kernel image` or `kernel image missing`, respectively), which confuses
users when the associated file exists.

Instead use `kernel_err` to provide a correct and detailed description
of the problem (e.g. `missing '...' tool, please install it, usually
it's in the '...' package`), so the user can take the prescribed
action.
2019-09-22 01:09:58 +02:00
Erik Zettel d57fecec91 spectre-meltdown-checker.sh: fix typos 2019-09-20 23:50:52 +02:00
Stéphane Lesimple f835f4d07d Explain that Enhanced IBRS is better for performance than classic IBRS 2019-08-16 12:53:39 +02:00
Agata Gruza 482d6c200a Enhanced IBRS capabilities
There are two flavors of IBRS: plain and enhanced. This patch tells which flavor of IBRS is in use.
2019-08-16 12:53:39 +02:00
David Guglielmi 91d0699029 update MCEdb from v111 to v112 2019-06-03 22:49:03 +02:00
Stéphane Lesimple fcc4ff4de2 update MCEdb from v110 to v111, bump to v0.42 2019-05-24 22:49:45 +02:00
Stéphane Lesimple 0bd38ddda0 enh: -v -v now implies --dump-mock-data 2019-05-24 11:36:39 +02:00
Stéphane Lesimple e83dc818cd feat(mds): implement FreeBSD mitigation detection 2019-05-24 11:17:04 +02:00
Stéphane Lesimple d69ea67101 feat(mock): add --dump-mock-data 2019-05-24 10:49:40 +02:00
Stéphane Lesimple dfe0d10f2a fix(mds): remove useless display of MD_CLEAR info in non-hw section 2019-05-24 10:20:48 +02:00
Stéphane Lesimple 58a5acfdbb fix(bsd): read_msr returned data in an incorrect format 2019-05-24 09:33:56 +02:00
Stéphane Lesimple ccb4dbef7c enh(mock): avoid reading the sysfs interface outside sys_interface_check() for higher mocking coverage 2019-05-24 09:28:18 +02:00
Stéphane Lesimple afbb26277f feat(mock): add mocking functionality to help reproducing issues under specific CPUs 2019-05-24 09:28:18 +02:00
Stéphane Lesimple 77b34d48c6 fix(mds): check MDS_NO bit in is_cpu_mds_free() 2019-05-24 09:28:18 +02:00
Stéphane Lesimple 497efe6a82 fix(l1tf): RDCL_NO bit didn't take precedence for vulnerability check on some Intel CPUs 2019-05-24 09:28:18 +02:00
Stéphane Lesimple 62b46df4e7 fix(l1tf): remove libvirtd from hypervisor detection (#278) 2019-05-18 14:22:42 +02:00
Stéphane Lesimple 7d1f269bed fix(mds): AMD confirms they're not vulnerable 2019-05-16 11:31:28 +02:00
Erich Ritz 4f9ca803c8 Fix help text (#285)
* fix --help message

Commit 7b72c20f89 added help text for the
--cve switch, and the "can be specified multiple times" note got
associated with the --cve switch instead of staying with the --variant
switch.  Restore the line to belong to the --variant switch help
message.

* Add new variants to error message

Commit 8e870db4f5 added new variants but
did not add them to the error message that listed the allowable
variants.  Add them now.
2019-05-15 19:34:51 +02:00
Stéphane Lesimple 5788cec18b fix(mds): ARM and CAVIUM are not thought to be vulnerable 2019-05-15 10:56:49 +02:00
Stéphane Lesimple ae56ec0bc5 bump to v0.41 2019-05-15 09:57:28 +02:00
Stéphane Lesimple 871443c9db fix typos in README 2019-05-15 00:28:55 +02:00
Stéphane Lesimple 8fd4e3ab01 fix(xen): remove xenbus and xenwatch as they also exist in domU 2019-05-15 00:23:05 +02:00
Stéphane Lesimple de793a7204 feat(mds): more verbose info about kernel support and microcode support for mitigation 2019-05-15 00:21:08 +02:00
Stéphane Lesimple 11790027d3 feat(mds): add alias ZombieLoad for CVE-2018-12130 2019-05-14 21:42:36 +02:00
Stéphane Lesimple 5939c38c5c update mcedb from v109 to v110 to better detect MDS microcodes 2019-05-14 20:31:27 +02:00
Stéphane Lesimple db7d3206fd feat(mds): add detection of availability of MD_CLEAR instruction 2019-05-14 20:30:47 +02:00
Stéphane Lesimple 1d13a423b8 adjust README 2019-05-14 20:16:01 +02:00
Agata Gruza 8e870db4f5 Added support for MDS related vulnerabilities (#282) 2019-05-14 19:21:20 +02:00
Stéphane Lesimple d547ce4ab4 fix(ssb): fix error when no process uses prctl to set ssb mitigation
fixes #281
2019-05-13 15:35:58 +02:00
Stéphane Lesimple d187827841 enh(vmm): add Xen daemons detection 2019-05-08 20:44:54 +02:00
Hans-Joachim Kliemeck 2e304ec617 enh(xen): improvements for xen systems (#270)
* add mitigation detection for l1tf for xen based systems
* add information for hardware mitigation
* add xen support for meltdown
2019-05-07 20:35:52 +02:00
Stéphane Lesimple fcc04437e8 update builtin MCEdb from v96 to v109 2019-05-07 20:29:59 +02:00
Stéphane Lesimple d31a9810e6 enhance previous commit logic 2019-05-05 20:09:53 +02:00
Stéphane Lesimple 4edb867def fix(vmm): revert to checking the running processes to detect a hypervisor
More information available on #278
2019-05-05 20:04:25 +02:00
Stéphane Lesimple 1264b1c7a3 chore: more shellcheck 0.6 fixes 2019-05-05 18:34:09 +02:00
Stéphane Lesimple 7beca1ac50 fix: invalid names in json batch mode (fixes #279) 2019-05-05 18:15:41 +02:00
David 8ad10e15d3 chore: Comply with Shellcheck SC2209 (#280) 2019-05-05 17:31:18 +02:00
Stéphane Lesimple bfa4de96e6 enh(l1tf): in paranoid mode, assume we're running a hypervisor unless stated otherwise
This change ensures we check for SMT and advise the user to disable it for maximum security.
Doing this, we'll help users mitigate a whole range of vulnerabilities taking advantage of SMT to attack purely from userland other userland processes, as seen in CVE-2018-5407 (also see #261)
2019-04-21 14:05:43 +02:00
Stéphane Lesimple b022b27a51 feat(ssbd): in live mode, report whether the mitigation is active (fix #210) 2019-04-20 20:27:45 +02:00
Dario Faggioli c4bae6ee6a IBRS kernel reported active even if sysfs has "IBRS_FW" only (#275) (#276)
On a (pre-SkyLake) system, where /sys/.../vulnerabilities/spectre_v2 is
"Mitigation: Full generic retpoline, IBPB: conditional, IBRS_FW, RSB filling"

the tool, incorrectly, reports, a couple of lines above:
* IBRS enabled and active:  YES  (for kernel and firmware code)

Use '\<IBRS\>', as suggested by @jirislaby, in upstream issue #275
(https://github.com/speed47/spectre-meltdown-checker/issues/275) when
checking whether IBRS is enabled/active for the kernel.

With that, the output becomes:
* IBRS enabled and active:  YES  (for firmware code only)

which is actually the case.

I double checked that, if the same kernel is used on a post-SkyLake
hardware, which on openSUSE uses IBRS as, even with this change, the
tool (this time correctly) reports:
* IBRS enabled and active:  YES  (for kernel and firmware code)
2019-04-20 14:04:29 +02:00
Stéphane Lesimple 23e7db044e fix(bsd): load vmm if not already loaded, fixes #274
As we read sysctl values under the vmm hierarchy, the modules needs to be loaded,
so if not already done, we load it before testing for CVE-2018-3620 and CVE-2018-3646
2019-04-19 19:47:04 +02:00
Stéphane Lesimple fc4981bb94 update MCEDB from v84 to v96 2019-01-20 19:52:46 +01:00
Dajiang Zhong 419508758e add spectre and meltdown mitigation technologies checking for Hygon CPU (#271)
* add spectre and meltdown mitigation technologies checking for Hygon CPU

* update microarhitecture name for Hygon CPU family 24 with moksha
2019-01-20 19:32:36 +01:00
Stéphane Lesimple d7d2e6934b fix: typo in bare metal detection (fixes #269) 2018-12-12 00:24:17 +01:00
Jan b0083d918e Remove unneeded volumes in Dockerfile (#266) 2018-12-10 19:42:13 +01:00
Lily Wilson 904a83c675 Fix Arch kernel image detection (#268)
currently, the script tries to use the wrong kernel image on Arch if an
alternative kernel (hardened, zen, or lts) is in use. Fortunately, all
the Arch kernel packages place a symlink to the kernel image as /usr/lib/modules/$(uname -r)/vmlinuz, so simply removing the guess for Arch fixes the issue.
2018-12-10 19:36:58 +01:00
Rob Gill 906f54cf9d Improved hypervisor detection (#259)
* Code consistency

``` opt_batch_format="text" ``` replaced by ``` opt_batch_format='text' ```
```nrpe_vuln='"" ``` replaced by ``` nrpe_vuln='' ``` , as used by other parse options

Redundant ``` ! -z ``` replaced by ``` -n ```, as used elsewhere

Signed-off-by: Rob Gill <rrobgill@protonmail.com>

* Improved hypervisor detection

Tests for presence of hypervisor flag in /proc/cpuino
Tests for evidence of hypervisor in dmesg

Signed-off-by: Rob Gill <rrobgill@protonmail.com>

* formatting fix

Signed-off-by: Rob Gill <rrobgill@protonmail.com>

* Set $l1d_mode to -1 in cases where cpu/vulnerabilities/l1tf is not available

(prevents invalid number error when evaluating [ "$l1d_mode" -ge 1 ])

Signed-off-by: Rob Gill <rrobgill@protonmail.com>

* Update Intel Atom 6 cpu names to align with kernel

Update processor names of atom 6 family processors to align with those from kernel as of October 2018.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/x86/include/asm/intel-family.h?id=f2c4db1bd80720cd8cb2a5aa220d9bc9f374f04e
Update list of known immune processors from
https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/arch/x86/kernel/cpu/common.c?id=f2c4db1bd80720cd8cb2a5aa220d9bc9f374f04e

* Fix unset $l1d_mode

Another instance of unset l1d_mode causing error "./spectre-meltdown-checker.sh: 3867: [: Illegal number:"

* chore: update readme with brief summary of L1tfs

L1tf mitigation and impact details from

https://www.kernel.org/doc/html/latest/admin-guide/l1tf.html and https://blogs.oracle.com/oraclesecurity/intel-l1tf

* typo
2018-12-10 19:33:07 +01:00
Brett T. Warden c45a06f414 Warn on missing kernel info (#265)
Missing kernel information can cause all sorts of false positives or
negatives. This is worth at least a warning, and repeating immediately
following the status.
2018-11-25 18:37:03 +01:00
Brett T. Warden 4a6fa070a4 Fix misdetection of files under Clear Linux (#264) 2018-11-25 18:14:04 +01:00
Stéphane Lesimple c705afe764 bump to v0.40 2018-10-03 20:56:46 +02:00
Stanislav Kholmanskikh 401ccd4b14 Correct aarch64 KPTI dmesg message
As it's seen in unmap_kernel_at_el0 (both the function definition
and its usage in arm64_features[]) from arch/arm64/kernel/cpufeature.c
the kernel reports this string:

CPU features: detected: Kernel page table isolation (KPTI)

or (before commit e0f6429dc1c0 ("arm64: cpufeature: Remove redundant "feature"
in reports")):

CPU features: detected feature: Kernel page table isolation (KPTI)

if KPTI is enabled on the system.

So on let's adjust check_variant3_linux() to make it grep these
strings if executed on an aarch64 platform.

Tested on a Cavium ThunderX2 machine.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
2018-10-03 20:49:55 +02:00
Stanislav Kholmanskikh 55120839dd Fix a typo in check_variant3_linux()
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
2018-10-03 20:49:55 +02:00
Stéphane Lesimple f5106b3c02 update MCEDB from v83 to v84 (no actual change) 2018-09-30 16:57:35 +02:00
Stéphane Lesimple 68289dae1e feat: add --update-builtin-mcedb to update the DB inside the script 2018-09-30 16:56:58 +02:00
Stéphane Lesimple 3b2d529654 feat(l1tf): read & report ARCH_CAPABILITIES bit 3 (SKIP_VMENTRY_L1DFLUSH) 2018-09-29 13:16:07 +02:00
Stéphane Lesimple cbb18cb6b6 fix(l1tf): properly detect status under Red Hat/CentOS kernels 2018-09-29 13:01:13 +02:00
Stéphane Lesimple 299103a3ae some fixes when script is not started as root 2018-09-29 13:01:13 +02:00
Stéphane Lesimple dc5402b349 chore: speed optimization of hw check and indentation fixes 2018-09-29 13:01:13 +02:00
Stéphane Lesimple 90c2ae5de2 feat: use the MCExtractor DB as the reference for the microcode versions
Use platomav's MCExtractor DB as the reference to decide whether our CPU microcode is the latest or not.
We have a builtin version of the DB in the script, but an updated version can be fetched and stored locally with --update-mcedb
2018-09-29 13:01:13 +02:00
Michael Lass 53d6a44754 Fix detection of CVE-2018-3615 (L1TF_SGX) (#253)
* Add another location of Arch Linux ARM kernel

* Fix detection of CVE-2018-3615

We change the value of variantl1tf in the line directly before so its
value will never be "immune". Instead we can directly use the value of
variantl1tf to initialize variantl1tf_sgx.
2018-09-29 11:35:10 +02:00
Stéphane Lesimple 297d890ce9 fix ucode version check regression introduced by fbbb19f under BSD 2018-09-23 15:00:39 +02:00
Stéphane Lesimple 0252e74f94 feat(bsd): implement CVE-2018-3620 and CVE-2018-3646 mitigation detection 2018-09-22 12:26:56 +02:00
Nicolas Sauzede fbbb19f244 Fix cases where a CPU ucode version is not found in $procfs/cpuinfo. (#246)
* Fix cases where a CPU ucode version is not found in $procfs/cpuinfo.

When running whithin a virtual machine, it seems like $procfs/cpuinfo doesn't contain
a 'microcode' line, which triggers a script runtime error.
Fall back to '0x0' in this case, as other part of the script seems to already this
as a default value anyway.

* Double quote to prevent globbing and word splitting.
2018-09-19 22:00:59 +02:00
Stéphane Lesimple 1571a56ce2 feat: add L1D flush cpuid feature bit detection 2018-09-19 09:05:23 +02:00
Stéphane Lesimple 3cf9141601 fix: don't display summary if no CVE was tested (e.g. --hw-only) 2018-09-19 09:04:52 +02:00
Stéphane Lesimple bff38f1b26 BSD: add not-implemented-yet notice for Foreshadow-NG 2018-09-18 22:06:01 +02:00
Stéphane Lesimple b419fe7c63 feat(variant4): properly detect SSBD under BSD 2018-09-18 22:00:32 +02:00
alexvong1995 f193484a4a chore: fix deprecated SPDX license identifier (#249) (#251)
The SPDX license identifier 'GPL-3.0' has been deprecated according to
<https://spdx.org/licenses/GPL-3.0.html>.
2018-09-18 20:00:53 +02:00
Laszlo Toth 349d77b3b6 Fix kernel detection when /lib/kernel exists on a distro (#252)
Commit b48b2177b7 ("feat: Add Clear Linux Distro (#244)") broke kernel
detection for distros using that directory for other purposes than
storing the kernel image.

Example:
 # pacman -Qo /lib/kernel
/usr/lib/kernel/ is owned by mkinitcpio 24-2
/usr/lib/kernel/ is owned by systemd 239.2-1

Signed-off-by: Laszlo Toth <laszlth@gmail.com>
2018-09-18 20:00:20 +02:00
Stéphane Lesimple e589ed7f02 fix: don't test SGX again in check_CVE_2018_3615, already done by is_cpu_vulnerable 2018-09-17 22:28:04 +02:00
Stéphane Lesimple ae1206288f fix: remove some harcoded /proc paths, use $procfs instead 2018-09-17 22:26:20 +02:00
Stéphane Lesimple b44d2b5470 chore: remove 'experimental' notice of Foreshadow from README 2018-09-17 21:48:20 +02:00
Stéphane Lesimple 7b72c20f89 feat(l1tf): explode L1TF in its 3 distinct CVEs 2018-09-17 21:44:48 +02:00
Luis Ponce b48b2177b7 feat: Add Clear Linux Distro (#244)
Add path of Clear Linux kernel binary and kernel config file.
2018-09-15 15:51:49 +02:00
Pierre Gaxatte 8f31634df6 feat(batch): Add a batch short option for one line result (#243)
When using this script on a large amount a machine (via clustershell or
instance) it can be easier to have a very short result on one line
showing only the vulnerabilities
2018-09-15 15:45:10 +02:00
Luis Ponce 96798b1932 chore: add SPDX GPL-3.0 license identifier (#245)
The spectre-meltdown-checker.sh file is missing licensing information.
The SPDX identifier is a legally binding shorthand, which can be
used instead of the full boiler plate text.
2018-09-15 15:33:41 +02:00
Stéphane Lesimple 687ce1a7fa fix: load cpuid module if absent even when /dev/cpu/0/cpuid is there 2018-09-08 23:15:50 +02:00
Stéphane Lesimple 80e0db7cc4 fix: don't show erroneous ucode version when latest version is unknown (fixes #238) 2018-08-28 20:51:46 +02:00
David Guglielmi e8890ffac6 feat(config): support for genkernel kernel config file (#239)
Add support for distributions using genkernel.
2018-08-28 20:24:37 +02:00
Stéphane Lesimple b2f64e1132 fix README after merge 2018-08-18 12:09:34 +02:00
unrealization 42a3a61f1d Slightly improved Docker configuration (#230)
* Listed the required volumes in the Dockerfile.

* Added docker-compose.yml for convenience as users won't need to manually
specify volumes and stuff when running through docker-compose.

Adjusted README.md to reflect this change.
2018-08-18 12:06:16 +02:00
Karsten Weiss afb36c519d Fix typo: 'RBS filling' => 'RSB filling' (#237) 2018-08-18 12:05:17 +02:00
Stéphane Lesimple 0009c0d473 fix: --batch now implies --no-color to avoid colored warnings 2018-08-18 12:04:18 +02:00
Stéphane Lesimple dd67fd94d7 feat: add FLUSH_CMD MSR availability detection (part of L1TF mitigation) 2018-08-16 19:05:09 +02:00
Stéphane Lesimple 339ad31757 fix: add missing l1tf CPU vulnerability display in hw section 2018-08-16 15:19:29 +02:00
Stéphane Lesimple 794c5be1d2 feat: add optional git describe support to display inter-release version numbers 2018-08-16 15:18:47 +02:00
Stéphane Lesimple a7afc585a9 fix several incorrect ucode version numbers 2018-08-16 10:51:55 +02:00
Stéphane Lesimple fc1dffd09a feat: implement detection of latest known versions of intel microcodes 2018-08-15 12:53:49 +02:00
Stéphane Lesimple e942616189 feat: initial support for L1TF 2018-08-15 12:05:08 +02:00
Stéphane Lesimple 360be7b35f fix: hide arch_capabilities_msr_not_read warning under !intel 2018-08-13 15:42:56 +02:00
Stéphane Lesimple 5f59257826 bump to v0.39 2018-08-13 15:33:03 +02:00
Stéphane Lesimple 92d59cbdc1 chore: adjust some comments, add 2 missing inits 2018-08-11 10:31:10 +02:00
Stéphane Lesimple 4747b932e7 feat: add detection of RSBA feature bit and adjust logic accordingly 2018-08-10 10:26:23 +02:00
Stéphane Lesimple 860023a806 fix: ARCH MSR was not read correctly, preventing proper SSB_NO and RDCL_NO detection 2018-08-10 10:26:23 +02:00
Stéphane Lesimple ab67a9221d feat: read/write msr now supports msr-tools or perl as dd fallback 2018-08-10 10:26:23 +02:00
0x9fff00 f4592bf3a8 Add Arch armv5/armv7 kernel image location (#227) 2018-08-09 22:13:30 +02:00
Stéphane Lesimple be15e47671 chore: setting master to v0.38+ 2018-08-09 14:25:22 +02:00
Nathan Parsons d3481d9524 Add support for the kernel being within a btrfs subvolume (#226)
- /boot may be within a named root subvolume (eg. "/@/boot")
- /boot may be in its own subvolume (eg. "/@boot")
2018-08-09 14:00:35 +02:00
Stéphane Lesimple 21af561148 bump to v0.38 2018-08-07 10:55:50 +02:00
Stéphane Lesimple cb740397f3 feat(arm32): add spectrev1 mitigation detection 2018-08-07 10:42:03 +02:00
Stéphane Lesimple 84195689af change: default to --no-explain, use --explain to get detailed mitigation help 2018-08-04 16:31:41 +02:00
Stéphane Lesimple b637681fa8 fix: debug output: msg inaccuracy for ARM checks 2018-08-04 16:19:54 +02:00
Stéphane Lesimple 9316c30577 fix: armv8: models < 0xd07 are not vulnerable 2018-08-04 16:19:54 +02:00
Lily Wilson f9dd9d8cb9 add guess for archlinuxarm aarch64 kernel image on raspberry pi 3 (#222) 2018-08-01 00:15:52 +02:00
Stéphane Lesimple 0f0d103a89 fix: correctly init capabilities_ssb_no var in all cases 2018-07-26 10:18:14 +02:00
Stéphane Lesimple b262c40541 fix: remove spurious character after an else statement 2018-07-25 21:55:50 +02:00
Stéphane Lesimple cc2910fbbc fix: read_cpuid: don't use iflag=skip_bytes for compat with old dd versions
This closes #215 #199 #193
2018-07-23 09:12:30 +02:00
manish jaggi 30c4a1f6d2 arm64: cavium: Add CPU Implementer Cavium (#216)
This patch adds 0x43 check for cavium implementor id in function
parse_cpu_details. Also adds that Cavium Soc is not vulnerable to variant 3/3a

Signed-off-by: Manish Jaggi <manish.jagg@cavium.com>
2018-07-22 19:06:19 +02:00
Stéphane Lesimple cf06636a3f fix: prometheus output: use printf for proper \n interpretation (#204) 2018-06-21 23:35:51 +02:00
Stéphane Lesimple 60077c8d12 fix(arm): rewrite vuln logic from latest arm statement for Cortex A8 to A76 2018-06-21 23:24:18 +02:00
Rob Gill c181978d7c fix(arm): Updated arm cortex status (#209)
* Cortex A8 Vulnerable

Arm Cortex A8 is vulnerable to variants 1 & 2  (https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability)

Part number is 0xc08 (https://developer.arm.com/docs/ddi0344/b/system-control-coprocessor/system-control-coprocessorregisters/c0-main-id-register)

False negative reported by @V10lator in #206

* ARM Cortex A12 Vulnerable to 1&2

https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability

* A76 vulnerable to variant 4

All arch 8 cortex A57-A76 are vulnerable to variant 4.

https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability

* Whitelist variant4 nonvuln Arms

* ARM Cortex Whitelist & Cumulative Blacklist

Applies all information about vulnerabilities of ARM Cortex processors (from https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability).

Whitelist & blacklist approach, using both vulnerable and non vulnerable status for each identified CPU, with vulnerabilities tracked cumulatively for multi CPU systems.
2018-06-16 12:14:39 +02:00
Jan 9a6406a9a2 chore: add docker support (#203) 2018-06-14 20:25:35 +02:00
Rob Gill 5962d20ba7 fix(variant4): whitelist from common.c::cpu_no_spec_store_bypass (#202)
* variant4 from common.c::cpu_no_spec_store_bypass

Variant 4 - Add function to 'whitelist' the hand-full of CPUs unaffected by speculative store bypass. 

This would allow improved determination of variant 4 status ( #189 ) of immune CPUs while waiting for the 4.17/stable patches to be backported to distro kernels.

Source of cpu list : https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/common.c#n945)
Modeled after is_cpu_specex_free()

* amd families fix

amd families are reported by parse_cpu_details() in decimal

* remove duplicates

Only list processors which speculate and are immune to variant 4.
Avoids duplication with non-speculating CPUs listed in is_cpu_specex_free()
2018-05-27 15:14:29 +02:00
Rob Gill 17a3488505 fix(help): add missing references to variants 3a & 4 (#201) 2018-05-24 16:35:57 +02:00
Stéphane Lesimple e54e8b3e84 chore: remove warning in README, fix display indentation 2018-05-24 16:32:53 +02:00
Stéphane Lesimple 39c778e3ac fix(amd): AMD families 0x15-0x17 non-arch MSRs are a valid way to control SSB 2018-05-23 23:08:07 +02:00
Stéphane Lesimple 2cde6e4649 feat(ssbd): add detection of proper CPUID bits on AMD 2018-05-23 22:50:52 +02:00
Stéphane Lesimple f4d51e7e53 fix(variant4): add another detection way for Red Hat kernel 2018-05-23 22:47:54 +02:00
Stéphane Lesimple 85d46b2799 feat(variant4): add more detailed explanations 2018-05-23 21:08:58 +02:00
Stéphane Lesimple 61e02abd0c feat(variant3a): detect up to date microcode 2018-05-23 21:08:08 +02:00
Stéphane Lesimple 114756fab7 fix(amd): not vulnerable to variant3a 2018-05-23 20:38:43 +02:00
Rob Gill ea75969eb7 fix(help): Update variant options in usage message (#200) 2018-05-22 15:54:25 +02:00
Stéphane Lesimple ca391cbfc9 fix(variant2): correctly detect IBRS/IBPB in SLES kernels 2018-05-22 12:06:46 +02:00
Stéphane Lesimple 68af5c5f92 feat(variant4): detect SSBD-aware kernel 2018-05-22 12:05:46 +02:00
Stéphane Lesimple 19be8f79eb doc: update README with some info about variant3 and variant4 2018-05-22 09:43:29 +02:00
Stéphane Lesimple f75cc0bb6f feat(variant4): add sysfs mitigation hint and some explanation about the vuln 2018-05-22 09:39:11 +02:00
Stéphane Lesimple f33d65ff71 feat(variant3a): add information about microcode-sufficient mitigation 2018-05-22 09:38:29 +02:00
Stéphane Lesimple 725eaa8bf5 feat(arm): adjust vulnerable ARM CPUs for variant3a and variant4 2018-05-22 09:19:29 +02:00
Stéphane Lesimple c6ee0358d1 feat(variant4): report SSB_NO CPUs as not vulnerable 2018-05-22 09:18:30 +02:00
Stéphane Lesimple 22d0b203da fix(ssb_no): rename ssbd_no to ssb_no and fix shift 2018-05-22 00:38:31 +02:00
Stéphane Lesimple 3062a8416a fix(msg): add missing words 2018-05-22 00:10:08 +02:00
Stéphane Lesimple 6a4318addf feat(variant3a/4): initial support for 2 new CVEs 2018-05-22 00:06:56 +02:00
Stéphane Lesimple c19986188f fix(variant2): adjust detection for SLES kernels 2018-05-19 09:53:12 +02:00
Rob Gill 7e4899bcb8 ibrs can't be enabled on no ibrs cpu (#195)
* ibrs can't be enabled on no ibrs cpu

If the cpu is identified, and does not support SPEC_CTRL or IBRS, then ibrs can't be enabled, even if supported by the kernel.
Instead of reporting IBRS enabled and active UNKNOWN, report IBRS enabled and active NO.
2018-05-17 15:39:48 +02:00
rrobgill 5cc77741af Update spectre-meltdown-checker.sh 2018-05-05 13:00:44 +02:00
rrobgill 1c0f6d9580 cpuid and msr module check
This adds a check before loading the cpuid and msr modules under linux, ensuring they are not unloaded in exit_cleanup() if they were initially present.
2018-05-05 13:00:44 +02:00
Onno Zweers 4acd0f647a Suggestion to change VM to a CPU with IBRS capability 2018-04-20 20:35:12 +02:00
Stéphane Lesimple fb52dbe7bf set master branch to v0.37+ 2018-04-20 20:34:42 +02:00
Stéphane Lesimple edebe4dcd4 bump to v0.37 2018-04-18 23:51:45 +02:00
Stéphane Lesimple 83ea78f523 fix: arm: also detect variant 1 mitigation when using native objdump 2018-04-17 18:50:32 +02:00
Stéphane Lesimple 602b68d493 fix(spectrev2): explain that retpoline is possible for Skylake+ if there is RSB filling, even if IBRS is still better 2018-04-16 09:27:28 +02:00
Stéphane Lesimple 97bccaa0d7 feat: rephrase IBPB warning when only retpoline is enabled in non-paranoid mode 2018-04-16 09:13:25 +02:00
Stéphane Lesimple 68e619b0d3 feat: show RSB filling capability for non-Skylake in verbose mode 2018-04-16 09:08:25 +02:00
Stéphane Lesimple a6f4475cee feat: make IBRS_FW blue instead of green 2018-04-16 09:07:54 +02:00
Stéphane Lesimple 223f5028df feat: add --paranoid to choose whether we require IBPB 2018-04-15 23:05:30 +02:00
Stéphane Lesimple c0108b9690 fix(spectre2): don't explain how to fix when NOT VULNERABLE 2018-04-15 20:55:55 +02:00
Stéphane Lesimple a3016134bd feat: make RSB filling support mandatory for Skylake+ CPUs 2018-04-15 20:55:31 +02:00
Stéphane Lesimple 59d85b39c9 feat: detect RSB filling capability in the kernel 2018-04-15 20:55:01 +02:00
Stéphane Lesimple baaefb0c31 fix: remove shellcheck warnings 2018-04-11 22:24:03 +02:00
Igor Lubashev d452aca03a fix: invalid bash syntax when ibpb_enabled or ibrs_enabled are empty 2018-04-11 10:29:42 +02:00
Stéphane Lesimple 10b8d94724 feat: detect latest Red Hat kernels' RO ibpb_enabled knob 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 8606e60ef7 refactor: no longer display the retoline-aware compiler test when we can't tell for sure 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 6a48251647 fix: regression in 51aeae25, when retpoline & ibpb are enabled 2018-04-10 22:51:45 +02:00
Stéphane Lesimple f4bf5e95ec fix: typos 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 60eac1ad43 feat: also do PTI performance check with (inv)pcid for BSD 2018-04-10 22:51:45 +02:00
Stéphane Lesimple b3cc06a6ad fix regression introduced by 82c25dc 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 5553576e31 feat(amd/zen): re-introduce IBRS for AMD except ZEN family 2018-04-10 22:51:45 +02:00
Stéphane Lesimple e16ad802da feat(ibpb=2): add detection of SMT before concluding the system is not vulnerable 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 29c294edff feat(bsd): explain how to mitigate variant2 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 59714011db refactor: IBRS_ALL & RDCL_NO are Intel-only 2018-04-10 22:51:45 +02:00
Stéphane Lesimple 51e8261a32 refactor: separate hw checks for Intel & AMD 2018-04-10 22:49:28 +02:00
Stéphane Lesimple 2a4bfad835 refactor: add is_amd and is_intel funcs 2018-04-10 22:49:28 +02:00
Stéphane Lesimple 7e52cea66e feat(spectre2): refined how status of this vuln is decided and more precise explanations on how to fix 2018-04-10 22:49:28 +02:00
Benjamin Bouvier 417d7aab91 Fix trailing whitespace and mixed indent styles; 2018-04-10 22:42:47 +02:00
Sylvestre Ledru 67bf761029 Fix some user facing typos with codespell -w -q3 . 2018-04-08 18:44:13 +02:00
Stéphane Lesimple 0eabd266ad refactor: decrease default verbosity for some tests 2018-04-05 22:20:16 +02:00
Stéphane Lesimple b77fb0f226 fix: don't override ibrs/ibpb results with later tests 2018-04-05 22:04:20 +02:00
Stéphane Lesimple 89c2e0fb21 fix(amd): show cpuinfo and ucode details 2018-04-05 21:39:27 +02:00
Stéphane Lesimple b88f32ed95 feat: print raw cpuid, and fetch ucode version under BSD 2018-04-05 00:07:12 +02:00
Stéphane Lesimple 7a4ebe8009 refactor: rewrite read_cpuid to get more common code parts between BSD and Linux 2018-04-05 00:06:24 +02:00
Stéphane Lesimple 0919f5c236 feat: add explanations of what to do when a vulnerability is not mitigated 2018-04-05 00:03:04 +02:00
Stéphane Lesimple de02dad909 feat: rework Spectre V2 mitigations detection w/ latest vanilla & Red Hat 7 kernels 2018-04-05 00:01:54 +02:00
Stéphane Lesimple 07484d0ea7 add dump of variables at end of script in debug mode 2018-04-04 23:58:15 +02:00
Stéphane Lesimple a8b557b9e2 fix(cpu): skip CPU checks if asked to (--no-hw) or if inspecting a kernel of another architecture 2018-04-03 19:36:28 +02:00
Stéphane Lesimple 619b2749d8 fix(sysfs): only check for sysfs for spectre2 when in live mode 2018-04-03 19:32:36 +02:00
Stéphane Lesimple 94857c983d update readme 2018-04-03 16:00:36 +02:00
Stéphane Lesimple 056ed00baa feat(arm): detect spectre variant 1 mitigation 2018-04-03 15:52:25 +02:00
Stéphane Lesimple aef99d20f3 fix(pti): when PTI activation is unknown, don't say we're vulnerable 2018-04-03 12:45:17 +02:00
Stéphane Lesimple e2d7ed2243 feat(arm): support for variant2 and meltdown mitigation detection 2018-04-01 17:50:18 +02:00
Stéphane Lesimple eeaeff8ec3 set version to v0.36+ for master branch between releases 2018-04-01 17:45:01 +02:00
Stéphane Lesimple f5269a362a feat(bsd): add retpoline detection for BSD 2018-04-01 17:42:29 +02:00
Stéphane Lesimple f3883a37a0 fix(xen): adjust message for DomUs w/ sysfs 2018-03-31 13:44:04 +02:00
Stéphane Lesimple b6fd69a022 release: v0.36 2018-03-27 23:08:38 +02:00
Stéphane Lesimple 7adb7661f3 enh: change colors and use red only to report vulnerability 2018-03-25 18:15:08 +02:00
Stéphane Lesimple c7892e3399 update README.md 2018-03-25 14:18:39 +02:00
Stéphane Lesimple aa74315df4 feat: speed up kernel version detection 2018-03-25 13:42:19 +02:00
Stéphane Lesimple 0b8a09ec70 fix: mis adjustments for BSD compat 2018-03-25 13:26:00 +02:00
Stéphane Lesimple b42d8f2f27 fix(write_msr): use /dev/zero instead of manually echoing zeroes 2018-03-25 12:53:50 +02:00
Stéphane Lesimple f191ec7884 feat: add --hw-only to only show CPU microcode/cpuid/msr details 2018-03-25 12:48:37 +02:00
Stéphane Lesimple 28da7a0103 misc: message clarifications 2018-03-25 12:48:03 +02:00
Stéphane Lesimple ece25b98a1 feat: implement support for NetBSD/FreeBSD/DragonFlyBSD 2018-03-25 12:28:02 +02:00
Stéphane Lesimple 889172dbb1 feat: add special extract_vmlinux mode for old RHEL kernels 2018-03-25 11:55:44 +02:00
Stéphane Lesimple 37ce032888 fix: bypass MSR/CPUID checks for non-x86 CPUs 2018-03-25 11:55:44 +02:00
Stéphane Lesimple 701cf882ad feat: more robust validation of extracted kernel image 2018-03-25 11:55:44 +02:00
Stéphane Lesimple 6a94c3f158 feat(extract_vmlinux): look for ELF magic in decompressed blob and cut at found offset 2018-03-25 11:55:42 +02:00
Stéphane Lesimple 2d993812ab feat: add --prefix-arch for cross-arch kernel inspection 2018-03-25 11:55:10 +02:00
Stéphane Lesimple 4961f8327f fix(ucode): fix blacklist detection for some ucode versions 2018-03-19 12:09:39 +01:00
Alex ecdc448531 Check MSR in each CPU/Thread (#136) 2018-03-17 17:17:15 +01:00
Stéphane Lesimple 12ea49fe0c fix(kvm): properly detect PVHVM mode (fixes #163) 2018-03-16 18:29:58 +01:00
Stéphane Lesimple 053f1613de fix(doc): use https:// URLs in the script comment header 2018-03-16 18:24:59 +01:00
Stéphane Lesimple bda18d04a0 fix: pine64: re-add vmlinuz location and some error checks 2018-03-10 16:02:44 +01:00
Stéphane Lesimple 2551295541 doc: use https URLs 2018-03-10 15:20:07 +01:00
Stéphane Lesimple d5832dc1dc feat: add ELF magic detection on kernel image blob for some arm64 systems 2018-03-10 14:57:25 +01:00
Stéphane Lesimple d2f46740e9 feat: enhance kernel image version detection for some old kernels 2018-03-10 14:57:25 +01:00
Sam Morris 2f6a6554a2 Produce output for consumption by prometheus-node-exporter
A report of all vulnerable machines to be produced with a query such as:

    spexec_vuln_status{status!="OK"}
2018-02-27 11:08:39 +01:00
Stéphane Lesimple 30842dd9c0 release: bump to v0.35 2018-02-16 10:35:49 +01:00
Stéphane Lesimple b4ac5fcbe3 feat(variant2): better explanation when kernel supports IBRS but CPU does not 2018-02-16 10:34:01 +01:00
Stéphane Lesimple fef380d66f feat(readme): add quick run section 2018-02-15 21:19:49 +01:00
Stéphane Lesimple 55a6fd3911 feat(variant1): better detection for Red Hat/Ubuntu patch 2018-02-15 21:19:49 +01:00
Sylvestre Ledru 35c8a63de6 Remove the color in the title 2018-02-15 20:21:00 +01:00
Stéphane Lesimple 5f914e555e fix(xen): declare Xen's PTI patch as a valid mitigation for variant3 2018-02-14 14:24:55 +01:00
Stéphane Lesimple 66dce2c158 fix(ucode): update blacklisted ucodes list from latest Intel info 2018-02-14 14:14:16 +01:00
Calvin Walton 155cac2102 Teach checker how to find kernels installed by systemd kernel-install 2018-02-10 20:51:33 +01:00
Stéphane Lesimple 22cae605e1 fix(retpoline): remove the "retpoline enabled" test
This test worked for some early versions of the retpoline
implementation in vanilla kernels, but the corresponding
flag has been removed from /proc/cpuinfo in latest kernels.
The full information is available in /sys instead, which
was already implemented in the script.
2018-02-09 20:12:33 +01:00
Stéphane Lesimple eb75e51975 fix(ucode): update list of blacklisted ucodes from 2018-02-08 Intel document
Removed 2 ucodes and added 2 other ones
2018-02-09 19:56:27 +01:00
積丹尼 Dan Jacobson 253e180807 Update spectre-meltdown-checker.sh
Dots better than colon for indicating waiting.
2018-02-06 19:02:56 +01:00
Stéphane Lesimple 5d6102a00e enh: show kernel version in offline mode 2018-02-02 11:27:04 +01:00
Stéphane Lesimple a2dfca671e feat: detect disrepancy between found kernel image and running kernel 2018-02-02 11:13:54 +01:00
Stéphane Lesimple 36bd80d75f enh: speedup by not decompressing kernel on --sysfs-only 2018-02-02 11:13:31 +01:00
Stéphane Lesimple 1834dd6201 feat: add skylake era cpu detection routine 2018-02-02 11:12:10 +01:00
Stéphane Lesimple 3d765bc703 enh: lazy loading of cpu informations 2018-02-02 11:11:51 +01:00
Stéphane Lesimple 07afd95b63 feat: better cleanup routine on exit & interrupt 2018-02-02 11:09:36 +01:00
Stéphane Lesimple b7a10126d1 fix: ARM CPU display name & detection
Fix ARM CPU display name, and properly
detect known vulnerable ARM CPUs when
multiple different model cores are
present (mostly Android phones)
2018-02-02 11:00:23 +01:00
Stéphane Lesimple 6346a0deaa fix: --no-color workaround for android's sed 2018-02-02 10:59:49 +01:00
Stéphane Lesimple 8106f91981 release: bump to v0.34 2018-01-31 16:28:54 +01:00
Stéphane Lesimple b1fdf88f28 enh: display ucode info even when not blacklisted 2018-01-31 16:21:32 +01:00
Stéphane Lesimple 4d29607630 cleanup: shellcheck pass 2018-01-31 16:15:20 +01:00
Stéphane Lesimple 0267659adc cleanup: remove superseded atom detection code
This is now handled properly by checking the CPU
vendor, family, model instead of looking for the
commercial name of the CPU in /proc/cpuinfo
2018-01-31 16:15:20 +01:00
Stéphane Lesimple 247b176882 feat: detect known speculative-execution free CPUs
Based on a kernel patch that has been merged to Linus' tree.
Some of the detections we did by grepping the model name
will probably no longer be needed.
2018-01-31 16:15:20 +01:00
Stéphane Lesimple bcae8824ec refacto: create a dedicated func to read cpuid bits 2018-01-31 16:15:20 +01:00
Stéphane Lesimple 71e7109c22 refacto: move cpu discovery bits to a dedicated function 2018-01-31 16:15:20 +01:00
Stéphane Lesimple aa18b51e1c fix(variant1): smarter lfence check
Instead of just counting the number of LFENCE
instructions, now we're only counting the those
that directly follow a jump instruction.
2018-01-31 14:34:54 +01:00
Stéphane Lesimple b738ac4bd7 fix: regression introduced by previous commit
449: ./spectre-meltdown-checker.sh: 3: parameter not set
This happened only on blacklisted microcodes, fixed by
adding set +u before the return
2018-01-31 12:13:50 +01:00
Stéphane Lesimple 799ce3eb30 update blacklisted ucode list from kernel source 2018-01-31 11:26:23 +01:00
Stéphane Lesimple f1e18c136f doc(disclaimer): Spectre affects all software
Add a paragraph in the disclaimer stating that this tool focuses
on the kernel side of things, and that for Spectre, any software
might be vulnerable.
2018-01-30 14:37:52 +01:00
Stéphane Lesimple e05ec5c85f feat(variant1): detect vanilla mitigation
Implement detection of mitigation for Variant 1 that is
being pushed on vanilla kernel.
Current name of the patch:
"spectre variant1 mitigations for tip/x86/pti" (v6)
Also detect some distros that already backported this
patch without modifying the vulnerabilities sysfs hierarchy.
This detection is more reliable than the LFENCE one, trust
it and skip the LFENCE heuristic if a match is found.
2018-01-30 12:55:34 +01:00
Stéphane Lesimple 6e544d6055 fix(cpu): Pentium Exxxx are vulnerable to Meltdown 2018-01-29 11:18:15 +01:00
Stéphane Lesimple 90a65965ff adjust: show how to enable IBRS/IBPB in -v only 2018-01-29 11:06:15 +01:00
Stéphane Lesimple 9b53635eda refacto: fix shellcheck warnings for better compat
Now `shellcheck -s sh` no longer shows any warnings.
This should improve compatibility with exotic shells
as long as they're POSIX compliant.
2018-01-29 10:34:08 +01:00
Joseph Mulloy 7404929661 Fix printing of microcode to use cpuinfo values
The values used should be the ones that come from cpuinfo instead of
the test values. The following line will print the last tuple tested
instead of the actual values of the CPU.

Line 689: _debug "is_ucode_blacklisted: no ($model/$stepping/$ucode)"
2018-01-26 18:23:18 +01:00
Stéphane Lesimple bf46fd5d9b update: new screenshots for README.md 2018-01-26 15:15:24 +01:00
Stéphane Lesimple 0798bd4c5b fix: report arch_capabilities as NO when no MSR
When the arch_capabilities MSR is not there, it means
that all the features it might advertise can be considered
as NO instead of UNKNOWN
2018-01-26 14:55:01 +01:00
Stéphane Lesimple 42094c4f8b release: v0.33 2018-01-26 14:20:29 +01:00
Stéphane Lesimple 03d2dfe008 feat: add blacklisted Intel ucode detection
Some Intel microcodes are known to cause instabilities
such as random reboots. Intel advises to revert to a
previous version if a newer one that fixes those issues
is not available. Detect such known bad microcodes.
2018-01-26 14:19:54 +01:00
Stéphane Lesimple 9f00ffa5af fix: fallback to UNKNOWN when we get -EACCES
For detection of IBRS_ALL and RDCL_NO, fallback to
UNKNOWN when we were unable to read the CPUID or MSR.
2018-01-26 14:16:34 +01:00
Matthieu Cerda 7f0d80b305 xen: detect if the host is a Xen Dom0 or PV DomU (fixes #83) 2018-01-25 11:04:30 +01:00
Stéphane Lesimple d1c1f0f0f0 fix(batch): fix regression introduced by acf12a6
In batch mode, $echo_cmd was not initialized early
enough, and caused this error:
./spectre-meltdown-checker.sh: 899: ./spectre-meltdown-checker.sh: -ne: not found
Fix it by initing echo_cmd unconditionally at the start
2018-01-24 17:57:19 +01:00
Stéphane Lesimple acf12a6d2d feat(cpu) add STIBP, RDCL_NO, IBRS_ALL checks
Move all the CPU checks to their own section,
for clarity. We now check for IBRS, IBPB, STIBP,
RDCL_NO and IBRS_ALL. We also show whether the
system CPU is vulnerable to the three variants,
regardless of the fact that mitigations are in
place or not, which is determined in each vuln-
specific section.
2018-01-24 14:44:16 +01:00
Stéphane Lesimple b45e40bec8 feat(stibp): add STIBP cpuid feature check 2018-01-24 12:19:02 +01:00
Stéphane Lesimple 3c1d452c99 fix(cpuid): fix off-by-one SPEC_CTRL bit check 2018-01-24 12:18:56 +01:00
Stéphane Lesimple 53b9eda040 fix: don't make IBPB mandatory when it's not there
On some kernels there could be IBRS support but not
IBPB support, in that case, don't report VULN just
because IBPB is not enabled when IBRS is
2018-01-24 09:04:25 +01:00
Stéphane Lesimple 3b0ec998b1 fix(cosmetic): tiny msg fixes 2018-01-24 09:04:25 +01:00
Stéphane Lesimple d55bafde19 fix(cpu): trust is_cpu_vulnerable even w/ debugfs
For variant3 under AMD, the debugfs vulnerabilities hierarchy
flags the system as Vulnerable, which is wrong. Trust our own
is_cpu_vulnerable() func in that case
2018-01-24 09:04:25 +01:00
Stéphane Lesimple 147462c0ab fix(variant3): do our checks even if sysfs is here 2018-01-24 09:04:25 +01:00
Stéphane Lesimple ddc7197b86 fix(retpoline): retpoline-compiler detection
When kernel is not compiled with retpoline option, doesn't
have the sysfs vulnerability hierarchy and our heuristic to
detect a retpoline-aware compiler didn't match, change result
for retpoline-aware compiler detection from UNKNOWN to NO.
When CONFIG_RETPOLINE is not set, a retpoline-aware compiler
won't produce different asm than a standard one anyway.
2018-01-24 09:04:25 +01:00
Stéphane Lesimple e7aa3b9d16 feat(retpoline): check if retpoline is enabled
Before we would just check if retpoline was compiled
in, now we also check that it's enabled at runtime
(only in live mode)
2018-01-24 09:04:25 +01:00
Stéphane Lesimple ff5c92fa6f feat(sysfs): print details even with sysfs
Before, when the /sys kernel vulnerability interface
was available, we would bypass all our tests and just
print the output of the vulnerability interface. Now,
we still rely on it when available, but we run our
checks anyway, except for variant 1 where the current
method of mitigation detection doesn't add much value
to the bare /sys check
2018-01-24 09:04:25 +01:00
Stéphane Lesimple 443d9a2ae9 feat(ibpb): now also check for IBPB on variant 2
In addition to IBRS (and microcode support), IBPB
must be used to mitigate variant 2, if retpoline
support is not available. The vulnerability status
of a system will be defined as "non vulnerable"
if IBRS and IBPB are both enabled, or if IBPB
is enabled with a value of 2 for RedHat kernels,
see https://access.redhat.com/articles/3311301
2018-01-24 09:04:25 +01:00
Stéphane Lesimple 3e454f1817 fix(offline): report unknown when too few info
In offline mode, in the worst case where an invalid
config file is given, and we have no vmlinux image
nor System.map, the script was reporting Variant 2
and Variant 3 as vulnerable in the global status.
Replace this by a proper pair of UNKNOWNs
2018-01-23 22:20:34 +01:00
Stéphane Lesimple c8a25c5d97 feat: detect invalid kconfig files 2018-01-23 21:48:19 +01:00
Stéphane Lesimple 40381349ab fix(dmesg): detect when dmesg is truncated
To avoid false negatives when looking for a message
in dmesg, we were previously also grepping in known
on-disk archives of dmesg (dmesg.log, kern.log).
This in turn caused false positives because we have no
guarantee that we're grepping the dmesg of the current
running kernel. Hence we now only look in the live
`dmesg`, detect if it has been truncated, and report
it to the user.
2018-01-21 16:26:08 +01:00
Stéphane Lesimple 0aa5857a76 fix(cpu): Pentium Exxxx series are not vulnerable
Pentium E series are not in the vulnerable list from
Intel, and Spectre2 PoC reportedly doesn't work on
an E5200
2018-01-21 16:13:17 +01:00
Stéphane Lesimple b3b7f634e6 fix(display): use text-mode compatible colors
in text-mode 80-cols TERM=linux terminals, colors
were not displaying properly, one had to use
--no-color to be able to read some parts of the
text.
2018-01-21 12:32:22 +01:00
Stéphane Lesimple 263ef65fec bump to v0.32 2018-01-20 12:49:12 +01:00
Stéphane Lesimple a1bd233c49 revert to a simpler check_vmlinux() 2018-01-20 12:26:26 +01:00
Stéphane Lesimple de6590cd09 cache is_cpu_vulnerable result for performance 2018-01-20 12:24:23 +01:00
Stéphane Lesimple 56d4f82484 is_cpu_vulnerable: implement check for multi-arm systems 2018-01-20 12:24:23 +01:00
Stéphane Lesimple 7fa2d6347b check_vmlinux: when readelf doesn't work, try harder with another way 2018-01-20 12:23:55 +01:00
Stéphane Lesimple 3be5e90481 be smarter to find a usable echo command 2018-01-20 12:23:55 +01:00
Stéphane Lesimple 995620a682 add pine64 vmlinuz location 2018-01-20 12:23:19 +01:00
Stéphane Lesimple 193e0d8d08 arm: cosmetic fix for name and handle aarch64 2018-01-20 12:22:48 +01:00
Stéphane Lesimple 72ef94ab3d ARM: display a friendly name instead of empty string 2018-01-20 12:22:48 +01:00
Harald Hoyer ccc0453df7 search in /lib/modules/$(uname -r) for vmlinuz, config, System.map
On Fedora machines /lib/modules/$(uname -r) has all the files.
2018-01-20 11:19:34 +01:00
Stéphane Lesimple 14ca49a042 Atom N270: implement another variation 2018-01-19 18:47:38 +01:00
Stéphane Lesimple db357b8e25 CoreOS: remove ephemeral install of a non-used package 2018-01-18 10:17:25 +01:00
Stéphane Lesimple 42a57dd980 add kern.log as another backend of dmesg output 2018-01-17 17:17:39 +01:00
Stéphane Lesimple 5ab95f3656 fix(atom): don't use a pcre regex, only an extended one 2018-01-17 12:01:13 +01:00
Stéphane Lesimple 5b6e39916d fix(atom): properly detect Nxxx Atom series 2018-01-17 11:07:47 +01:00
Willy Sudiarto Raharjo 556951d5f0 Add Support for Slackware.
Signed-off-by: Willy Sudiarto Raharjo <willysr@gmail.com>
2018-01-16 11:55:03 +01:00
Stéphane Lesimple 7a88aec95f Implement CoreOS compatibility mode (#84)
* Add special CoreOS compatibility mode
* CoreOS: refuse --coreos if we're not under CoreOS
* CoreOS: warn if launched without --coreos option
* is_coreos: make stderr silent
* CoreOS: tiny adjustments
2018-01-16 10:33:01 +01:00
Stéphane Lesimple bd18323d79 bump to v0.31 to reflect changes 2018-01-14 22:34:09 +01:00
Stéphane Lesimple b89d67dd15 meltdown: detecting Xen PV, reporting as not vulnerable 2018-01-14 22:31:21 +01:00
Stéphane Lesimple 704e54019a is_cpu_vulnerable: add check for old Atoms 2018-01-14 21:32:56 +01:00
Stéphane Lesimple d96093171a verbose: add PCID check for performance impact of PTI 2018-01-14 17:18:34 +01:00
Stéphane Lesimple dcc4488340 Merge pull request #80 from speed47/cpuid_spec_ctrl
v0.30, cpuid spec ctrl and other enhancements
2018-01-14 16:48:02 +01:00
Stéphane Lesimple 32e3fe6c07 bump to v0.30 to reflect changes 2018-01-14 16:45:59 +01:00
Stéphane Lesimple f488947d43 Merge pull request #79 from andir/add-nixos
add support for NixOS kernel
2018-01-14 16:40:10 +01:00
Stéphane Lesimple 71213c11b3 ibrs: check for spec_ctrl_ibrs in cpuinfo 2018-01-14 16:36:51 +01:00
Andreas Rammhold 2964c4ab44 add support for NixOS kernel
this removes the need to specify the kernel version manually on NixOS
2018-01-14 16:18:29 +01:00
Stéphane Lesimple 749f432d32 also check for spec_ctrl flag in cpuinfo 2018-01-14 15:47:51 +01:00
Stéphane Lesimple a422b53d7c also check for cpuinfo flag 2018-01-14 15:47:51 +01:00
Stéphane Lesimple c483a2cf60 check spec_ctrl support using cpuid 2018-01-14 15:47:51 +01:00
Stéphane Lesimple dead0054a4 fix: proper detail msg in vuln status 2018-01-14 15:47:22 +01:00
Stéphane Lesimple 8ed7d465aa Merge pull request #77 from speed47/exitcode
proper return codes regardless of the batch mode
2018-01-14 14:25:12 +01:00
Stéphane Lesimple e5e4851d72 proper return codes regardless of the batch mode 2018-01-14 14:24:31 +01:00
Stéphane Lesimple 7f92717a2c add info about accuracy when missing kernel files 2018-01-13 13:59:17 +01:00
Stéphane Lesimple b47d505689 AMD now vuln to variant2 (as per their stmt) 2018-01-13 13:35:31 +01:00
Corey Hickey 4a2d051285 minor is_cpu_vulnerable() changes (#71)
* correct is_cpu_vulnerable() comment

As far as I can tell, the function and usage are correct for the comment
to be inverted.

Add a clarifying note as to why the value choice makes sense.

* exit on invalid varient

If this happens, it's a bug in the script. None of the calling code
checks for status 255, so don't let a scripting bug cause a false
negative.

* no need to set vulnerable CPUs

According to comment above this code:
'by default, everything is vulnerable, we work in a "whitelist" logic here.'
2018-01-13 13:16:37 +01:00
Sylvestre Ledru f3551b9734 Only show the name of the script, not the full path (#72) 2018-01-13 13:14:19 +01:00
Sylvestre Ledru 45b98e125f fix some typos (#73) 2018-01-13 13:13:40 +01:00
Stéphane Lesimple dce917bfbb add --version, bump to v0.28 2018-01-12 19:10:44 +01:00
Stéphane Lesimple 8f18f53aba add cpu model in output 2018-01-12 19:08:12 +01:00
M. Willis Monroe d3f102b3b3 Typofix in readme (#61) 2018-01-12 13:58:04 +01:00
M. Willis Monroe 8bd093173d Fixed a few spelling errors (#60) 2018-01-12 11:46:36 +01:00
Stéphane Lesimple bfe5a3b840 add some debug 2018-01-12 10:53:19 +01:00
Stéphane Lesimple 6a0242eea3 bump to v0.27 2018-01-11 15:36:41 +01:00
Stéphane Lesimple bc4e39038a fix(opcodes): fix regression introduced in previous commit
We were saying unknown instead of vulnerable when the count of lfence opcodes was low
This was not impacting batch mode or the final decision, just the human-readable output of the script.
2018-01-11 15:35:57 +01:00
Stéphane Lesimple 62f8ed6f61 adding support for new /sys interface (#55)
* adding support for new /sys interface
* fix(objdump): prefer -d instead of -D, some kernels crash objdump otherwise
2018-01-11 12:23:16 +01:00
Gianluca Varisco 56b67f8082 Typo in README (#54) 2018-01-11 12:01:31 +01:00
Tobias Rüetschi 52a8f78885 send warning to stderr. (#53)
With --batch json there must not be any other output on stdout, so redirect warnings to stderr will show the warning on the console and only the json output is on stdout.
2018-01-11 09:55:43 +01:00
Stéphane Lesimple a09a5ba38f bump to v0.25 to reflect changes 2018-01-11 09:08:29 +01:00
Abdoul Bah 5a7d8d7edf Produce JSON output formatted for Puppet, Ansible, Chef... (#50)
Produce JSON output formatted for Puppet, Ansible, Chef...
2018-01-11 09:04:13 +01:00
Stéphane Lesimple 49fdc6c449 Merge pull request #51 from cowanml/file_read_check_fixup
fixed file read test
2018-01-10 21:39:09 +01:00
Matt Cowan af3de2a862 fixed file read test 2018-01-10 15:17:14 -05:00
Stéphane Lesimple c6e1b0ac8a feat(kernel): add support for LZ4 decompression 2018-01-10 20:10:57 +01:00
Stéphane Lesimple b913dacc1b Merge pull request #48 from speed47/opensuse
fix(opensuse): add specific location for ibrs_enabled file
2018-01-10 18:41:30 +01:00
Stéphane Lesimple eb0ebef5a8 fix(opensuse): add specific location for ibrs_enabled file 2018-01-10 17:40:33 +01:00
Stéphane Lesimple e0254025e8 Merge pull request #47 from speed47/readme
update readme
2018-01-10 17:12:54 +01:00
Stéphane Lesimple bd010340e6 update readme 2018-01-10 17:12:33 +01:00
Stéphane Lesimple a658de2f01 fix(kernel): fix detection for separate /boot partitions 2018-01-10 16:27:16 +01:00
Stéphane Lesimple 4aed5589fe Merge pull request #44 from speed47/bootimage
feat(kernel): check the BOOT_IMAGE info from cmdline before trying th…
2018-01-10 16:13:00 +01:00
Stéphane Lesimple 8ed1f5e3af feat(kernel): check the BOOT_IMAGE info from cmdline before trying the default names 2018-01-10 15:46:29 +01:00
Stéphane Lesimple ffc542eb82 bump to v0.23 to reflect changes 2018-01-10 15:25:55 +01:00
Stéphane Lesimple 74bc7ba637 add --variant to specify what check we want to run 2018-01-10 15:22:30 +01:00
Stéphane Lesimple 5389ac6844 Merge pull request #41 from bang-communications/master
NRPE mode
2018-01-10 15:11:45 +01:00
Stéphane Lesimple 36fb83215a Merge pull request #42 from simon-vasseur/style
added some style (screenshot in readme)
2018-01-10 15:07:34 +01:00
Marcus Downing 59fe8c2ad8 Error on unknown batch format 2018-01-10 13:57:10 +00:00
Simon Vasseur b8d28e7f61 added some style 2018-01-10 14:55:58 +01:00
Marcus Downing 7c11d07865 Stray tab 2018-01-10 11:59:33 +00:00
Marcus Downing 7c5cfbb8c3 batch nrpe 2018-01-10 11:57:45 +00:00
Marcus Downing 381038eceb NRPE mode 2018-01-10 11:18:45 +00:00
Stéphane Lesimple d6e4aa43f0 Merge pull request #37 from deufrai/better-dmesg-support
Improve PTI detection
2018-01-09 19:52:45 +01:00
Stéphane Lesimple e5e09384f0 typofix 2018-01-09 18:54:35 +01:00
Stéphane Lesimple 7222367f04 add disclaimer and bump to 0.21 2018-01-09 18:52:21 +01:00
Stéphane Lesimple ab512687cf Merge pull request #38 from Alkorin/fixARM
Fix ARM checks
2018-01-09 18:47:25 +01:00
Stéphane Lesimple a5aaa790a0 Merge pull request #39 from Alkorin/typo
Fix small typo in error message
2018-01-09 18:45:58 +01:00
Alkorin 335439dee0 Fix small typo in error message 2018-01-09 18:44:15 +01:00
Alkorin 45297b6f7d Fix ARM checks 2018-01-09 18:41:48 +01:00
Frederic CORNU a7b14306d5 Improve PTI detection even more
when PTI detection relies on dmesg, dmesg output is checked first
then /var/log/dmesg if dmesg output lacks boot time messages
2018-01-09 18:26:32 +01:00
Frederic CORNU 608952ff71 Improve PTI detection
In case of a busy or misconfigured server, kernel message buffer loop
can be filled with messages broadcasted later than boot time. So dmesg
command wont return boot time messages.

Grepping /var/log/dmesg fixes it and this log file location semms pretty
standard across many common distros
2018-01-09 18:17:39 +01:00
Stéphane Lesimple 1c3d349667 Merge pull request #31 from Feandil/batch
Add a "batch" and "verbose" mode
2018-01-09 18:12:39 +01:00
Stéphane Lesimple b93b13263d fix(pti): remove escapes since we use grep -E now 2018-01-09 16:01:44 +01:00
Vincent Brillault ad342cab06 Introduce "verbose" and "batch" modes
Rewrite the way the output is processed:
- Define verbosity level (currently warn, info (default) & verbose)
- Add a batch mode, for simple machine parsing
2018-01-09 15:58:13 +01:00
Vincent Brillault 5fd85e288b No-color: interpret string (-e) to be able to mach \x1B 2018-01-09 15:57:10 +01:00
Stéphane Lesimple 322f4efc8f fix broken logic of 68961f9, increment version to 0.20 2018-01-09 14:55:12 +01:00
Vincent Brillault b6bfcdbd45 Move configuration at the beginning of the script 2018-01-09 14:18:02 +01:00
Stéphane Lesimple 19b01078c2 Merge pull request #32 from speed47/arm
adding known non-vulnerable ARM chips
2018-01-09 13:57:27 +01:00
Stéphane Lesimple 68961f98c2 adding known non-vulnerable ARM chips 2018-01-09 13:11:48 +01:00
Stéphane Lesimple f0f2ea9b11 v0.19: introduce --no-color 2018-01-09 10:32:51 +01:00
Stéphane Lesimple 6f1bdba1d9 bump to v0.18 to reflect changes 2018-01-09 09:21:42 +01:00
Stéphane Lesimple 7b05105a54 Merge pull request #25 from Feandil/proc_config
When using /proc/config.gz, indicate it more clearly
2018-01-09 09:19:36 +01:00
Stéphane Lesimple 8aed2d4086 Merge pull request #26 from Feandil/proc_kallsym
Use /proc/kallsyms to get symbols, if available
2018-01-09 09:17:18 +01:00
Vincent Brillault f4140a992a Use /proc/kallsyms to get symbols, if available 2018-01-09 08:58:09 +01:00
Vincent Brillault 2c51b00a90 When using /proc/config.gz, indicate it more clearly 2018-01-09 08:54:07 +01:00
Stéphane Lesimple 2d94514c07 adding mention of heuristic for variant 1 check 2018-01-09 08:43:52 +01:00
Stéphane Lesimple 0e8f97afbc Merge pull request #24 from angus-p/Remove-extra-space
remove superfluous space from test line 315
2018-01-09 08:34:10 +01:00
Stéphane Lesimple 70323a30da Merge pull request #23 from mradcliffe/issue-22
Increases tmp directory uniqueness to 6 characters to support Slackware
2018-01-09 08:33:32 +01:00
angus-p cc0b325383 remove superfluous space from test line 315
Extra space was causing non-existent variable to be tested resulting in 'YES' if running in live mode and IBRS compiled in
2018-01-09 03:47:25 +00:00
Matthew Radcliffe 4454f03136 Increases tmp directory uniqueness to 6 characters to support Slackware 2018-01-08 22:28:55 -05:00
Stéphane Lesimple 949f316f89 missed version bump + README typofix 2018-01-08 23:15:42 +01:00
Stéphane Lesimple 5082afae61 Merge pull request #19 from speed47/offline_mode
implement offline mode and help
2018-01-08 23:13:19 +01:00
Stéphane Lesimple d73a24cb5b implement offline mode and help 2018-01-08 23:09:17 +01:00
Stéphane Lesimple 75332e6e0f Merge pull request #18 from GrimKriegor/linux-libre_support
Linux-libre support
2018-01-08 23:07:41 +01:00
Grim Kriegor 2d33a4369e Linux-libre support 2018-01-08 21:56:11 +00:00
Stéphane Lesimple 8d4d295309 bump to v0.16 to reflect changes 2018-01-08 17:48:20 +01:00
Stéphane Lesimple 1ff437edbb Merge pull request #16 from Alkorin/fixes
Fixes
2018-01-08 17:45:59 +01:00
Stéphane Lesimple 34656827f5 detect retpoline-compliant compiler from latest LKML patches 2018-01-08 17:32:19 +01:00
Alkorin 8c8a8d35fd Detect if 'readelf' is present 2018-01-08 16:52:09 +01:00
Alkorin debd10b517 Detect if 'strings' is present 2018-01-08 16:51:20 +01:00
Alkorin 21f81ff5c9 Detect if uncompress binaries are present 2018-01-08 16:51:14 +01:00
Stéphane Lesimple 206e4b7fbc add detection of retpoline-aware compiler 2018-01-08 16:28:00 +01:00
Alkorin 1a14483c98 Use 'readelf' instead of 'file' to detect kernel 2018-01-08 15:56:19 +01:00
Alkorin 26564206db Do not execute checks if we already found that PTI is enabled 2018-01-08 15:56:19 +01:00
Stéphane Lesimple 207168e097 detect if the used compiler supports retpoline (WIP) 2018-01-08 15:45:09 +01:00
Stéphane Lesimple f8ca11e56a Merge pull request #12 from sebastianw/fix-double-print
Remove superfluous 'YES' output when checking cpuinfo
2018-01-08 15:05:15 +01:00
Sebastian Wiesinger c88acdd31d Remove superfluous 'YES' output when checking cpuinfo 2018-01-08 14:50:59 +01:00
Stéphane Lesimple 88df48f4a7 Merge pull request #11 from sebastianw/kaiser-cpu-flag
Recognize 'kaiser' flag in /proc/cpuinfo
2018-01-08 14:45:40 +01:00
Sebastian Wiesinger 124ce8e27a Recognize 'kaiser' flag in /proc/cpuinfo 2018-01-08 14:38:43 +01:00
Stéphane Lesimple 7bbcfe0df7 Merge pull request #7 from Feandil/redhat
Redhat support
2018-01-08 14:17:33 +01:00
Vincent Brillault a792348928 RedHat uses a different configuration name 2018-01-08 12:59:12 +01:00
Vincent Brillault 66f7708095 Refactor RedHat support:
- Isolate file check to different elif (allowing to add more)
- Do the PTI debugfs check first (faster and supposed to be dynamic)
- If pti_enable is 0, don't trust dmesg (supposed to be dynamic)
2018-01-08 12:59:03 +01:00
Vincent Brillault 34ef5ef21b Delay umount (for RedHat access to pti_enable) 2018-01-08 12:58:22 +01:00
Stéphane Lesimple edbdf0da1f push the lfence opcodes threshold to 70 2018-01-08 12:49:23 +01:00
Stéphane Lesimple 68adbfdf14 Merge pull request #10 from Alkorin/permissionDenied
Avoid 'cat: /sys/kernel/debug/x86/pti_enabled: Permission denied'
2018-01-08 12:44:09 +01:00
Alkorin 47c30babf1 Avoid 'cat: /sys/kernel/debug/x86/pti_enabled: Permission denied' 2018-01-08 12:41:28 +01:00
Stéphane Lesimple ef7a5c4cf6 adding uname -v to get potential additional vendor information 2018-01-08 12:22:56 +01:00
Stéphane Lesimple 4406910bea Merge pull request #8 from Feandil/debugfs
Fix debugfs mount check
2018-01-08 12:19:23 +01:00
Vincent Brillault b7197d6f54 Fix debugfs mount check 2018-01-08 12:15:51 +01:00
Stéphane Lesimple c792fa35bf add kernel version information to the output 2018-01-08 12:14:12 +01:00
Stéphane Lesimple d1498fe03f Merge pull request #5 from fccagou/centos
fix(centos): check according to redhat patch.
2018-01-08 12:10:07 +01:00
Stéphane Lesimple 12bdd0e412 root check is now more visible 2018-01-08 11:31:19 +01:00
Stéphane Lesimple 89f9bef577 Merge pull request #4 from dguglielmi/add-genkernel-support
Add support for Gentoo genkernel image path
2018-01-08 11:24:07 +01:00
fccagou 0f50e04dab fix(centos): check according to redhat patch. https://access.redhat.com/articles/3311301 2018-01-08 11:14:22 +01:00
David Guglielmi bf056ae73d Add support for Gentoo genkernel image path 2018-01-08 11:08:53 +01:00
Stéphane Lesimple 623e180ae1 Merge pull request #3 from TheHendla/arch_boot_img
add arch linux bootimage path
2018-01-08 10:51:59 +01:00
Frederik Schreiber 40a9d43c44 add arch linux bootimage path 2018-01-08 10:36:29 +01:00
Stéphane Lesimple c1004d5171 fix extract-vmlinux for non-gzip 2018-01-08 09:56:29 +01:00
Stéphane Lesimple fa0850466e add some comments, enhance pti detection 2018-01-08 09:37:54 +01:00
Stéphane Lesimple 5c14384e15 Merge pull request #1 from t-nelis/root-check
Improve "running as root" check
2018-01-08 08:58:21 +01:00
Thibault Nélis 1aaca63dcf Improve "running as root" check
Small issue with the USER environment variable:

  $ echo $USER
  thib
  $ sudo sh -c 'echo $USER'
  thib
  $ sudo -i sh -c 'echo $USER'
  root

Rather than recommending users to use sudo --login / -i, use the (very
widespread/portable) id program to retrieve the effective user ID
instead and don't change the recommendation.

  $ id -u
  1000
  $ sudo id -u
  0
  $ sudo -i id -u
  0
2018-01-08 01:22:14 +01:00
Stéphane Lesimple 96dfa03c00 fix for uncompressed vmlinux case 2018-01-08 00:45:12 +01:00
Stéphane Lesimple 05c79425ab detect kpti directly in vmlinux if option is not there 2018-01-07 22:47:41 +01:00
Stéphane Lesimple 9def0c949a update readme 2018-01-07 20:13:10 +01:00
Stéphane Lesimple 64eb1d005c add couple missing elses 2018-01-07 18:49:15 +01:00
Stéphane Lesimple bffda8b3e7 remove dependency on rdmsr 2018-01-07 18:36:56 +01:00
Stéphane Lesimple 13f2133a97 cosmetic fix 2018-01-07 18:14:08 +01:00
Stéphane Lesimple 8c2fd0f0bb fix MSR reading, need rdmsr for now 2018-01-07 18:13:25 +01:00
Stéphane Lesimple 761c2b80e4 cosmetic fix 2018-01-07 17:19:37 +01:00
Stéphane Lesimple d6977928e5 msg fix 2018-01-07 17:15:08 +01:00
Stéphane Lesimple bd4c74331e add retpolines check 2018-01-07 16:57:14 +01:00
Stéphane Lesimple 82972f8790 fix status unknown for variant 1 2018-01-07 16:32:34 +01:00
Stéphane Lesimple 30de4f6336 remove hardcoded kernel image path 2018-01-07 16:25:50 +01:00
Stéphane Lesimple 9ed1fcd98a cosmetic + v0.02 2018-01-07 16:22:30 +01:00
Stéphane Lesimple ef7c0d7ec5 add variant 1 check 2018-01-07 16:16:11 +01:00
Stéphane Lesimple 3b760822ff fix echo under some shells 2018-01-07 16:00:01 +01:00
Stéphane Lesimple 0201b02313 typofix 2018-01-07 15:37:50 +01:00
Stéphane Lesimple c937e6603b add System.map way of detecting kpti build 2018-01-07 15:36:05 +01:00
Stéphane Lesimple 0c4591f8ec fix readme 2018-01-07 15:02:59 +01:00
Stéphane Lesimple 4211178b3a v0.01 2018-01-07 15:00:59 +01:00
Stéphane Lesimple 3b59139e79 Initial commit 2018-01-07 15:00:15 +01:00
20 changed files with 15490 additions and 2158 deletions
+185
View File
@@ -0,0 +1,185 @@
name: build
on:
push:
branches:
- test
- source
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: true
- name: install prerequisites
run: sudo apt-get update && sudo apt-get install -y shellcheck shfmt jq sqlite3 iucode-tool make
- name: update Intel model list
run: ./scripts/update_intel_models.sh
- name: build and check
run: |
make build fmt-check shellcheck
mv spectre-meltdown-checker.sh dist/
- name: check direct execution
run: |
set -x
expected=$(cat .github/workflows/expected_cve_count)
cd dist
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
echo "Invalid number of CVEs reported: $nb instead of $expected"
echo "$json" | jq '.vulnerabilities[].cve'
exit 1
else
echo "OK $nb CVEs reported"
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
run: |
expected=$(cat .github/workflows/expected_cve_count)
cd dist
docker compose build
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
echo "Invalid number of CVEs reported: $nb instead of $expected"
exit 1
else
echo "OK $nb CVEs reported"
fi
- name: check docker run execution
run: |
expected=$(cat .github/workflows/expected_cve_count)
cd dist
docker build -t spectre-meltdown-checker .
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
echo "Invalid number of CVEs reported: $nb instead of $expected"
exit 1
else
echo "OK $nb CVEs reported"
fi
- name: check fwdb update (separated)
run: |
cd dist
nbtmp1=$(find /tmp 2>/dev/null | wc -l)
./spectre-meltdown-checker.sh --update-fwdb; ret=$?
if [ "$ret" != 0 ]; then
echo "Non-zero return value: $ret"
exit 1
fi
nbtmp2=$(find /tmp 2>/dev/null | wc -l)
if [ "$nbtmp1" != "$nbtmp2" ]; then
echo "Left temporary files!"
exit 1
fi
if ! [ -e ~/.mcedb ]; then
echo "No .mcedb file found after updating fwdb"
exit 1
fi
- name: check fwdb update (builtin)
run: |
cd dist
nbtmp1=$(find /tmp 2>/dev/null | wc -l)
./spectre-meltdown-checker.sh --update-builtin-fwdb; ret=$?
if [ "$ret" != 0 ]; then
echo "Non-zero return value: $ret"
exit 1
fi
nbtmp2=$(find /tmp 2>/dev/null | wc -l)
if [ "$nbtmp1" != "$nbtmp2" ]; then
echo "Left temporary files!"
exit 1
fi
- name: create a pull request to ${{ github.ref_name }}-build
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)
mv ./dist/* .github $tmpdir/
rm -rf ./dist
git fetch origin ${{ github.ref_name }}-build
git checkout -f ${{ github.ref_name }}-build
rm -rf doc/
mv $tmpdir/* .
rm -rf src/ scripts/ img/
mkdir -p .github
rsync -vaP --delete $tmpdir/.github/ .github/
git add --all
echo =#=#= DIFF CACHED
git diff --cached
echo =#=#= STATUS
git status
echo =#=#= COMMIT
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git log ${{ github.ref }} -1 --format=format:'%s%n%n built from commit %H%n dated %ai%n by %an (%ae)%n%n %b'
git log ${{ github.ref }} -1 --format=format:'%s%n%n built from commit %H%n dated %ai%n by %an (%ae)%n%n %b' | git commit -F -
git push
+1
View File
@@ -0,0 +1 @@
32
-4
View File
@@ -1,4 +0,0 @@
__pycache__/
*.py[cod]
*.egg-info/
.venv/
+7
View File
@@ -0,0 +1,7 @@
FROM alpine:latest
RUN apk --update --no-cache add kmod binutils grep perl zstd wget sharutils unzip sqlite procps coreutils iucode-tool gzip xz bzip2 lz4
COPY spectre-meltdown-checker.sh /
ENTRYPOINT ["/spectre-meltdown-checker.sh"]
+321
View File
@@ -0,0 +1,321 @@
Spectre & Meltdown Checker
==========================
A self-contained shell script to assess your system's resilience against the several [transient execution](https://en.wikipedia.org/wiki/Transient_execution_CPU_vulnerability) CVEs that were published since early 2018, and give you guidance as to how to mitigate them.
## CVE list
CVE | Name | Aliases
--- | ---- | -------
[CVE-2017-5753](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5753) | Bounds Check Bypass | Spectre V1
[CVE-2017-5715](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715) | Branch Target Injection | Spectre V2
[CVE-2017-5754](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5754) | Rogue Data Cache Load | Meltdown
[CVE-2018-3640](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3640) | Rogue System Register Read | Variant 3a
[CVE-2018-3639](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639) | Speculative Store Bypass | Variant 4, SSB
[CVE-2018-3615](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3615) | L1 Terminal Fault | Foreshadow (SGX)
[CVE-2018-3620](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3620) | L1 Terminal Fault | Foreshadow-NG (OS/SMM)
[CVE-2018-3646](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3646) | L1 Terminal Fault | Foreshadow-NG (VMM)
[CVE-2018-12126](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12126) | Microarchitectural Store Buffer Data Sampling | MSBDS, Fallout
[CVE-2018-12127](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12127) | Microarchitectural Load Port Data Sampling | MLPDS, RIDL
[CVE-2018-12130](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12130) | Microarchitectural Fill Buffer Data Sampling | MFBDS, ZombieLoad
[CVE-2018-12207](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12207) | Machine Check Exception on Page Size Changes | iTLB Multihit, No eXcuses
[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-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-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-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-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-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-2025-40300](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-40300) | VM-Exit Stale Branch Prediction | VMScape
[CVE-2024-45332](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-45332) | Branch Privilege Injection | BPI
[CVE-2025-54505](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-54505) | AMD Zen1 Floating-Point Divider Stale Data Leak | FPDSS
## Am I at risk?
Depending on your situation, the table below answers whether an attacker in a given position can extract data from a given target.
The "Userland → Kernel" column also applies within a VM (VM userland vs. VM kernel), since the same CPU mechanisms are at play regardless of virtualization.
Vulnerability | Userland → Kernel | Userland → Userland | VM → Host | VM → VM | Mitigation
------------ | :---------------: | :-----------------: | :-------: | :-----: | ----------
CVE-2017-5753 (Spectre V1) | 💥 | 💥 | 💥 | 💥 | Recompile everything with LFENCE
CVE-2017-5715 (Spectre V2) | 💥 | 💥 | 💥 | 💥 | Microcode + kernel update (or retpoline)
CVE-2017-5754 (Meltdown) | 💥 | ✅ | ✅ | ✅ | Kernel update
CVE-2018-3640 (Variant 3a) | 💥 | ✅ | ✅ | ✅ | Microcode update
CVE-2018-3639 (Variant 4, SSB) | ✅ | 💥 | ✅ | ✅ | Microcode + kernel update
CVE-2018-3615 (Foreshadow, SGX) | ✅ (3) | ✅ (3) | ✅ (3) | ✅ (3) | Microcode update
CVE-2018-3620 (Foreshadow-NG, OS/SMM) | 💥 | ✅ | ✅ | ✅ | Kernel update
CVE-2018-3646 (Foreshadow-NG, VMM) | ✅ | ✅ | 💥 | 💥 | Kernel update (or disable EPT/SMT)
CVE-2018-12126 (MSBDS, Fallout) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2018-12127 (MLPDS, RIDL) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2018-12130 (MFBDS, ZombieLoad) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2018-12207 (iTLB Multihit, No eXcuses) | ✅ | ✅ | ☠️ | ✅ | Hypervisor update (or disable hugepages)
CVE-2019-11091 (MDSUM, RIDL) | 💥 | 💥 (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-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-29901 (Retbleed Intel, RSBA) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update (eIBRS or IBRS)
CVE-2022-40982 (Downfall, GDS) | 💥 | 💥 | 💥 | 💥 | Microcode update (or disable AVX)
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-23583 (Reptar) | ☠️ | ☠️ | ☠️ | ☠️ | Microcode update
CVE-2023-28746 (RFDS) | 💥 | ✅ | 💥 | ✅ | Microcode + kernel update
CVE-2024-28956 (ITS) | 💥 | ✅ | 💥 (4) | ✅ | Microcode + kernel update
CVE-2024-36350 (TSA-SQ) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2024-36357 (TSA-L1) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel update
CVE-2025-40300 (VMScape) | ✅ | ✅ | 💥 | ✅ | Kernel update (IBPB on VM-exit)
CVE-2024-45332 (BPI) | 💥 | ✅ | 💥 | ✅ | Microcode update
CVE-2025-54505 (FPDSS) | 💥 | 💥 | 💥 | 💥 | Kernel update
> 💥 Data can be leaked across this boundary.
> ✅ Not affected in this scenario.
> ☠️ Denial of service (system crash or unpredictable behavior), no data leak.
> (1) Cross-process leakage requires SMT (Hyper-Threading) to be active — attacker and victim must share a physical core.
> (2) Only leaks RDRAND/RDSEED output, not arbitrary memory; still allows recovering cryptographic material from any victim.
> (3) CVE-2018-3615 (Foreshadow SGX) inverts the normal trust model: the OS reads SGX enclave data. It is irrelevant unless the system runs SGX enclaves, and the attacker must already have OS-level access.
> (4) VM→Host leakage applies only to certain affected CPU models (Skylake-X, Kaby Lake, Comet Lake). Ice Lake, Tiger Lake, and Rocket Lake are only affected for native (user-to-kernel) attacks, not guest-to-host.
## Detailed CVE descriptions
<details>
<summary>Unfold for more detailed CVE descriptions</summary>
**CVE-2017-5753 — Bounds Check Bypass (Spectre Variant 1)**
An attacker can train the branch predictor to mispredict a bounds check, causing the CPU to speculatively access out-of-bounds memory. This affects all software, including the kernel, because any conditional bounds check can potentially be exploited. Mitigation requires recompiling software and the kernel with a compiler that inserts LFENCE instructions (or equivalent speculation barriers like `array_index_nospec`) at the proper positions. The performance impact is negligible because the barriers only apply to specific, targeted code patterns.
**CVE-2017-5715 — Branch Target Injection (Spectre Variant 2)**
An attacker can poison the Branch Target Buffer (BTB) to redirect speculative execution of indirect branches in the kernel, leaking kernel memory. Two mitigation strategies exist: (1) microcode updates providing IBRS (Indirect Branch Restricted Speculation), which flushes branch predictor state on privilege transitions — this has a medium to high performance cost, especially on older hardware; or (2) retpoline, a compiler technique that replaces indirect branches with a construct the speculator cannot exploit — this has a lower performance cost but requires recompiling the kernel and sensitive software.
**CVE-2017-5754 — Rogue Data Cache Load (Meltdown)**
On affected Intel processors, a user process can speculatively read kernel memory despite lacking permission. The CPU eventually raises a fault, but the data leaves observable traces in the cache. Mitigation is entirely kernel-side: Page Table Isolation (PTI/KPTI) unmaps most kernel memory from user-space page tables, so there is nothing to speculatively read. The performance impact is low to medium, mainly from the increased TLB pressure caused by switching page tables on every kernel entry and exit.
**CVE-2018-3640 — Rogue System Register Read (Variant 3a)**
Similar to Meltdown but targeting system registers: an unprivileged process can speculatively read privileged system register values (such as Model-Specific Registers) and exfiltrate them via a side channel. Mitigation requires a microcode update only — no kernel changes are needed. Performance impact is negligible.
**CVE-2018-3639 — Speculative Store Bypass (Variant 4)**
The CPU may speculatively load a value from memory before a preceding store to the same address completes, reading stale data. This primarily affects software using JIT compilation (e.g. JavaScript engines, eBPF), where an attacker can craft code that exploits the store-to-load dependency. No known exploitation against the kernel itself has been demonstrated. Mitigation requires a microcode update (providing the SSBD mechanism) plus a kernel update that allows affected software to opt in to the protection via prctl(). The performance impact is low to medium, depending on how frequently the mitigation is activated.
**CVE-2018-3615 — L1 Terminal Fault (Foreshadow, SGX)**
The original Foreshadow attack targets Intel SGX enclaves. When a page table entry's Present bit is cleared, the CPU may still speculatively use the physical address in the entry to fetch data from the L1 cache, bypassing SGX protections. An attacker can extract secrets (attestation keys, sealed data) from SGX enclaves. Mitigation requires a microcode update that includes modifications to SGX behavior. Performance impact is negligible.
**CVE-2018-3620 — L1 Terminal Fault (Foreshadow-NG, OS/SMM)**
A generalization of Foreshadow beyond SGX: unprivileged user-space code can exploit the same L1TF mechanism to read kernel memory or System Management Mode (SMM) memory. Mitigation requires a kernel update that implements PTE inversion — marking non-present page table entries with invalid physical addresses so the L1 cache cannot contain useful data at those addresses. Performance impact is negligible because PTE inversion is a one-time change to the page table management logic with no runtime overhead.
**CVE-2018-3646 — L1 Terminal Fault (Foreshadow-NG, VMM)**
A guest VM can exploit L1TF to read memory belonging to the host or other guests, because the hypervisor's page tables may have non-present entries pointing to valid host physical addresses still resident in L1. Mitigation options include: flushing the L1 data cache on every VM entry (via a kernel update providing L1d flush support), disabling Extended Page Tables (EPT), or disabling Hyper-Threading (SMT) to prevent a sibling thread from refilling the L1 cache during speculation. The performance impact ranges from low to significant depending on the chosen mitigation, with L1d flushing on VM entry being the most practical but still measurable on VM-heavy workloads.
**CVE-2018-12126 — Microarchitectural Store Buffer Data Sampling (MSBDS, Fallout)**
**CVE-2018-12127 — Microarchitectural Load Port Data Sampling (MLPDS, RIDL)**
**CVE-2018-12130 — Microarchitectural Fill Buffer Data Sampling (MFBDS, ZombieLoad)**
**CVE-2019-11091 — Microarchitectural Data Sampling Uncacheable Memory (MDSUM, RIDL)**
These four CVEs are collectively known as "MDS" (Microarchitectural Data Sampling) vulnerabilities. They exploit different CPU internal buffers — store buffer, fill buffer, load ports, and uncacheable memory paths — that can leak recently accessed data across privilege boundaries during speculative execution. An unprivileged attacker can observe data recently processed by the kernel or other processes. Mitigation requires a microcode update (providing the MD_CLEAR mechanism) plus a kernel update that uses VERW to clear affected buffers on privilege transitions. Disabling Hyper-Threading (SMT) provides additional protection because sibling threads share these buffers. The performance impact is low to significant, depending on the frequency of kernel transitions and whether SMT is disabled.
**CVE-2018-12207 — Machine Check Exception on Page Size Changes (iTLB Multihit, No eXcuses)**
A malicious guest VM can trigger a machine check exception (MCE) — crashing the entire host — by creating specific conditions in the instruction TLB involving page size changes. This is a denial-of-service vulnerability affecting hypervisors running untrusted guests. Mitigation requires either disabling hugepage use in the hypervisor or updating the hypervisor to avoid the problematic iTLB configurations. The performance impact ranges from low to significant depending on the approach: disabling hugepages can substantially impact memory-intensive workloads.
**CVE-2019-11135 — TSX Asynchronous Abort (TAA, ZombieLoad V2)**
On CPUs with Intel TSX, a transactional abort can leave data from the line fill buffers in a state observable through side channels, similar to the MDS vulnerabilities but triggered through TSX. Mitigation requires a microcode update plus kernel support to either clear affected buffers or disable TSX entirely (via the TSX_CTRL MSR). The performance impact is low to significant, similar to MDS, with the option to eliminate the attack surface entirely by disabling TSX at the cost of losing transactional memory support.
**CVE-2020-0543 — Special Register Buffer Data Sampling (SRBDS, CROSSTalk)**
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)**
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.
**CVE-2022-29901 — Arbitrary Speculative Code Execution with Return Instructions (Retbleed Intel, RSBA)**
On Intel Skylake through Rocket Lake processors with RSB Alternate Behavior (RSBA), return instructions can be speculatively redirected via the Branch Target Buffer when the Return Stack Buffer underflows, bypassing retpoline mitigations. Mitigation requires either Enhanced IBRS (eIBRS, via microcode update) or a kernel compiled with IBRS-on-entry support (Linux 5.19+). Call depth tracking (stuffing) is an alternative mitigation available from Linux 6.2+. Plain retpoline does NOT mitigate this vulnerability on RSBA-capable CPUs. Performance impact is medium to high.
**CVE-2022-40982 — Gather Data Sampling (GDS, Downfall)**
The AVX GATHER instructions can leak data from previously used vector registers across privilege boundaries through the shared gather data buffer. This affects any software using AVX2 or AVX-512 on vulnerable Intel processors. Mitigation is provided by a microcode update that clears the gather buffer, or alternatively by disabling the AVX feature entirely. Performance impact is negligible for most workloads but can be significant (up to 50%) for AVX-heavy applications such as HPC and AI inference.
**CVE-2023-20569 — Return Address Security (Inception, SRSO)**
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)**
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.
**CVE-2023-23583 — Redundant Prefix Issue (Reptar)**
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)**
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.
**CVE-2024-36350 — Transient Scheduler Attack, Store Queue (TSA-SQ)**
On AMD Zen 3 and Zen 4 processors, the CPU's transient scheduler may speculatively retrieve stale data from the store queue during certain timing windows, allowing an attacker to infer data from previous store operations across privilege boundaries. The attack can also leak data between SMT sibling threads. Mitigation requires both a microcode update (exposing the VERW_CLEAR capability) and a kernel update (CONFIG_MITIGATION_TSA, Linux 6.16+) that uses the VERW instruction to clear CPU buffers on user/kernel transitions and before VMRUN. The kernel also clears buffers on idle when SMT is active. Performance impact is low to medium.
**CVE-2024-36357 — Transient Scheduler Attack, L1 (TSA-L1)**
On AMD Zen 3 and Zen 4 processors, the CPU's transient scheduler may speculatively retrieve stale data from the L1 data cache during certain timing windows, allowing an attacker to infer data in the L1D cache across privilege boundaries. Mitigation requires the same microcode and kernel updates as TSA-SQ: a microcode update exposing VERW_CLEAR and a kernel update (CONFIG_MITIGATION_TSA, Linux 6.16+) that clears CPU buffers via VERW on privilege transitions. Performance impact is low to medium.
**CVE-2025-40300 — VM-Exit Stale Branch Prediction (VMScape)**
After a guest VM exits to the host, stale branch predictions from the guest can influence host-side speculative execution before the kernel returns to userspace, allowing a local attacker to leak host kernel memory. This affects Intel processors from Sandy Bridge through Arrow Lake/Lunar Lake, AMD Zen 1 through Zen 5 families, and Hygon family 0x18. Only systems running a hypervisor with untrusted guests are at risk. Mitigation requires a kernel update (CONFIG_MITIGATION_VMSCAPE, Linux 6.18+) that issues IBPB before returning to userspace after a VM exit. No specific microcode update is required beyond existing IBPB support. Performance impact is low.
**CVE-2024-45332 — Branch Privilege Injection (BPI)**
A race condition in the branch predictor update mechanism of Intel processors (Coffee Lake through Raptor Lake, plus some server and Atom parts) allows user-space branch predictions to briefly influence kernel-space speculative execution, undermining eIBRS and IBPB protections. This means systems relying solely on eIBRS for Spectre V2 mitigation may not be fully protected without the microcode fix. Mitigation requires a microcode update (intel-microcode 20250512+) that fixes the asynchronous branch predictor update timing so that eIBRS and IBPB work as originally intended. No kernel changes are required. Performance impact is negligible.
**CVE-2025-54505 — AMD Zen1 Floating-Point Divider Stale Data Leak (FPDSS)**
On AMD Zen1 and Zen+ processors (EPYC 7001, EPYC Embedded 3000, Athlon 3000 with Radeon, Ryzen 3000 with Radeon, Ryzen PRO 3000 with Radeon Vega), the hardware floating-point divider can retain partial quotient data from previous operations. Under certain circumstances, those results can be leaked to another thread sharing the same divider, crossing any privilege boundary. This was assigned CVE-2025-54505 and published by AMD as AMD-SB-7053 on 2026-04-17. Mitigation requires a kernel update (mainline commit e55d98e77561, "x86/CPU: Fix FPDSS on Zen1", Linux 7.1) that sets bit 9 (ZEN1_DENORM_FIX_BIT) of MSR 0xc0011028 (MSR_AMD64_FP_CFG) unconditionally on every Zen1 CPU at boot, disabling the hardware optimization responsible for the leak. No microcode update is required: the chicken bit is present in Zen1 silicon from the factory and is independent of microcode revision. Performance impact is limited to a small reduction in floating-point divide throughput, which is why AMD does not enable the bit by default in hardware.
</details>
## Unsupported CVEs
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.).
The complete list along with the reason for each exclusion is available in the
[UNSUPPORTED_CVE_LIST.md](doc/UNSUPPORTED_CVE_LIST.md) file.
## Scope
Supported operating systems:
- Linux (all versions, flavors and distros)
- 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](doc/FAQ.md#how-does-this-script-work).
Other operating systems such as MacOS, Windows, ESXi, etc. [will never be supported](doc/FAQ.md#why-is-my-os-not-supported).
Supported architectures:
- `x86` (32 bits)
- `amd64`/`x86_64` (64 bits)
- `ARM` and `ARM64`
- other architectures will work, but mitigations (if they exist) might not always be detected
## Frequently Asked Questions (FAQ)
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](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
### Direct way (recommended)
- Get the latest version of the script using `curl` *or* `wget`
```bash
curl -L https://meltdown.ovh -o spectre-meltdown-checker.sh
wget https://meltdown.ovh -O spectre-meltdown-checker.sh
```
- Inspect the script. You never blindly run scripts you downloaded from the Internet, do you?
```bash
vim spectre-meltdown-checker.sh
```
- When you're ready, run the script as root
```bash
chmod +x spectre-meltdown-checker.sh
sudo ./spectre-meltdown-checker.sh
```
### Using a docker container
<details>
<summary>Unfold for instructions</summary>
Using `docker compose`:
```shell
docker compose build
docker compose run --rm spectre-meltdown-checker
```
Note that on older versions of docker, `docker-compose` is a separate command, so you might
need to replace the two `docker compose` occurences above by `docker-compose`.
Using `docker build` directly:
```shell
docker build -t spectre-meltdown-checker .
docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/modules:/lib/modules:ro spectre-meltdown-checker
```
</details>
## Example of script output
- AMD EPYC-Milan running under Debian Trixie
![alt text](https://raw.githubusercontent.com/speed47/spectre-meltdown-checker/refs/heads/test/img/smc_amd_epyc_milan.jpg)
+145
View File
@@ -0,0 +1,145 @@
# Questions
- [What to expect from this tool?](#what-to-expect-from-this-tool)
- [Why was this script written in the first place?](#why-was-this-script-written-in-the-first-place)
- [Why are those vulnerabilities so different than regular CVEs?](#why-are-those-vulnerabilities-so-different-than-regular-cves)
- [What do "affected", "vulnerable" and "mitigated" mean exactly?](#what-do-affected-vulnerable-and-mitigated-mean-exactly)
- [What are the main design decisions regarding this script?](#what-are-the-main-design-decisions-regarding-this-script)
- [Everything is indicated in `sysfs` now, is this script still useful?](#everything-is-indicated-in-sysfs-now-is-this-script-still-useful)
- [How does this script work?](#how-does-this-script-work)
- [Which BSD OSes are supported?](#which-bsd-oses-are-supported)
- [Why is my OS not supported?](#why-is-my-os-not-supported)
- [The tool says there is an updated microcode for my CPU, but I don't have it!](#the-tool-says-there-is-an-updated-microcode-for-my-cpu-but-i-dont-have-it)
- [The tool says that I need a more up-to-date microcode, but I have the more recent version!](#the-tool-says-that-i-need-a-more-up-to-date-microcode-but-i-have-the-more-recent-version)
- [Which rules are governing the support of a CVE in this tool?](#which-rules-are-governing-the-support-of-a-cve-in-this-tool)
# Answers
## What to expect from this tool?
This tool does its best to determine where your system stands on each of the collectively named [transient execution](https://en.wikipedia.org/wiki/Transient_execution_CPU_vulnerability) vulnerabilities (also sometimes called "speculative execution" vulnerabilities) that were made public since early 2018. It doesn't attempt to run any kind of exploit, and can't guarantee that your system is secure, but rather helps you verifying if your system is affected, and if it is, checks whether it has the known mitigations in place to avoid being vulnerable.
Some mitigations could also exist in your kernel that this script doesn't know (yet) how to detect, or it might falsely detect mitigations that in the end don't work as expected (for example, on backported or modified kernels).
Please also note that for Spectre vulnerabilities, all software can possibly be exploited, this tool only verifies that the kernel (which is the core of the system) you're using has the proper protections in place. Verifying all the other software is out of the scope of this tool. As a general measure, ensure you always have the most up to date stable versions of all the software you use, especially for those who are exposed to the world, such as network daemons and browsers.
This tool has been released in the hope that it'll be useful, but don't use it to jump to definitive conclusions about your security: hardware vulnerabilities are [complex beasts](#why-are-those-vulnerabilities-so-different-than-regular-cves), and collective understanding of each vulnerability is evolving with time.
## Why was this script written in the first place?
The first commit of this script is dated *2018-01-07*, only 4 days after the world first heard about the Meltdown and the Spectre attacks. With those attacks disclosure, a _whole new range of vulnerabilities_ that were previously thought to be mostly theoretical and only possible in very controlled environments (labs) - hence of little interest for most except researchers - suddenly became completely mainstream and apparently trivial to conduct on an immensely large number of systems.
On the few hours and days after that date, the whole industry went crazy. Proper, verified information about these vulnerabilities was incredibly hard to find, because before this, even the CPU vendors never had to deal with managing security vulnerabilities at scale, as software vendors do since decades. There were a lot of FUD, and the apparent silence of the vendors was enough for most to fear the worst. The whole industry had everything to learn about this new type of vulnerabilities. However, most systems administrators had a few simple questions:
- Am **I** vulnerable? And if yes,
- What do I have to do to mitigate these vulnerabilities on **my** system?
Unfortunately, answering those questions was very difficult (and still is to some extent), even if the safe answer to the first question was "you probably are". This script was written to try to give simple answers to those simple questions, and was made to evolve as the information about these vulnerabilities became available. On the first few days, there was several new versions published **per day**.
## Why are those vulnerabilities so different than regular CVEs?
Those are hardware vulnerabilities, while most of the CVEs we see everyday are software vulnerabilities. A quick comparison would be:
Software vulnerability:
- Can be fixed? Yes.
- How to fix? Update the software (or uninstall it!)
Hardware vulnerability:
- Can be fixed? No, only mitigated (or buy new hardware!)
- How to ~~fix~~ mitigate? In the worst case scenario, 5 "layers" need to be updated: the microcode/firmware, the host OS kernel, the hypervisor, the VM OS kernel, and possibly all the software running on the machine. Sometimes only a subset of those layers need to be updated. In yet other cases, there can be several possible mitigations for the same vulnerability, implying different layers. Yes, it can get horribly complicated.
A more detailed video explanation is available here: https://youtu.be/2gB9U1EcCss?t=425
## What do "affected", "vulnerable" and "mitigated" mean exactly?
- **Affected** means that your CPU's hardware, as it went out of the factory, is known to be concerned by a specific vulnerability, i.e. the vulnerability applies to your hardware model. Note that it says nothing about whether a given vulnerability can actually be used to exploit your system. However, an unaffected CPU will never be vulnerable, and doesn't need to have mitigations in place.
- **Vulnerable** implies that you're using an **affected** CPU, and means that a given vulnerability can be exploited on your system, because no (or insufficient) mitigations are in place.
- **Mitigated** implies that a previously **vulnerable** system has followed all the steps (updated all the required layers) to ensure a given vulnerability cannot be exploited. About what "layers" mean, see [the previous question](#why-are-those-vulnerabilities-so-different-than-regular-cves).
## What are the main design decisions regarding this script?
There are a few rules that govern how this tool is written.
1) It should be okay to run this script in a production environment. This implies, but is not limited to:
* 1a. Never modify the system it's running on, and if it needs to e.g. load a kernel module it requires, that wasn't loaded before it was launched, it'll take care to unload it on exit
* 1b. Never attempt to "fix" or "mitigate" any vulnerability, or modify any configuration. It just reports what it thinks is the status of your system. It leaves all decisions to the sysadmin.
* 1c. Never attempt to run any kind of exploit to tell whether a vulnerability is mitigated, because it would violate 1a), could lead to unpredictable system behavior, and might even lead to wrong conclusions, as some PoC must be compiled with specific options and prerequisites, otherwise giving wrong information (especially for Spectre). If you want to run PoCs, do it yourself, but please read carefully about the PoC and the vulnerability. PoCs about a hardware vulnerability are way more complicated and prone to false conclusions than PoCs for software vulnerabilities.
2) Never look at the kernel version to tell whether it supports mitigation for a given vulnerability. This implies never hardcoding version numbers in the script. This would defeat the purpose: this script should be able to detect mitigations in unknown kernels, with possibly backported or forward-ported patches. Also, don't believe what `sysfs` says, when possible. See the next question about this.
3) Never look at the microcode version to tell whether it has the proper mechanisms in place to support mitigation for a given vulnerability. This implies never hardcoding version numbers in the script. Instead, look for said mechanisms, as the kernel would do.
4) When a CPU is not known to be explicitly unaffected by a vulnerability, make the assumption that it is. This strong design choice has it roots in the early speculative execution vulnerability days (see [this answer](#why-was-this-script-written-in-the-first-place)), and is still a good approach as of today.
## Everything is indicated in `sysfs` now, is this script still useful?
A lot as changed since 2018. Nowadays, the industry adapted and this range of vulnerabilities is almost "business as usual", as software vulnerabilities are. However, due to their complexity, it's still not as easy as just checking a version number to ensure a vulnerability is closed.
Granted, we now have a standard way under Linux to check whether our system is affected, vulnerable, mitigated against most of these vulnerabilities. By having a look at the `sysfs` hierarchy, and more precisely the `/sys/devices/system/cpu/vulnerabilities/` folder, one can have a pretty good insight about its system state for each of the listed vulnerabilities. Note that the output can be a little different with some vendors (e.g. Red Hat has some slightly different output than the vanilla kernel for some vulnerabilities), but it's still a gigantic leap forward, given where we were in 2018 when this script was started, and it's very good news. The kernel is the proper place to have this because the kernel knows everything about itself (the mitigations it might have), and the CPU (its model, and microcode features that are exposed). Note however that some vulnerabilities are not reported through this file hierarchy at all, such as Zenbleed.
However I see a few reasons why this script might still be useful to you, and that's why its development has not halted when the `sysfs` hierarchy came out:
- A given version of the kernel doesn't have knowledge about the future. To put it in another way: a given version of the kernel only has the understanding of a vulnerability available at the time it was compiled. Let me explain this: when a new vulnerability comes out, new versions of the microcode and kernels are released, with mitigations in place. With such a kernel, a new `sysfs` entry will appear. However, after a few weeks or months, corner cases can be discovered, previously-thought unaffected CPUs can turn out to be affected in the end, and sometimes mitigations can end up being insufficient. Of course, if you're always running the latest kernel version from kernel.org, this issue might be limited for you. The spectre-meltdown-checker script doesn't depend on a kernel's knowledge and understanding of a vulnerability to compute its output. That is, unless you tell it to (using the `--sysfs-only` option).
- Mitigating a vulnerability completely can sometimes be tricky, and have a lot of complicated prerequisites, depending on your kernel version, CPU vendor, model and even sometimes stepping, CPU microcode, hypervisor support, etc. The script gives a very detailed insight about each of the prerequisites of mitigation for every vulnerability, step by step, hence pointing out what is missing on your system as a whole to completely mitigate an issue.
- 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 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.
There are probably other reasons, but that are the main ones that come to mind. In the end, of course, only you can tell whether it's useful for your use case ;)
## How does this script work?
On one hand, the script gathers information about your CPU, and the features exposed by its microcode. To do this, it uses the low-level CPUID instruction (through the `cpuid` kernel module under Linux, and the `cpucontrol` tool under BSD), and queries to the MSR registers of your CPU (through the `msr` kernel module under Linux, and the `cpucontrol` tool under BSD).
On another hand, the script looks into the kernel image your system is running on, for clues about the mitigations it supports. Of course, this is very specific for each operating system, even if the implemented mitigation is functionally the same, the actual code is completely specific. As you can imagine, the Linux kernel code has a few in common with a BSD kernel code, for example. Under Linux, the script supports looking into the kernel image, and possibly the System.map and kernel config file, if these are available. Under BSD, it looks into the kernel file only.
Then, for each vulnerability it knows about, the script decides whether your system is [affected, vulnerable, and mitigated](#what-do-affected-vulnerable-and-mitigated-mean-exactly) against it, using the information it gathered about your hardware and your kernel.
## Which BSD OSes are supported?
For the BSD range of operating systems, the script will work as long as the BSD you're using supports `cpuctl` and `linprocfs`. This is not the case for OpenBSD for example. Known BSD flavors having proper support are: FreeBSD, NetBSD, DragonflyBSD. Derivatives of those should also work. To know why other BSDs will likely never be supported, see [why is my OS not supported?](#why-is-my-os-not-supported).
## Why is my OS not supported?
This tool only supports Linux, and [some flavors of BSD](#which-bsd-oses-are-supported). Other OSes will most likely never be supported, due to [how this script works](#how-does-this-script-work). It would require implementing these OSes specific way of querying the CPU. It would also require to get documentation (if available) about how this OS mitigates each vulnerability, down to this OS kernel code, and if documentation is not available, reverse-engineer the difference between a known old version of a kernel, and a kernel that mitigates a new vulnerability. This means that all the effort has to be duplicated times the number of supported OSes, as everything is specific, by construction. It also implies having a deep understanding of every OS, which takes years to develop. However, if/when other tools appear for other OSes, that share the same goal of this one, they might be listed here as a convenience.
## The tool says there is an updated microcode for my CPU, but I don't have it!
Even if your operating system is fully up to date, the tool might still tell you that there is a more recent microcode version for your CPU. Currently, it uses (and merges) information from 4 sources:
- The official [Intel microcode repository](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files)
- The awesome platomav's [MCExtractor database](https://github.com/platomav/MCExtractor) for non-Intel CPUs
- The official [linux-firmware](https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git) repository for AMD
- Specific Linux kernel commits that sometimes hardcode microcode versions, such as for [Zenbleed](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=522b1d69219d8f083173819fde04f994aa051a98) or for the bad [Spectre](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/intel.c#n141) microcodes
Generally, it means a more recent version of the microcode has been seen in the wild. However, fully public availability of this microcode might be limited yet, or your OS vendor might have chosen not to ship this new version (yet), maybe because it's currently being tested, or for other reasons. This tool can't tell you when or if this will be the case. You should ask your vendor about it. Technically, you can still go and upgrade your microcode yourself, and use this tool to confirm whether you did it successfully. Updating the microcode for you is out of the scope of this tool, as this would violate [rule 1b](#what-are-the-main-design-decisions-regarding-this-script).
## The tool says that I need a more up-to-date microcode, but I have the more recent version!
This can happen for a few reasons:
- Your CPU is no longer supported by the vendor. In that case, new versions of the microcode will never be published, and vulnerabilities requiring microcode features will never be fixed. On most of these vulnerabilities, you'll have no way to mitigate the issue on a vulnerable system, appart from buying a more recent CPU. Sometimes, you might be able to mitigate the issue by disabling a CPU feature instead (often at the cost of speed). When this is the case, the script will list this as one of the possible mitigations for the vulnerability.
- The vulnerability is recent, and your CPU has not yet received a microcode update for the vendor. Often, these updates come in batches, and it can take several batches to cover all the supported CPUs.
In both cases, you can contact your vendor to know whether there'll be an update or not, and if yes, when. For Intel, at the time this FAQ entry was written, such guidance was [available here](https://software.intel.com/content/www/us/en/develop/topics/software-security-guidance/processors-affected-consolidated-product-cpu-model.html).
## Which rules are governing the support of a CVE in this tool?
On the early days, it was easy: just Spectre and Meltdown (hence the tool name), because that's all we had. Now that this range of vulnerability is seeing a bunch of newcomers every year, this question is legitimate.
To stick with this tool's goal, a good indication as to why a CVE should be supported, is when mitigating it requires either kernel modifications, microcode modifications, or both.
Counter-examples include (non-exhaustive list):
- [CVE-2019-14615](https://github.com/speed47/spectre-meltdown-checker/issues/340), mitigating this issue is done by updating the Intel driver. This is out of the scope of this tool.
- [CVE-2019-15902](https://github.com/speed47/spectre-meltdown-checker/issues/304), this CVE is due to a bad backport in the stable kernel. If the faulty backport was part of the mitigation of another supported CVE, and this bad backport was detectable (without hardcoding kernel versions, see [rule 2](#why-are-those-vulnerabilities-so-different-than-regular-cves)), it might have been added as a bullet point in the concerned CVE's section in the tool. However, this wasn't the case.
- The "[Take A Way](https://github.com/speed47/spectre-meltdown-checker/issues/344)" vulnerability, AMD said that they believe this is not a new attack, hence there were no microcode and no kernel modification made. As there is nothing to look for, this is out of the scope of this tool.
- [CVE-2020-0550](https://github.com/speed47/spectre-meltdown-checker/issues/347), the vendor thinks this is hardly exploitable in the wild, and as mitigations would be too performance impacting, as a whole the industry decided to not address it. As there is nothing to check for, this is out of the scope of this tool.
- [CVE-2020-0551](https://github.com/speed47/spectre-meltdown-checker/issues/348), the industry decided to not address it, as it is believed mitigations for other CVEs render this attack practically hard to make, Intel just released an updated SDK for SGX to help mitigate the issue, but this is out of the scope of this tool.
Look for the [information](https://github.com/speed47/spectre-meltdown-checker/issues?q=is%3Aissue+is%3Aopen+label%3Ainformation) tag in the issues list for more examples.
+309
View File
@@ -0,0 +1,309 @@
# 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-3665 — Lazy FP State Restore (LazyFP)
- **Advisory:** [INTEL-SA-00145](https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/lazy-fp-state-restore.html)
- **Research paper:** [LazyFP: Leaking FPU Register State using Microarchitectural Side-Channels (Stecklina & Prescher, 2018)](https://arxiv.org/abs/1806.07480)
- **Affected CPUs:** Intel Core family (Sandy Bridge through Kaby Lake) when lazy FPU switching is in use
- **CVSS:** 4.3 (Medium)
Intel CPUs using lazy FPU state switching may speculatively expose another process's FPU/SSE/AVX register contents (including AES round keys and other cryptographic material) across context switches. The `#NM` (device-not-available) exception normally used to trigger lazy restore is delivered late enough that dependent instructions can transiently execute against the stale FPU state before the fault squashes them.
**Why out of scope:** The Linux mitigation is to use eager FPU save/restore, which was already the default on Intel CPUs with XSAVEOPT well before disclosure, and was then hard-enforced upstream by the removal of all lazy FPU code in Linux 4.14 (Andy Lutomirski's "x86/fpu: Hard-disable lazy FPU mode" cleanup). There is no `/sys/devices/system/cpu/vulnerabilities/` entry, no CPUID flag, no MSR, and no kernel config option that reflects this mitigation — detection on a running kernel would require hardcoding kernel version ranges, which is against this tool's design principles (same rationale as CVE-2019-15902). In practice, any supported kernel today is eager-FPU-only, and CPUs advertising XSAVEOPT/XSAVES cannot enter the vulnerable lazy-switching mode regardless of kernel configuration.
## 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.
+393
View File
@@ -0,0 +1,393 @@
# 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, or when
`--arch-prefix` is set (host CPU info is then suppressed to avoid mixing
with a different-arch target kernel).
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`
Every 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, or if the CVE's check read sysfs in silent/quiet mode (raw message is still captured in `sysfs_message`) |
| `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
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 or when --arch-prefix is set (host CPU info is then suppressed to avoid mixing with a different-arch target kernel). 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. Every value is tri-state: true=present, false=absent, null=not applicable or unreadable.",
"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": "IBRS supported (via SPEC_CTRL, IBRS_SUPPORT, or cpuinfo fallback)" },
"ibpb": { "type": ["boolean", "null"], "description": "IBPB supported (via SPEC_CTRL, IBPB_SUPPORT, or cpuinfo fallback)" },
"ibpb_ret": { "type": ["boolean", "null"], "description": "IBPB on return (enhanced form)" },
"stibp": { "type": ["boolean", "null"], "description": "STIBP supported (Intel/AMD/HYGON or cpuinfo fallback)" },
"ssbd": { "type": ["boolean", "null"], "description": "SSBD supported (SPEC_CTRL, VIRT_SPEC_CTRL, non-architectural MSR, or cpuinfo fallback)" },
"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): true if PRED_CMD MSR SBPB bit write succeeded; false if write failed; null if not verifiable (non-root, CPUID error, or CPU does not report SBPB support)" },
"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"]
}
}
}
}
}
}
+154
View File
@@ -0,0 +1,154 @@
# 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 ...` |
| Non-root + VULN + UNK | `N/T CVE(s) appear vulnerable (unconfirmed, not root): CVE-A ..., M inconclusive` |
### 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. Notes are emitted in this
order when more than one applies:
| 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 detected as 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 |
When VMM detection did not run (e.g. `--no-hw`), neither the
`hypervisor host detected` nor the `not a hypervisor host` note is printed.
#### 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`
+413
View File
@@ -0,0 +1,413 @@
# 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` / `no-runtime` / `no-hw` / `hw-only` | Operating mode (see below) |
| `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 entirely when none of `kernel_release`, `kernel_arch`, or
`hypervisor_host` can be determined (e.g. non-live mode with no VMM detection).
Each label is emitted only when its value is known; missing labels are
omitted rather than set to an empty string.
| Label | Values | Meaning |
|---|---|---|
| `kernel_release` | string | Output of `uname -r`; emitted only in live mode |
| `kernel_arch` | string | Output of `uname -m`; emitted only in live mode |
| `hypervisor_host` | `true` / `false` | Whether this machine is detected as a hypervisor host (running KVM, Xen, VMware, etc.); absent when VMM detection did not run (e.g. `--no-hw`) |
**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 or when `--arch-prefix` is set (host CPU info is suppressed to avoid
mixing with a different-arch target kernel).
Common labels (always emitted when the data is available):
| Label | Values | Meaning |
|---|---|---|
| `vendor` | string | CPU vendor (e.g. `GenuineIntel`, `AuthenticAMD`, `HygonGenuine`, `ARM`) |
| `model` | string | CPU friendly name from `/proc/cpuinfo` |
| `arch` | `x86` / `arm` | Architecture family; determines which arch-specific labels follow |
| `smt` | `true` / `false` | Whether SMT (HyperThreading) is currently enabled; absent if undeterminable |
| `microcode` | hex string | Installed microcode version (e.g. `0xf4`); absent if unreadable |
| `microcode_latest` | hex string | Latest known-good microcode version from the firmware database; absent if the CPU is not in the database |
| `microcode_up_to_date` | `true` / `false` | Whether `microcode == microcode_latest`; absent if either is unavailable |
| `microcode_blacklisted` | `true` / `false` | Whether the installed microcode is known to cause problems and should be rolled back; emitted whenever `microcode` is emitted |
x86-only labels (emitted when `arch="x86"`):
| Label | Values | Meaning |
|---|---|---|
| `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`) |
| `codename` | string | Intel CPU codename (e.g. `Coffee Lake`); absent on AMD/Hygon |
ARM-only labels (emitted when `arch="arm"`):
| Label | Values | Meaning |
|---|---|---|
| `part_list` | string | Space-separated list of ARM part numbers across cores (e.g. `0xd0b 0xd05` on big.LITTLE) |
| `arch_list` | string | Space-separated list of ARM architecture levels across cores (e.g. `8 8`) |
**x86 example:**
```
smc_cpu_info{vendor="GenuineIntel",model="Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz",arch="x86",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
```
**ARM example:**
```
smc_cpu_info{vendor="ARM",model="ARM v8 model 0xd0b",arch="arm",part_list="0xd0b 0xd05",arch_list="8 8",smt="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
**No-runtime mode (`--no-runtime`)**
`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="no-runtime"` in `smc_build_info` signals this. No-runtime mode is
primarily useful for pre-deployment auditing, not fleet runtime monitoring.
**No-hardware mode (`--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. `mode="no-hw"` in `smc_build_info`
signals this.
**Cross-arch inspection (`--arch-prefix`)**
When a cross-arch toolchain prefix is passed, the script suppresses the host
CPU metadata so it does not get mixed with data from a different-arch target
kernel: `smc_cpu_info` is not emitted, the same as under `--no-hw`.
**Hardware-only mode (`--hw-only`)**
Only hardware detection is performed; CVE checks are skipped. `smc_cpu_info`
is emitted but no `smc_vulnerability_status` metrics appear (and
`smc_vulnerable_count` / `smc_unknown_count` are `0`). `mode="hw-only"` in
`smc_build_info` signals this.
**`--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.
+13
View File
@@ -0,0 +1,13 @@
services:
spectre-meltdown-checker:
build:
context: ./
dockerfile: ./Dockerfile
image: spectre-meltdown-checker:latest
container_name: spectre-meltdown-checker
privileged: true
network_mode: none
volumes:
- /boot:/boot:ro
- /dev/cpu:/dev/cpu:ro
- /lib/modules:/lib/modules:ro
-266
View File
@@ -1,266 +0,0 @@
# Daily transient-execution vulnerability scan — classification step
You are a scheduled agent running inside a GitHub Actions job. A preceding
workflow step has already fetched all configured sources, applied HTTP
conditional caching, deduped against prior state, and written the pre-filtered
list of new items to `new_items.json`. Your only job is to classify each item.
## Scope — read the authoritative docs before classifying
The project's own docs define what belongs in this tool. **Read them early
in the run** (once per run; Claude caches, these don't change daily):
1. **`./checker/DEVELOPMENT.md`** — "Project Mission" section. What the
script does, what it explicitly does not do, its platform scope
(Linux + BSD on x86/amd64/ARM/ARM64).
2. **`./checker/dist/doc/FAQ.md`** — the section titled
_"Which rules are governing the support of a CVE in this tool?"_.
This is the **operative test**:
> A CVE belongs in scope when mitigating it requires **kernel
> modifications, microcode modifications, or both** — and those
> modifications are **detectable** by this tool (no hardcoded kernel
> versions; look for actual mechanisms).
3. **`./checker/dist/doc/UNSUPPORTED_CVE_LIST.md`** — explicit list of
CVEs ruled out, grouped by reason:
- _Already covered by a parent CVE check_ (e.g. SpectreRSB ⊂ Spectre V2).
- _No detectable kernel/microcode mitigation_ (vendor won't fix, GPU
driver-only, userspace-only, etc.).
- _Not a transient / speculative execution vulnerability at all_.
Match incoming items against those exclusion patterns. If a CVE is a
subvariant of a covered parent, or has no kernel/microcode mitigation
this tool can detect, or is simply not a transient-execution issue, it
is **unrelated** — not `tocheck`. Out-of-scope items with zero ambiguity
should not linger in the `tocheck` backlog.
In-scope shortlist (for quick reference; the README's CVE table is the
authoritative source): Spectre v1/v2/v4, Meltdown, Foreshadow/L1TF,
MDS (ZombieLoad/RIDL/Fallout), TAA, SRBDS, iTLB Multihit, MMIO Stale
Data, Retbleed, Zenbleed, Downfall (GDS), Inception/SRSO, DIV0, Reptar,
RFDS, ITS, TSA-SQ/TSA-L1, VMScape, BPI, FP-DSS — and similar
microarchitectural side-channel / speculative-execution issues on
Intel / AMD / ARM CPUs with a detectable mitigation.
Explicitly out of scope: generic software CVEs, GPU driver bugs,
networking stacks, filesystem bugs, userspace crypto issues, unrelated
kernel subsystems, CPU bugs that the industry has decided not to mitigate
(nothing for the tool to check), and CVEs fixed by userspace/SDK updates
only.
## Inputs
- `new_items.json` — shape:
```json
{
"scan_date": "2026-04-18T14:24:43+00:00",
"window_cutoff": "2026-04-17T13:24:43+00:00",
"per_source": { "phoronix": {"status": 200, "new": 2, "total_in_feed": 75} },
"items": [
{
"source": "phoronix",
"stable_id": "CVE-2026-1234",
"title": "...",
"permalink": "https://...",
"guid": "...",
"published_at": "2026-04-18T05:00:00+00:00",
"extracted_cves": ["CVE-2026-1234"],
"vendor_ids": [],
"snippet": "first 400 chars of description, tags stripped"
}
],
"reconsider": [
{
"canonical_id": "INTEL-SA-00145",
"current_bucket": "toimplement",
"title": "Lazy FP State Restore",
"sources": ["intel-psirt"],
"urls": ["https://www.intel.com/.../intel-sa-00145.html"],
"extracted_cves": [],
"first_seen": "2026-04-19T09:41:44+00:00"
}
]
}
```
- `items` are fresh observations from today's fetch: already inside the
time window and not yet present in state under any alt-ID.
- `reconsider` holds existing `toimplement`/`tocheck` entries from state,
submitted for re-review each run (see the "Reconsideration" section
below). On days where both arrays are empty, write stub output files
with `(no new items in this window)`.
- `./checker/` is a checkout of the **`test`** branch of this repo (the
development branch where coded-but-unreleased CVE checks live). This is
the source of truth for whether a CVE is already covered. Grep this
directory — not the working directory root, which only holds the
vuln-watch scripts and has no checker code.
## Classification rules
For each item in `items`, pick exactly one bucket:
- **toimplement** — clearly in-scope per the FAQ test (kernel/microcode
mitigation exists AND is detectable by this tool), and **not already
covered** by `./checker/`. Verify the second half: grep `./checker/`
for each `extracted_cves` entry *and* for any codename in the title
(e.g., "FP-DSS", "Inception"). If either matches, the right bucket is
`unrelated` (already covered) or `tocheck` (maintainer should confirm
whether an existing check handles the new variant).
- **tocheck** — there is a **specific question a maintainer must answer**
before this can be filed anywhere else. Examples:
- Ambiguity about whether an existing check (e.g. parent Spectre V2)
transitively covers this new sub-variant, or whether a fresh entry
is warranted.
- Embedded-only ARM SKU and it's unclear if the tool's ARM support
reaches that class of SKU.
- Vendor advisory published without a CVE ID yet, but the vuln looks
in-scope; revisit once the CVE is assigned.
- Contradictory statements across sources about whether a mitigation
is detectable (kernel-patch vs. userspace-only vs. microcode).
**Do NOT use `tocheck` as a catch-all** for "I'm not sure". Most items
have a clear answer once you consult UNSUPPORTED_CVE_LIST.md and the
FAQ rule. If you can articulate the specific question a maintainer
needs to answer — `tocheck`. If the only reason is "maybe?" — it's
`unrelated`.
- **unrelated** — everything else. Including:
- Matches a pattern in UNSUPPORTED_CVE_LIST.md (subvariant of covered
parent, no detectable mitigation, not transient-execution).
- Fails the FAQ rule (userspace-only fix, driver update, industry
decided not to mitigate).
- Non-CPU security topic (kernel filesystem bug, network stack, crypto
library, GPU driver, compiler flag change, distro release notes).
**Tie-breakers** (note the direction — this used to bias the other way):
- Prefer `unrelated` over `tocheck` when the item matches a category in
UNSUPPORTED_CVE_LIST.md or plainly fails the FAQ rule. Growing the
`tocheck` backlog with obvious-unrelateds wastes human time more than
a confident `unrelated` does.
- Prefer `tocheck` over `toimplement` when the CVE is still "reserved" /
"pending" — false positives in `toimplement` create phantom work.
`WebFetch` is available for resolving genuine `tocheck` ambiguity.
Budget: **3 follow-ups per run total**. Do not use it for items you
already plan to file as `unrelated` or `toimplement`.
## Reconsideration rules (for `reconsider` entries)
Each `reconsider` entry is an item *already* in state under `current_bucket`
= `toimplement` or `tocheck`, from a prior run. Re-examine it against the
**current** `./checker/` tree and the scope docs above. This pass is the
right place to prune the `tocheck` backlog: prior runs (before these
scope docs were wired in) may have hedged on items that now have a clear
`unrelated` answer — demote them aggressively. You may:
- **Demote** `toimplement` → `tocheck` or `unrelated` if the checker now
covers the CVE/codename (grep confirms), or if reinterpreting the
advisory shows it's out of scope.
- **Demote** `tocheck` → `unrelated` if new context settles the ambiguity
as out-of-scope.
- **Promote** `tocheck` → `toimplement` if you now have firm evidence it's
a real, in-scope, not-yet-covered CVE.
- **Leave it unchanged** (same bucket) — emit a record anyway; it's cheap
and documents that the reconsideration happened today.
- **Reassign the canonical ID** — if a CVE has since been assigned to a
vendor advisory (e.g., an INTEL-SA that previously had no CVE), put the
CVE in `extracted_cves` and use it as the new `canonical_id`. The merge
step will rekey the record under the CVE and keep the old ID as an alias.
For every reconsider record you emit, set `"reconsider": true` in its
classification entry — this tells the merge step to **overwrite** the
stored bucket (including demotions), not just promote.
## Outputs
Compute `TODAY` = the `YYYY-MM-DD` prefix of `scan_date`. Write three files at
the repo root, overwriting if present:
- `watch_${TODAY}_toimplement.md`
- `watch_${TODAY}_tocheck.md`
- `watch_${TODAY}_unrelated.md`
These delta files cover the **`items`** array only — they answer "what
did today's fetch surface". Reconsider decisions update state (and surface
in the `current_*.md` snapshots the merge step rewrites); don't duplicate
them here.
Each file uses level-2 headers per source short-name, then one bullet per
item: the stable ID, the permalink, and 12 sentences of context.
```markdown
## oss-sec
- **CVE-2026-1234** — https://www.openwall.com/lists/oss-security/2026/04/18/3
New Intel transient-execution bug "Foo"; affects Redwood Cove cores.
Not yet covered (grepped CVE-2026-1234 and "Foo" — no matches).
```
If a bucket has no items, write `(no new items in this window)`.
Append the following block to the **tocheck** file (creating it if
otherwise empty):
```markdown
## Run summary
- scan_date: <value>
- per-source counts (from per_source): ...
- fetch failures (status != 200/304): ...
- total classified this run: toimplement=<n>, tocheck=<n>, unrelated=<n>
- reconsidered: <n> entries re-reviewed; <list any bucket transitions, e.g.
"CVE-2018-3665: toimplement -> tocheck (now covered at src/vulns/...)">,
or "no transitions" if every reconsider kept its existing bucket.
```
## `classifications.json` — required side-channel for the merge step
Also write `classifications.json` at the repo root. It is a JSON array, one
record per item in `new_items.json.items`:
```json
[
{
"stable_id": "CVE-2026-1234",
"canonical_id": "CVE-2026-1234",
"bucket": "toimplement",
"extracted_cves": ["CVE-2026-1234"],
"sources": ["phoronix"],
"urls": ["https://www.phoronix.com/news/..."]
}
]
```
Rules:
- One record per input item (`items` + `reconsider`). For items, use the
same `stable_id` as in `new_items.json`. For reconsider entries, use the
entry's `canonical_id` from state as the record's `stable_id`.
- `canonical_id`: prefer the first `extracted_cves` entry if any; otherwise
the item's `stable_id`. **Use the same `canonical_id` for multiple items
that are really the same CVE from different sources** — the merge step
will collapse them into one entry and add alias rows automatically.
- **Populate `extracted_cves` / `canonical_id` from context when the feed
didn't.** If the title, body, or a well-known transient-execution codename
mapping lets you identify a CVE the feed didn't emit (e.g., "Lazy FP
State Restore" → `CVE-2018-3665`, "LazyFP" → same, "FP-DSS" → whatever
CVE AMD/Intel assigned), put the CVE in `extracted_cves` and use it as
`canonical_id`. This prevents Intel's CVE-less listing entries from
creating orphan `INTEL-SA-NNNNN` records in the backlog.
- `sources` / `urls`: arrays; default to the item's own single source and
permalink if you didn't enrich further.
- **`reconsider: true`** — set on every record that corresponds to an
input from the `reconsider` array. The merge step uses this flag to
overwrite the stored bucket instead of merging by "strongest wins" —
this is what enables demotions.
- If both `items` and `reconsider` are empty, write `[]`.
## Guardrails
- Do NOT modify any repo source code. Only write the four output files.
- Do NOT create commits, branches, or PRs.
- Do NOT call tools that post externally (Slack, GitHub comments, issues, …).
- Do NOT re-fetch the RSS/HTML sources — that was the prior step's job.
`WebFetch` is only for drilling into a specific advisory/article URL to
resolve a `tocheck` ambiguity (budget 3).
- If total runtime exceeds 10 minutes, finish what you have, write partial
outputs (+ a note in the tocheck run summary), and exit cleanly.
View File
-570
View File
@@ -1,570 +0,0 @@
#!/usr/bin/env python3
"""Fetch all configured sources, dedup against state/seen.json, emit new_items.json.
Writes updated per-source HTTP cache metadata (etag, last_modified, hwm_*) back
into state/seen.json. Does NOT touch state.seen / state.aliases — that is the
merge step's job, after Claude has classified the new items.
Usage:
SCAN_DATE=2026-04-18T14:24:43Z python -m scripts.vuln_watch.fetch_and_diff
"""
from __future__ import annotations
import argparse
import datetime
import gzip
import json
import os
import pathlib
import re
import sys
import urllib.error
import urllib.parse
import urllib.request
from typing import Any, Iterable
import feedparser # type: ignore[import-untyped]
from .sources import REQUEST_TIMEOUT, SOURCES, Source, USER_AGENT
from . import state
CVE_RE = re.compile(r"CVE-\d{4}-\d{4,7}")
DEFAULT_WINDOW_HOURS = 25
DEFAULT_RECONSIDER_AGE_DAYS = 7
MAX_ITEMS_PER_FEED = 200
SNIPPET_MAX = 400
NEW_ITEMS_PATH = pathlib.Path("new_items.json")
def parse_iso(ts: str | None) -> datetime.datetime | None:
if not ts:
return None
try:
return datetime.datetime.fromisoformat(ts.replace("Z", "+00:00"))
except ValueError:
return None
def now_from_scan_date(scan_date: str) -> datetime.datetime:
dt = parse_iso(scan_date)
if dt is None:
dt = datetime.datetime.now(datetime.timezone.utc)
return dt
def conditional_get(
url: str,
etag: str | None,
last_modified: str | None,
user_agent: str = USER_AGENT,
) -> tuple[int | str, bytes | None, str | None, str | None]:
"""Perform a conditional GET.
Returns (status, body, new_etag, new_last_modified).
status is:
- 200 with body on success
- 304 with body=None when unchanged
- an int HTTP error code on server-side errors
- a string describing a network/transport failure
"""
req = urllib.request.Request(url, headers={
"User-Agent": user_agent,
# AMD's CDN stalls on non-gzip clients; asking for gzip speeds up
# every source and is strictly beneficial (we decompress locally).
"Accept-Encoding": "gzip",
})
if etag:
req.add_header("If-None-Match", etag)
if last_modified:
req.add_header("If-Modified-Since", last_modified)
try:
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
body = resp.read()
if resp.headers.get("Content-Encoding", "").lower() == "gzip":
try:
body = gzip.decompress(body)
except OSError:
pass # server lied about encoding; use as-is
return (
resp.status,
body,
resp.headers.get("ETag"),
resp.headers.get("Last-Modified"),
)
except urllib.error.HTTPError as e:
if e.code == 304:
return (304, None, etag, last_modified)
return (e.code, None, etag, last_modified)
except (urllib.error.URLError, TimeoutError, OSError) as e:
return (f"network:{type(e).__name__}", None, etag, last_modified)
def extract_cves(text: str) -> list[str]:
seen: set[str] = set()
out: list[str] = []
for m in CVE_RE.findall(text or ""):
if m not in seen:
seen.add(m)
out.append(m)
return out
def extract_vendor_ids(text: str, patterns: Iterable[str]) -> list[str]:
seen: set[str] = set()
out: list[str] = []
for p in patterns:
for m in re.findall(p, text or ""):
if m not in seen:
seen.add(m)
out.append(m)
return out
def pick_stable_id(vendor_ids: list[str], cves: list[str], guid: str, link: str) -> str:
"""Pick canonical-ish stable ID: vendor advisory → CVE → guid → permalink.
CVE is preferred over guid/URL so that the same CVE seen via different
feeds collapses on its stable_id alone (in addition to the alias map).
"""
if vendor_ids:
return vendor_ids[0]
if cves:
return cves[0]
if guid:
return guid
return link
def clean_snippet(s: str) -> str:
s = re.sub(r"<[^>]+>", " ", s or "")
s = re.sub(r"\s+", " ", s)
return s.strip()
def _struct_time_to_iso(st: Any) -> str | None:
if not st:
return None
try:
return datetime.datetime(*st[:6], tzinfo=datetime.timezone.utc).isoformat()
except (TypeError, ValueError):
return None
def parse_feed_body(src: Source, body: bytes) -> list[dict[str, Any]]:
parsed = feedparser.parse(body)
items: list[dict[str, Any]] = []
for entry in parsed.entries[:MAX_ITEMS_PER_FEED]:
link = (entry.get("link") or "").strip()
guid = (entry.get("id") or entry.get("guid") or "").strip()
title = (entry.get("title") or "").strip()
summary = entry.get("summary") or ""
published_at = (
_struct_time_to_iso(entry.get("published_parsed"))
or _struct_time_to_iso(entry.get("updated_parsed"))
)
blob = f"{title}\n{summary}"
cves = extract_cves(blob)
vendor_ids = extract_vendor_ids(blob, src.advisory_id_patterns)
stable_id = pick_stable_id(vendor_ids, cves, guid, link)
items.append({
"source": src.name,
"stable_id": stable_id,
"title": title,
"permalink": link,
"guid": guid,
"published_at": published_at,
"extracted_cves": cves,
"vendor_ids": vendor_ids,
"snippet": clean_snippet(summary)[:SNIPPET_MAX],
})
return items
def _parse_intel_psirt(src: Source, text: str) -> list[dict[str, Any]]:
"""Intel's security-center page uses a table of <tr class="data"> rows:
<tr class="data" ...>
<td ...><a href="/.../intel-sa-NNNNN.html">Title</a></td>
<td>INTEL-SA-NNNNN</td>
<td>March 10, 2026</td> <- Last updated
<td>March 10, 2026</td> <- First published
</tr>
We pick the later of the two dates as `published_at` (most recent
activity) so updates to older advisories also show up in the window.
"""
items: list[dict[str, Any]] = []
seen_ids: set[str] = set()
permalink_base = src.display_url or src.url
for m in re.finditer(r'<tr class="data"[^>]*>(.*?)</tr>', text, re.DOTALL):
row = m.group(1)
sid = re.search(r'INTEL-SA-\d+', row)
if not sid:
continue
advisory_id = sid.group(0)
if advisory_id in seen_ids:
continue
seen_ids.add(advisory_id)
link_m = re.search(r'href="([^"#]+)"', row)
permalink = urllib.parse.urljoin(permalink_base, link_m.group(1)) if link_m else permalink_base
title_m = re.search(r'<a[^>]*>([^<]+)</a>', row)
title = title_m.group(1).strip() if title_m else advisory_id
published_at: str | None = None
for ds in re.findall(r'<td[^>]*>\s*([A-Z][a-z]+ \d{1,2}, \d{4})\s*</td>', row):
try:
dt = datetime.datetime.strptime(ds, "%B %d, %Y").replace(tzinfo=datetime.timezone.utc)
iso = dt.isoformat()
if published_at is None or iso > published_at:
published_at = iso
except ValueError:
continue
items.append({
"source": src.name,
"stable_id": advisory_id,
"title": title,
"permalink": permalink,
"guid": "",
"published_at": published_at,
"extracted_cves": extract_cves(row),
"vendor_ids": [advisory_id],
"snippet": clean_snippet(row)[:SNIPPET_MAX],
})
return items[:MAX_ITEMS_PER_FEED]
def _parse_amd_psirt(src: Source, text: str) -> list[dict[str, Any]]:
"""AMD's product-security page has a bulletin table where each row ends
with two `<td data-sort="YYYY-MM-DD HHMMSS">` cells (Published Date,
Last Updated Date). The machine-readable `data-sort` attribute is far
easier to parse than the human-readable text alongside it.
"""
items: list[dict[str, Any]] = []
seen_ids: set[str] = set()
permalink_base = src.display_url or src.url
for m in re.finditer(r'<tr[^>]*>(.*?AMD-SB-\d+.*?)</tr>', text, re.DOTALL):
row = m.group(1)
sid = re.search(r'AMD-SB-\d+', row)
if not sid:
continue
advisory_id = sid.group(0)
if advisory_id in seen_ids:
continue
seen_ids.add(advisory_id)
link_m = re.search(r'href="([^"#]+)"', row)
permalink = urllib.parse.urljoin(permalink_base, link_m.group(1)) if link_m else permalink_base
title_m = re.search(r'<a[^>]*>([^<]+)</a>', row)
title = title_m.group(1).strip() if title_m else advisory_id
published_at: str | None = None
for (y, mo, d, h, mi, s) in re.findall(
r'data-sort="(\d{4})-(\d{2})-(\d{2})\s+(\d{2})(\d{2})(\d{2})"', row
):
iso = f"{y}-{mo}-{d}T{h}:{mi}:{s}+00:00"
if published_at is None or iso > published_at:
published_at = iso
items.append({
"source": src.name,
"stable_id": advisory_id,
"title": title,
"permalink": permalink,
"guid": "",
"published_at": published_at,
"extracted_cves": extract_cves(row),
"vendor_ids": [advisory_id],
"snippet": clean_snippet(row)[:SNIPPET_MAX],
})
return items[:MAX_ITEMS_PER_FEED]
def _parse_html_generic(src: Source, text: str) -> list[dict[str, Any]]:
"""Fallback regex-only extractor for HTML sources with no known table
layout (arm-spec, transient-fail's tree.js). Emits `published_at=None`
— items pass the window filter as fail-safe, but state.seen dedup
prevents re-emission across runs."""
items: list[dict[str, Any]] = []
seen_ids: set[str] = set()
permalink_base = src.display_url or src.url
for pat in src.advisory_id_patterns:
for m in re.finditer(pat, text):
advisory_id = m.group(0)
if advisory_id in seen_ids:
continue
seen_ids.add(advisory_id)
window = text[max(0, m.start() - 400): m.end() + 400]
href_match = re.search(r'href="([^"#]+)"', window)
if href_match:
permalink = urllib.parse.urljoin(permalink_base, href_match.group(1))
else:
permalink = permalink_base
cves_in_window = extract_cves(window)
is_cve = advisory_id.startswith("CVE-")
cves = cves_in_window if not is_cve else list({advisory_id, *cves_in_window})
vendor_ids = [] if is_cve else [advisory_id]
items.append({
"source": src.name,
"stable_id": advisory_id,
"title": advisory_id,
"permalink": permalink,
"guid": "",
"published_at": None,
"extracted_cves": cves,
"vendor_ids": vendor_ids,
"snippet": clean_snippet(window)[:SNIPPET_MAX],
})
return items[:MAX_ITEMS_PER_FEED]
_HTML_PARSERS = {
"intel-psirt": _parse_intel_psirt,
"amd-psirt": _parse_amd_psirt,
}
def parse_html_body(src: Source, body: bytes) -> list[dict[str, Any]]:
"""Dispatch to a per-source HTML parser when one is registered;
fall back to the generic regex-over-advisory-IDs extractor."""
text = body.decode("utf-8", errors="replace")
parser = _HTML_PARSERS.get(src.name, _parse_html_generic)
return parser(src, text)
def parse_body(src: Source, body: bytes) -> list[dict[str, Any]]:
return parse_feed_body(src, body) if src.kind in ("rss", "atom") else parse_html_body(src, body)
def compute_cutoff(
scan_now: datetime.datetime,
last_run: str | None,
window_hours: float = DEFAULT_WINDOW_HOURS,
) -> datetime.datetime:
base = scan_now - datetime.timedelta(hours=window_hours)
lr = parse_iso(last_run)
if lr is None:
return base
widened = scan_now - (scan_now - lr + datetime.timedelta(hours=1))
return min(base, widened)
def _resolve_window_hours() -> float:
"""Pick up WINDOW_HOURS from the environment (set by workflow_dispatch).
Falls back to DEFAULT_WINDOW_HOURS for cron runs or local invocations."""
raw = os.environ.get("WINDOW_HOURS", "").strip()
if not raw:
return float(DEFAULT_WINDOW_HOURS)
try:
v = float(raw)
if v <= 0:
raise ValueError("must be > 0")
return v
except ValueError:
print(f"warning: ignoring invalid WINDOW_HOURS={raw!r}, using {DEFAULT_WINDOW_HOURS}",
file=sys.stderr)
return float(DEFAULT_WINDOW_HOURS)
def _resolve_reconsider_age_days() -> float:
"""Pick up RECONSIDER_AGE_DAYS from the environment. Entries whose last
review (reconsidered_at, or first_seen if never reconsidered) is more
recent than this many days ago are skipped. 0 = reconsider everything
every run (no throttle)."""
raw = os.environ.get("RECONSIDER_AGE_DAYS", "").strip()
if not raw:
return float(DEFAULT_RECONSIDER_AGE_DAYS)
try:
v = float(raw)
if v < 0:
raise ValueError("must be >= 0")
return v
except ValueError:
print(f"warning: ignoring invalid RECONSIDER_AGE_DAYS={raw!r}, "
f"using {DEFAULT_RECONSIDER_AGE_DAYS}", file=sys.stderr)
return float(DEFAULT_RECONSIDER_AGE_DAYS)
def backlog_to_reconsider(
data: dict[str, Any],
scan_now: datetime.datetime,
min_age_days: float = DEFAULT_RECONSIDER_AGE_DAYS,
) -> list[dict[str, Any]]:
"""Walk state.seen and emit toimplement/tocheck entries for re-review.
Throttle: skip entries whose "last review" timestamp is more recent
than `min_age_days` ago. "Last review" is `reconsidered_at` if Claude
has already reconsidered the entry at least once, otherwise
`first_seen` (the initial classification was itself a review). With
`min_age_days=0` the throttle is disabled — every qualifying entry
is emitted on every run.
Items in `unrelated` are never emitted — those are settled.
A CVE alias pointing at this canonical is included in `extracted_cves`
so Claude sees every known CVE for the item without having to consult
the full alias map.
"""
seen = data.get("seen", {})
aliases = data.get("aliases", {})
by_canonical: dict[str, list[str]] = {}
for alt, canon in aliases.items():
by_canonical.setdefault(canon, []).append(alt)
# Any entry whose last review is newer than this ISO cutoff is throttled.
cutoff = (scan_now - datetime.timedelta(days=min_age_days)).isoformat()
out: list[dict[str, Any]] = []
for canonical, rec in seen.items():
if rec.get("bucket") not in ("toimplement", "tocheck"):
continue
last_reviewed = rec.get("reconsidered_at") or rec.get("first_seen") or ""
if min_age_days > 0 and last_reviewed and last_reviewed > cutoff:
continue
cves: list[str] = []
if canonical.startswith("CVE-"):
cves.append(canonical)
for alt in by_canonical.get(canonical, []):
if alt.startswith("CVE-") and alt not in cves:
cves.append(alt)
out.append({
"canonical_id": canonical,
"current_bucket": rec.get("bucket"),
"title": rec.get("title") or "",
"sources": list(rec.get("sources") or []),
"urls": list(rec.get("urls") or []),
"extracted_cves": cves,
"first_seen": rec.get("first_seen"),
"reconsidered_at": rec.get("reconsidered_at"),
})
return out
def candidate_ids(item: dict[str, Any]) -> list[str]:
"""All identifiers under which this item might already be known."""
seen: set[str] = set()
out: list[str] = []
for cand in (
*(item.get("extracted_cves") or []),
*(item.get("vendor_ids") or []),
item.get("stable_id"),
item.get("guid"),
item.get("permalink"),
):
if cand and cand not in seen:
seen.add(cand)
out.append(cand)
return out
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--scan-date", default=os.environ.get("SCAN_DATE", ""))
ap.add_argument("--output", type=pathlib.Path, default=NEW_ITEMS_PATH)
args = ap.parse_args()
scan_now = now_from_scan_date(args.scan_date)
scan_date_iso = scan_now.isoformat()
window_hours = _resolve_window_hours()
reconsider_age_days = _resolve_reconsider_age_days()
data = state.load()
cutoff = compute_cutoff(scan_now, data.get("last_run"), window_hours)
per_source: dict[str, dict[str, Any]] = {}
all_new: list[dict[str, Any]] = []
for src in SOURCES:
meta = dict(data["sources"].get(src.name, {}))
status, body, etag, last_modified = conditional_get(
src.url, meta.get("etag"), meta.get("last_modified"),
user_agent=src.user_agent or USER_AGENT,
)
meta["last_fetched_at"] = scan_date_iso
meta["last_status"] = status
if isinstance(status, str) or (isinstance(status, int) and status >= 400 and status != 304):
per_source[src.name] = {"status": status, "new": 0}
data["sources"][src.name] = meta
continue
if status == 304 or body is None:
per_source[src.name] = {"status": 304, "new": 0}
data["sources"][src.name] = meta
continue
# Refresh cache headers only on successful 200.
if etag:
meta["etag"] = etag
if last_modified:
meta["last_modified"] = last_modified
items = parse_body(src, body)
total = len(items)
in_window = []
for it in items:
pub = parse_iso(it.get("published_at"))
if pub is None or pub >= cutoff:
in_window.append(it)
new: list[dict[str, Any]] = []
hwm_pub = meta.get("hwm_published_at")
hwm_id = meta.get("hwm_id")
for it in in_window:
if state.lookup(data, candidate_ids(it)) is not None:
continue
new.append(it)
pub = it.get("published_at")
if pub and (not hwm_pub or pub > hwm_pub):
hwm_pub = pub
hwm_id = it.get("stable_id")
if new:
meta["hwm_published_at"] = hwm_pub
meta["hwm_id"] = hwm_id
data["sources"][src.name] = meta
per_source[src.name] = {"status": status, "new": len(new), "total_in_feed": total}
all_new.extend(new)
# Persist updated HTTP cache metadata regardless of whether Claude runs.
state.save(data)
reconsider = backlog_to_reconsider(data, scan_now, reconsider_age_days)
out = {
"scan_date": scan_date_iso,
"window_cutoff": cutoff.isoformat(),
"per_source": per_source,
"items": all_new,
"reconsider": reconsider,
}
args.output.write_text(json.dumps(out, indent=2, sort_keys=True) + "\n")
# GitHub Actions step outputs. Downstream `if:` conditions gate the
# classify step on `new_count || reconsider_count`; both must be 0
# for Claude to be skipped.
gh_out = os.environ.get("GITHUB_OUTPUT")
if gh_out:
with open(gh_out, "a") as f:
f.write(f"new_count={len(all_new)}\n")
f.write(f"reconsider_count={len(reconsider)}\n")
failures = [
s for s, v in per_source.items()
if not (isinstance(v["status"], int) and v["status"] in (200, 304))
]
f.write(f"fetch_failures_count={len(failures)}\n")
print(f"Scan date: {scan_date_iso}")
print(f"Window: {window_hours:g} h")
print(f"Cutoff: {cutoff.isoformat()}")
print(f"New items: {len(all_new)}")
if reconsider_age_days == 0:
print(f"Reconsider: {len(reconsider)} (throttle disabled)")
else:
print(f"Reconsider: {len(reconsider)} (throttle: "
f"skip entries reviewed <{reconsider_age_days:g}d ago)")
for s, v in per_source.items():
print(f" {s:14s} status={str(v['status']):>16} new={v['new']}")
return 0
if __name__ == "__main__":
sys.exit(main())
-298
View File
@@ -1,298 +0,0 @@
#!/usr/bin/env python3
"""Merge Claude's classifications.json into state/seen.json.
Inputs:
state/seen.json (already has updated .sources from fetch_and_diff)
classifications.json (written by the Claude step; list of records)
new_items.json (fallback source of per-item metadata, if Claude
omitted urls/sources in a record)
Each classification record has shape:
{
"stable_id": "...", # required (the key used in new_items.json)
"canonical_id": "...", # optional; defaults to first extracted_cves, else stable_id
"bucket": "toimplement|tocheck|unrelated",
"extracted_cves": ["...", ...], # optional
"sources": ["...", ...], # optional
"urls": ["...", ...], # optional
"reconsider": true # optional; set by Claude for reconsidered
# backlog entries — merge overwrites
# the stored bucket (incl. demotions)
# instead of promoting
}
Behavior:
- For records WITHOUT `reconsider: true` (fresh items):
upsert seen[canonical_id], union sources/urls, promote bucket strength.
- For records WITH `reconsider: true` (previously-classified entries):
overwrite the stored bucket unconditionally (permits demotions), union
sources/urls. If Claude's canonical_id differs from the stable_id (the
previous canonical), rekey the seen entry under the new ID and leave
the old as an alias — used when a CVE has since been assigned to what
was previously a bare vendor-ID entry.
- For every alt_id in (stable_id, vendor_ids, extracted_cves) that differs
from canonical_id, set aliases[alt_id] = canonical_id.
- Update last_run to SCAN_DATE.
- Prune entries older than RETENTION_DAYS (180) before writing.
- Also writes the three daily watch_*.md files as stubs if Claude didn't run
(i.e. when new_items.json was empty and the classify step was skipped).
"""
from __future__ import annotations
import argparse
import datetime
import json
import os
import pathlib
import sys
from typing import Any
from . import state
RETENTION_DAYS = 180
NEW_ITEMS_PATH = pathlib.Path("new_items.json")
CLASSIFICATIONS_PATH = pathlib.Path("classifications.json")
def _load_json(path: pathlib.Path, default: Any) -> Any:
if not path.exists():
return default
return json.loads(path.read_text())
def _canonical(record: dict[str, Any], fallback_meta: dict[str, Any] | None) -> str:
if record.get("canonical_id"):
return record["canonical_id"]
cves = record.get("extracted_cves") or (fallback_meta or {}).get("extracted_cves") or []
if cves:
return cves[0]
return record["stable_id"]
def _alt_ids(record: dict[str, Any], fallback_meta: dict[str, Any] | None) -> list[str]:
ids: list[str] = []
ids.append(record.get("stable_id", ""))
ids.extend(record.get("extracted_cves") or [])
if fallback_meta:
ids.extend(fallback_meta.get("extracted_cves") or [])
ids.extend(fallback_meta.get("vendor_ids") or [])
guid = fallback_meta.get("guid")
if guid:
ids.append(guid)
link = fallback_meta.get("permalink")
if link:
ids.append(link)
return [i for i in ids if i]
def _unique(seq: list[str]) -> list[str]:
seen: set[str] = set()
out: list[str] = []
for x in seq:
if x and x not in seen:
seen.add(x)
out.append(x)
return out
def merge(
data: dict[str, Any],
classifications: list[dict[str, Any]],
new_items_by_stable_id: dict[str, dict[str, Any]],
scan_date: str,
) -> None:
for rec in classifications:
if not rec.get("stable_id"):
continue
if rec.get("reconsider"):
_apply_reconsider(data, rec, scan_date)
else:
_apply_new_item(data, rec, new_items_by_stable_id, scan_date)
def _apply_new_item(
data: dict[str, Any],
rec: dict[str, Any],
new_items_by_stable_id: dict[str, dict[str, Any]],
scan_date: str,
) -> None:
stable_id = rec["stable_id"]
meta = new_items_by_stable_id.get(stable_id, {})
canonical = _canonical(rec, meta)
bucket = rec.get("bucket", "unrelated")
title = (meta.get("title") or "").strip()
existing = data["seen"].get(canonical)
if existing is None:
data["seen"][canonical] = {
"bucket": bucket,
"first_seen": scan_date,
"seen_at": scan_date,
"title": title,
"sources": _unique(list(rec.get("sources") or []) + ([meta.get("source")] if meta.get("source") else [])),
"urls": _unique(list(rec.get("urls") or []) + ([meta.get("permalink")] if meta.get("permalink") else [])),
}
else:
existing["bucket"] = state.promote_bucket(existing["bucket"], bucket)
existing["seen_at"] = scan_date
existing.setdefault("first_seen", existing.get("seen_at") or scan_date)
if not existing.get("title") and title:
existing["title"] = title
existing["sources"] = _unique(list(existing.get("sources") or []) + list(rec.get("sources") or []) + ([meta.get("source")] if meta.get("source") else []))
existing["urls"] = _unique(list(existing.get("urls") or []) + list(rec.get("urls") or []) + ([meta.get("permalink")] if meta.get("permalink") else []))
for alt in _alt_ids(rec, meta):
if alt != canonical:
data["aliases"][alt] = canonical
def _apply_reconsider(
data: dict[str, Any],
rec: dict[str, Any],
scan_date: str,
) -> None:
"""Re-review of a previously-classified entry. The record's stable_id
is the entry's current canonical key in state; `canonical_id` may name
a new key (e.g. a freshly-assigned CVE) — in which case we rekey."""
old_key = rec["stable_id"]
new_canonical = _canonical(rec, None)
bucket = rec.get("bucket", "unrelated")
# Resolve the current record — may need to follow an alias if the
# backlog snapshot the classifier reviewed is slightly out of sync.
current_key = old_key if old_key in data["seen"] else data["aliases"].get(old_key)
if not current_key or current_key not in data["seen"]:
print(f"warning: reconsider record for {old_key!r} points at no "
f"state entry; skipping.", file=sys.stderr)
return
existing = data["seen"][current_key]
# Overwrite bucket unconditionally (allows demotions) and stamp the
# reconsideration date so we can later throttle if this grows.
existing["bucket"] = bucket
existing["seen_at"] = scan_date
existing["reconsidered_at"] = scan_date
# Union any fresh sources/urls the classifier surfaced.
if rec.get("sources"):
existing["sources"] = _unique(list(existing.get("sources") or []) + list(rec["sources"]))
if rec.get("urls"):
existing["urls"] = _unique(list(existing.get("urls") or []) + list(rec["urls"]))
# Alias every alt ID the classifier provided to the current key
# (before a possible rekey below redirects them).
for alt in _alt_ids(rec, None):
if alt != current_key:
data["aliases"][alt] = current_key
# Rekey if Claude newly identified a canonical ID (e.g., a CVE for a
# vendor-ID entry). If the destination already exists, merge; else
# move. In both cases, retarget all aliases and leave the old key
# itself as an alias.
if new_canonical and new_canonical != current_key:
if new_canonical in data["seen"]:
dest = data["seen"][new_canonical]
dest["bucket"] = state.promote_bucket(dest.get("bucket", "unrelated"), existing.get("bucket", "unrelated"))
dest["sources"] = _unique(list(dest.get("sources") or []) + list(existing.get("sources") or []))
dest["urls"] = _unique(list(dest.get("urls") or []) + list(existing.get("urls") or []))
if not dest.get("title") and existing.get("title"):
dest["title"] = existing["title"]
dest["seen_at"] = scan_date
dest["reconsidered_at"] = scan_date
dest.setdefault("first_seen", existing.get("first_seen") or scan_date)
del data["seen"][current_key]
else:
data["seen"][new_canonical] = existing
del data["seen"][current_key]
for alias_key, target in list(data["aliases"].items()):
if target == current_key:
data["aliases"][alias_key] = new_canonical
data["aliases"][current_key] = new_canonical
# Clean up any self-aliases the retarget may have produced.
for k in [k for k, v in data["aliases"].items() if k == v]:
del data["aliases"][k]
def ensure_stub_reports(scan_date: str) -> None:
"""If the Claude step was skipped, write empty stub watch_*.md files so the
report artifact is consistent across runs."""
day = scan_date[:10] # YYYY-MM-DD
stub = "(no new items in this window)\n"
for bucket in ("toimplement", "tocheck", "unrelated"):
p = pathlib.Path(f"watch_{day}_{bucket}.md")
if not p.exists():
p.write_text(stub)
def write_snapshots(data: dict[str, Any], scan_date: str) -> None:
"""Write current_toimplement.md and current_tocheck.md — full backlog
snapshots reflecting every entry in state under those buckets. A human
who reads only the latest run's artifact sees the complete picture
without having to consult prior runs."""
for bucket in ("toimplement", "tocheck"):
entries = [
(cid, rec) for cid, rec in data["seen"].items()
if rec.get("bucket") == bucket
]
# Oldest first — long-lingering items stay at the top as a reminder.
entries.sort(key=lambda kv: kv[1].get("first_seen") or kv[1].get("seen_at") or "")
out = [
f"# Current `{bucket}` backlog",
"",
f"_Snapshot as of {scan_date}. "
f"{len(entries)} item(s). Oldest first._",
"",
]
if not entries:
out.append("(backlog is empty)")
else:
for cid, rec in entries:
title = rec.get("title") or ""
first_seen = (rec.get("first_seen") or rec.get("seen_at") or "")[:10]
sources = ", ".join(rec.get("sources") or []) or "(none)"
out.append(f"- **{cid}**" + (f"{title}" if title else ""))
out.append(f" first seen {first_seen} · sources: {sources}")
for u in rec.get("urls") or []:
out.append(f" - {u}")
out.append("")
pathlib.Path(f"current_{bucket}.md").write_text("\n".join(out))
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--scan-date", default=os.environ.get("SCAN_DATE", ""))
ap.add_argument("--classifications", type=pathlib.Path, default=CLASSIFICATIONS_PATH)
ap.add_argument("--new-items", type=pathlib.Path, default=NEW_ITEMS_PATH)
args = ap.parse_args()
scan_date = args.scan_date or datetime.datetime.now(datetime.timezone.utc).isoformat()
data = state.load()
classifications = _load_json(args.classifications, [])
new_items_doc = _load_json(args.new_items, {"items": []})
new_items_by_stable_id = {it["stable_id"]: it for it in new_items_doc.get("items", []) if it.get("stable_id")}
if not isinstance(classifications, list):
print(f"warning: {args.classifications} is not a list; ignoring", file=sys.stderr)
classifications = []
merge(data, classifications, new_items_by_stable_id, scan_date)
data["last_run"] = scan_date
scan_now = datetime.datetime.fromisoformat(scan_date.replace("Z", "+00:00"))
before, after = state.prune(data, RETENTION_DAYS, scan_now)
state.save(data)
ensure_stub_reports(scan_date)
write_snapshots(data, scan_date)
print(f"Merged {len(classifications)} classifications.")
print(f"Pruned seen: {before} -> {after} entries (retention={RETENTION_DAYS}d).")
print(f"Aliases: {len(data['aliases'])}.")
return 0
if __name__ == "__main__":
sys.exit(main())
-59
View File
@@ -1,59 +0,0 @@
"""Declarative list of sources polled by the daily vuln scan."""
from dataclasses import dataclass
from typing import Literal
Kind = Literal["rss", "atom", "html"]
@dataclass(frozen=True)
class Source:
name: str
url: str
kind: Kind
# For HTML sources: regexes used to extract advisory IDs from the page.
advisory_id_patterns: tuple[str, ...] = ()
# Human-facing URL to use as permalink fallback when `url` points at a
# non-browsable endpoint (e.g. a JS data file). Empty = use `url`.
display_url: str = ""
# Per-source UA override. AMD's CDN drops connections when the UA string
# contains a parenthesized URL, while Intel/ARM's WAF rejects UAs that
# don't identify themselves — so we can't use one UA everywhere.
# Empty = use the module-level USER_AGENT.
user_agent: str = ""
SOURCES: tuple[Source, ...] = (
Source("phoronix", "https://www.phoronix.com/rss.php", "rss"),
Source("oss-sec", "https://seclists.org/rss/oss-sec.rss", "rss"),
Source("lwn", "https://lwn.net/headlines/newrss", "rss"),
Source("project-zero", "https://googleprojectzero.blogspot.com/feeds/posts/default", "atom"),
Source("vusec", "https://www.vusec.net/feed/", "rss"),
Source("comsec-eth", "https://comsec.ethz.ch/category/news/feed/", "rss"),
# api.msrc.microsoft.com/update-guide/rss is the real RSS endpoint; the
# msrc.microsoft.com/... URL returns the SPA shell (2.7 KB) instead.
Source("msrc", "https://api.msrc.microsoft.com/update-guide/rss", "rss"),
Source("cisa", "https://www.cisa.gov/cybersecurity-advisories/all.xml", "rss"),
Source("cert-cc", "https://www.kb.cert.org/vuls/atomfeed/", "atom"),
Source("intel-psirt", "https://www.intel.com/content/www/us/en/security-center/default.html", "html",
(r"INTEL-SA-\d+",)),
Source("amd-psirt", "https://www.amd.com/en/resources/product-security.html", "html",
(r"AMD-SB-\d+",),
user_agent="spectre-meltdown-checker/vuln-watch"),
Source("arm-spec", "https://developer.arm.com/Arm%20Security%20Center/Speculative%20Processor%20Vulnerability", "html",
(r"CVE-\d{4}-\d{4,7}",)),
# transient.fail renders its attack table from tree.js client-side; we
# pull the JS file directly (CVE regex works on its JSON-ish body).
Source("transient-fail", "https://transient.fail/tree.js", "html",
(r"CVE-\d{4}-\d{4,7}",),
display_url="https://transient.fail/"),
)
# Identify ourselves honestly. Akamai/Cloudflare WAFs fronting intel.com,
# developer.arm.com, and cisa.gov return 403 when the UA claims "Mozilla"
# but TLS/HTTP fingerprint doesn't match a real browser — an honest bot UA
# passes those rules cleanly.
USER_AGENT = (
"spectre-meltdown-checker/vuln-watch "
"(+https://github.com/speed47/spectre-meltdown-checker)"
)
REQUEST_TIMEOUT = 30
-137
View File
@@ -1,137 +0,0 @@
"""Load/save/migrate/lookup helpers for state/seen.json.
Schema v2:
{
"schema_version": 2,
"last_run": "<iso8601>|null",
"sources": {
"<name>": {
"etag": "...",
"last_modified": "...",
"hwm_id": "...",
"hwm_published_at": "<iso8601>",
"last_fetched_at": "<iso8601>",
"last_status": 200|304|<http-err>|"<str-err>"
}
},
"seen": {
"<canonical_id>": {
"bucket": "toimplement|tocheck|unrelated",
"seen_at": "<iso8601>",
"sources": ["<source-name>", ...],
"urls": ["<permalink>", ...]
}
},
"aliases": { "<alt_id>": "<canonical_id>" }
}
"""
from __future__ import annotations
import datetime
import json
import pathlib
from typing import Any
STATE_PATH = pathlib.Path("state/seen.json")
SCHEMA_VERSION = 2
def empty() -> dict[str, Any]:
return {
"schema_version": SCHEMA_VERSION,
"last_run": None,
"sources": {},
"seen": {},
"aliases": {},
}
def load(path: pathlib.Path = STATE_PATH) -> dict[str, Any]:
if not path.exists():
# Fallback: a committed bootstrap seed, used to bridge a workflow
# rename (old workflow_id's artifacts are invisible to the new one).
# Remove the bootstrap file once one successful run has produced a
# normal artifact, otherwise it will shadow any future first-run.
bootstrap = path.parent / f"{path.name}.bootstrap"
if bootstrap.exists():
print(f"state: seeding from {bootstrap} (no prior-run artifact found)")
path = bootstrap
if not path.exists():
return empty()
data = json.loads(path.read_text())
return _migrate(data)
def save(data: dict[str, Any], path: pathlib.Path = STATE_PATH) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n")
def _migrate(data: dict[str, Any]) -> dict[str, Any]:
"""Bring any older schema up to SCHEMA_VERSION."""
version = data.get("schema_version")
if version == SCHEMA_VERSION:
data.setdefault("sources", {})
data.setdefault("aliases", {})
data.setdefault("seen", {})
return data
# v1 shape: {"last_run": ..., "seen": {<id>: {bucket, seen_at, source, cve?}}}
migrated_seen: dict[str, Any] = {}
aliases: dict[str, str] = {}
for key, entry in (data.get("seen") or {}).items():
rec = {
"bucket": entry.get("bucket", "unrelated"),
"seen_at": entry.get("seen_at"),
"sources": [entry["source"]] if entry.get("source") else [],
"urls": [key] if isinstance(key, str) and key.startswith("http") else [],
}
migrated_seen[key] = rec
# If a v1 entry had a CVE that differs from the key, alias the CVE -> key.
cve = entry.get("cve")
if cve and cve != key:
aliases[cve] = key
return {
"schema_version": SCHEMA_VERSION,
"last_run": data.get("last_run"),
"sources": {},
"seen": migrated_seen,
"aliases": aliases,
}
def lookup(data: dict[str, Any], candidate_ids: list[str]) -> str | None:
"""Return the canonical key if any candidate is already known, else None."""
seen = data["seen"]
aliases = data["aliases"]
for cid in candidate_ids:
if not cid:
continue
if cid in seen:
return cid
canonical = aliases.get(cid)
if canonical and canonical in seen:
return canonical
return None
_BUCKET_STRENGTH = {"unrelated": 0, "tocheck": 1, "toimplement": 2}
def promote_bucket(current: str, incoming: str) -> str:
"""Return whichever of two buckets represents the 'stronger' classification."""
return incoming if _BUCKET_STRENGTH.get(incoming, 0) > _BUCKET_STRENGTH.get(current, 0) else current
def prune(data: dict[str, Any], days: int, now: datetime.datetime) -> tuple[int, int]:
"""Drop seen entries older than `days`, and aliases pointing at dropped keys."""
cutoff = (now - datetime.timedelta(days=days)).isoformat()
before = len(data["seen"])
data["seen"] = {
k: v for k, v in data["seen"].items()
if (v.get("seen_at") or "9999") >= cutoff
}
data["aliases"] = {k: v for k, v in data["aliases"].items() if v in data["seen"]}
return before, len(data["seen"])
+13167
View File
File diff suppressed because it is too large Load Diff
-824
View File
@@ -1,824 +0,0 @@
{
"aliases": {
"CVE-2018-3615": "CVE-2018-3646",
"CVE-2018-3620": "CVE-2018-3646",
"CVE-2025-54505": "https://www.phoronix.com/news/AMD-FP-DSS-Zen-1-Bug",
"CVE-2026-33691": "https://seclists.org/oss-sec/2026/q2/175",
"CVE-2026-41113": "https://seclists.org/oss-sec/2026/q2/176",
"CVE-2026-4519": "CVE-2026-4786",
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-33055": "CVE-2026-33055",
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-33056": "CVE-2026-33056",
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-4786": "CVE-2026-4786",
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-5160": "CVE-2026-5160",
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-6100": "CVE-2026-6100",
"https://seclists.org/oss-sec/2026/q2/173": "CVE-2026-33691",
"https://seclists.org/oss-sec/2026/q2/176": "CVE-2026-41113",
"https://transient.fail/": "CVE-2019-11091"
},
"last_run": "2026-04-19T14:06:07.928573+00:00",
"schema_version": 2,
"seen": {
"AMD-SB-7050": {
"bucket": "tocheck",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"amd-psirt"
],
"title": "",
"urls": []
},
"AMD-SB-7053": {
"bucket": "toimplement",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"amd-psirt"
],
"title": "",
"urls": []
},
"CVE-2017-5715": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2017-5715",
"urls": [
"https://transient.fail/"
]
},
"CVE-2017-5753": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2017-5753",
"urls": [
"https://transient.fail/"
]
},
"CVE-2017-5754": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2017-5754",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-12126": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-12126",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-12127": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-12127",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-12130": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-12130",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-3639": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-3639",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-3640": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-3640",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-3646": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-3615",
"urls": [
"https://transient.fail/"
]
},
"CVE-2018-3665": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2018-3665",
"urls": [
"https://transient.fail/"
]
},
"CVE-2019-11091": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2019-11091",
"urls": [
"https://transient.fail/"
]
},
"CVE-2019-11135": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"transient-fail"
],
"title": "CVE-2019-11135",
"urls": [
"https://transient.fail/"
]
},
"CVE-2025-66335": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-25917": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-30898": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-30912": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-32228": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-32690": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-33055": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"msrc"
],
"title": "CVE-2026-33055 tar-rs incorrectly ignores PAX size headers if header size is nonzero",
"urls": [
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-33055"
]
},
"CVE-2026-33056": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"msrc"
],
"title": "CVE-2026-33056 tar-rs: unpack_in can chmod arbitrary directories by following symlinks",
"urls": [
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-33056"
]
},
"CVE-2026-33691": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"oss-sec"
],
"title": "Re: [CVE-2026-33691] OWASP CRS whitespace padding bypass vulnerability",
"urls": [
"https://seclists.org/oss-sec/2026/q2/173",
"https://seclists.org/oss-sec/2026/q2/174",
"https://seclists.org/oss-sec/2026/q2/175"
]
},
"CVE-2026-39314": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-40170": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-40948": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-41113": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"oss-sec"
],
"title": "CVE-2026-41113: RCE in sagredo fork of qmail",
"urls": [
"https://seclists.org/oss-sec/2026/q2/176"
]
},
"CVE-2026-41254": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": []
},
"CVE-2026-4786": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"msrc"
],
"title": "CVE-2026-4786 Incomplete mitigation of CVE-2026-4519, %action expansion for command injection to webbrowser.open()",
"urls": [
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-4786"
]
},
"CVE-2026-5160": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"msrc"
],
"title": "CVE-2026-5160",
"urls": [
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-5160"
]
},
"CVE-2026-6100": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"msrc"
],
"title": "CVE-2026-6100 Use-after-free in lzma.LZMADecompressor, bz2.BZ2Decompressor, and gzip.GzipFile after re-use under memory pressure",
"urls": [
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-6100"
]
},
"https://lwn.net/Articles/1066156/": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"lwn"
],
"title": "",
"urls": [
"https://lwn.net/Articles/1066156/"
]
},
"https://lwn.net/Articles/1067029/": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"lwn"
],
"title": "",
"urls": [
"https://lwn.net/Articles/1067029/"
]
},
"https://lwn.net/Articles/1068400/": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"lwn"
],
"title": "",
"urls": [
"https://lwn.net/Articles/1068400/"
]
},
"https://lwn.net/Articles/1068473/": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"lwn"
],
"title": "Seven stable kernels for Saturday",
"urls": [
"https://lwn.net/Articles/1068473/"
]
},
"https://seclists.org/oss-sec/2026/q2/164": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/164"
]
},
"https://seclists.org/oss-sec/2026/q2/167": {
"bucket": "toimplement",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/167"
]
},
"https://seclists.org/oss-sec/2026/q2/169": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/169"
]
},
"https://seclists.org/oss-sec/2026/q2/170": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/170"
]
},
"https://seclists.org/oss-sec/2026/q2/171": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/171"
]
},
"https://seclists.org/oss-sec/2026/q2/172": {
"bucket": "unrelated",
"first_seen": "2026-04-19T09:01:57Z",
"seen_at": "2026-04-19T09:01:57Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/172"
]
},
"https://seclists.org/oss-sec/2026/q2/173": {
"bucket": "unrelated",
"first_seen": "2026-04-19T09:01:57Z",
"seen_at": "2026-04-19T09:01:57Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/173"
]
},
"https://seclists.org/oss-sec/2026/q2/174": {
"bucket": "unrelated",
"first_seen": "2026-04-19T09:01:57Z",
"seen_at": "2026-04-19T09:01:57Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/174"
]
},
"https://seclists.org/oss-sec/2026/q2/175": {
"bucket": "unrelated",
"first_seen": "2026-04-19T09:01:57Z",
"seen_at": "2026-04-19T09:01:57Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/175"
]
},
"https://seclists.org/oss-sec/2026/q2/176": {
"bucket": "unrelated",
"first_seen": "2026-04-19T09:01:57Z",
"seen_at": "2026-04-19T09:01:57Z",
"sources": [
"oss-sec"
],
"title": "",
"urls": [
"https://seclists.org/oss-sec/2026/q2/176"
]
},
"https://www.phoronix.com/news/AMD-2026-New-SMCA-Bank-Types": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "Linux 7.1 Adds New AMD SMCA Bank Types, Presumably For Upcoming EPYC Venice",
"urls": [
"https://www.phoronix.com/news/AMD-2026-New-SMCA-Bank-Types"
]
},
"https://www.phoronix.com/news/AMD-FP-DSS-Zen-1-Bug": {
"bucket": "toimplement",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/AMD-FP-DSS-Zen-1-Bug"
]
},
"https://www.phoronix.com/news/AMD-Harvested-GPUs-Linux": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "Valve Developer Further Improves Old AMD GPUs: HD 7870 XT Finally Working On Linux",
"urls": [
"https://www.phoronix.com/news/AMD-Harvested-GPUs-Linux"
]
},
"https://www.phoronix.com/news/AMD-RDNA4m-RADV-ACO": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/AMD-RDNA4m-RADV-ACO"
]
},
"https://www.phoronix.com/news/CachyOS-Super-Charged-Linux-7.0": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "CachyOS Rolls Out A Super-Charged Linux 7.0 Kernel",
"urls": [
"https://www.phoronix.com/news/CachyOS-Super-Charged-Linux-7.0"
]
},
"https://www.phoronix.com/news/GNOME-Graphs-2.0-Maps-Transit": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/GNOME-Graphs-2.0-Maps-Transit"
]
},
"https://www.phoronix.com/news/GhostBSD-26.1-R15.0p2": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "GhostBSD 26.1 Now Based On FreeBSD 15.0, Switches to XLibre X Server",
"urls": [
"https://www.phoronix.com/news/GhostBSD-26.1-R15.0p2"
]
},
"https://www.phoronix.com/news/KDE-Plasma-6.7-Session": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/KDE-Plasma-6.7-Session"
]
},
"https://www.phoronix.com/news/Linux-7.1-Block-Changes": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "Linux 7.1 Sees RAID Fixes, IO_uring Enhancements",
"urls": [
"https://www.phoronix.com/news/Linux-7.1-Block-Changes"
]
},
"https://www.phoronix.com/news/Linux-7.1-Crypto-QAT-Zstd": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "Intel QAT Zstd, QAT Gen6 Improvements Merged For Linux 7.1",
"urls": [
"https://www.phoronix.com/news/Linux-7.1-Crypto-QAT-Zstd"
]
},
"https://www.phoronix.com/news/Linux-7.1-HRTIMER-Overhaul": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/Linux-7.1-HRTIMER-Overhaul"
]
},
"https://www.phoronix.com/news/Linux-7.1-New-NTFS-Driver": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/Linux-7.1-New-NTFS-Driver"
]
},
"https://www.phoronix.com/news/Linux-7.1-Scheduler": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/Linux-7.1-Scheduler"
]
},
"https://www.phoronix.com/news/Linux-7.1-Sound": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "Linux 7.1 Sound Code Adds Bus Keepers: Aiming For Better Apple Silicon Support",
"urls": [
"https://www.phoronix.com/news/Linux-7.1-Sound"
]
},
"https://www.phoronix.com/news/Wine-11.7-Released": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/news/Wine-11.7-Released"
]
},
"https://www.phoronix.com/news/WireGuard-For-Windows-1.0": {
"bucket": "unrelated",
"first_seen": "2026-04-19T14:06:07.928573+00:00",
"seen_at": "2026-04-19T14:06:07.928573+00:00",
"sources": [
"phoronix"
],
"title": "WireGuard For Windows Reaches v1.0",
"urls": [
"https://www.phoronix.com/news/WireGuard-For-Windows-1.0"
]
},
"https://www.phoronix.com/review/ubuntu-2604-xe2-lunar-lake": {
"bucket": "unrelated",
"first_seen": "2026-04-18T14:24:43Z",
"seen_at": "2026-04-18T14:24:43Z",
"sources": [
"phoronix"
],
"title": "",
"urls": [
"https://www.phoronix.com/review/ubuntu-2604-xe2-lunar-lake"
]
}
},
"sources": {
"amd-psirt": {
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Sun, 19 Apr 2026 11:14:54 GMT",
"last_status": 200
},
"arm-spec": {
"etag": "\"c31f3bde81531617e355836b0f44bb05:1775559058.494352\"",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Tue, 07 Apr 2026 10:50:58 GMT",
"last_status": 200
},
"cert-cc": {
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Fri, 17 Apr 2026 16:57:16 GMT",
"last_status": 200
},
"cisa": {
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_status": 200
},
"comsec-eth": {
"etag": "W/\"ad4d6e03055d4fc084e06c1140e33311\"",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Fri, 17 Apr 2026 18:23:42 GMT",
"last_status": 200
},
"intel-psirt": {
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_status": 200
},
"lwn": {
"etag": "\"7a7f043e5c25da73032a33e230cd5adc23dce68d29b294dfdcaf96dcaf23a08c\"",
"hwm_id": "https://lwn.net/Articles/1068473/",
"hwm_published_at": "2026-04-18T15:48:08+00:00",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_status": 200
},
"msrc": {
"etag": "\"0x8DE9DE3F08E081D\"",
"hwm_id": "CVE-2026-4786",
"hwm_published_at": "2026-04-19T08:01:53+00:00",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Sun, 19 Apr 2026 07:19:05 GMT",
"last_status": 200
},
"oss-sec": {
"etag": "\"3ac0-64fc0e1ee44d0\"",
"hwm_id": "CVE-2026-41113",
"hwm_published_at": "2026-04-18T19:12:07+00:00",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Sat, 18 Apr 2026 19:15:03 GMT",
"last_status": 200
},
"phoronix": {
"hwm_id": "https://www.phoronix.com/news/AMD-Harvested-GPUs-Linux",
"hwm_published_at": "2026-04-19T13:25:50+00:00",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_status": 200
},
"project-zero": {
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Tue, 31 Mar 2026 22:50:42 GMT",
"last_status": 200
},
"transient-fail": {
"etag": "W/\"67ab337f-158c5\"",
"hwm_id": null,
"hwm_published_at": null,
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Tue, 11 Feb 2025 11:24:47 GMT",
"last_status": 200
},
"vusec": {
"etag": "W/\"6391ad5e2c03310cced577acfca52f46\"",
"last_fetched_at": "2026-04-19T14:02:00.309888+00:00",
"last_modified": "Mon, 16 Mar 2026 09:18:55 GMT",
"last_status": 200
}
}
}