Compare commits

...

15 Commits

Author SHA1 Message Date
github-actions[bot] 024e5a94b9 fix: another attempt to avoid sigpipe on grep (#519)
built from commit 5bbffaf053
 dated 2026-06-10 23:33:10 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 Take this opportunity to factorize all the greps in /proc/cpuinfo
into a helper that avoids using a pipe to entirely avoid SIGPIPE
on a possibly gigantic /proc/cpuinfo
2026-06-10 21:34:38 +00:00
github-actions[bot] 2ce3775287 fix: mmio: don't report "Intel never assessed this CPU" when the MSR is unreadable
built from commit 23ea5427b5
 dated 2026-06-08 22:55:45 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 When IA32_ARCH_CAPABILITIES (0x10a) can't be read from userspace (no msr
module, or kernel lockdown under Secure Boot), the FBSDP_NO/PSDP_NO/SBDR_SSDP_NO
bits were left at 0 ("explicitly not immune") instead of -1 ("unknown"). For a
recent CPU not in any kernel model list (e.g. Arrow Lake), this wrongly flipped
the MMIO Stale Data verdict into the "out of servicing period, Intel never
assessed this CPU" bucket.
2026-06-08 20:57:09 +00:00
github-actions[bot] 476ebe59fc fix: dmesg_grep: avoid sigpipe on some systems (#519)
built from commit cc159fe7fd
 dated 2026-06-08 21:41:08 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 Use 'grep -m 1' (works under Linux, busybox, BSD) instead of piping to head -n1
2026-06-08 19:42:39 +00:00
github-actions[bot] 7847c95208 arm64: add SSBS detection
built from commit 737cfe4a5f
 dated 2026-06-06 17:01:46 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-06-06 15:04:30 +00:00
github-actions[bot] 738a4f55f8 fix: zenbleed (CVE-2023-20593) handle the VM guest case (#488)
built from commit 0b022ee253
 dated 2026-06-06 16:09:55 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 Zenbleed (CVE-2023-20593) is mitigated either by up-to-date CPU microcode
or by the host kernel setting FP_BACKUP_FIX (DE_CFG MSR 0xc0011029 bit 9).
Both are applied at the host level. Inside a Xen dom0/domU (or any VM
guest) the script can't read that MSR and can't trust the microcode
version the hypervisor presents, so it wrongly concluded "kernel too old
+ microcode not fixed" and reported VULN even though the host had applied
the microcode fix (passing on bare metal).

In live mode, when the verdict would be VULN and we're running as a guest,
report UNK instead, explaining the mitigation is host-level and not
observable from inside the guest. Bare metal is unchanged (still VULN),
offline analysis is unchanged, and a guest with positively-confirmed
fixed microcode still reports OK.
2026-06-06 14:15:18 +00:00
github-actions[bot] 03cde37e67 doc: add CVE-2026-46174 (AMD Zen 2 Op Cache Improper Resource Isolation) to the unsupported list
built from commit d8abfbe20a
 dated 2026-06-06 15:07:18 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-06-06 13:08:44 +00:00
github-actions[bot] ad2b7edeca doc: add unsupported CVE to list (CVE-2021-26314 / CVE-2021-26313 / CVE-2025-52533)
built from commit 45fe976ca9
 dated 2026-06-06 12:53:21 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 CVE-2021-26314 / CVE-2021-26313 (Floating-Point Value Injection (FPVI) and Speculative Code Store Bypass (SCSB))
CVE-2025-52533 (AMD On-Chip Debug Interface Improper Access Control)
2026-06-06 10:55:16 +00:00
github-actions[bot] fa6f0b14e9 fix: arm64: collapse per-core CPU info lists to a single line
built from commit 44ba3790d9
 dated 2026-06-02 19:11:45 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 Store the per-core implementer/part/arch/variant/revision lists
space-separated (no embedded newlines, which also cleans up JSON and
prometheus output) and dedup them for the human-readable display, so
homogeneous systems show e.g. "0x41" instead of repeating it per core.
2026-06-02 17:16:47 +00:00
github-actions[bot] 17056d8f08 add scripts/update_mcedb.sh to be used in cron github workflow
built from commit 5d1363ee4b
 dated 2026-06-01 22:20:03 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-06-01 20:22:11 +00:00
github-actions[bot] e844f9cff3 feat: hide CVE checks that arebirrelevant for current arch
built from commit 7329c1fd2f
 dated 2026-04-21 08:53:08 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

 CVE_REGISTRY gains an optional fifth field that tags checks as x86-only or
arm-only, untagged entries apply everywhere. The main CVE dispatcher and the
affectedness summary both skip gated entries in default "all CVEs" runs,
removing the noise of arm64 errata on x86 hosts and of x86 CVEs on ARM hosts
across text, json, nrpe and prometheus outputs. Explicit --cve/--variant/--errata
selection bypasses the gate so manual queries still run anywhere.
The gate honours no-hw mode by ignoring the host CPU and keying off the
inspected kernel's architecture only, which handles cross-arch offline
analysis driven by --kernel/--config/--map.
2026-04-21 06:56:29 +00:00
github-actions[bot] 5262efbf55 fix: mmio stale data: EOL Intel CPUs may be vulnerable (#437)
built from commit 03b1787d69
 dated 2026-04-20 22:42:04 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-20 20:44:06 +00:00
github-actions[bot] 440424f524 doc: readme: correct markdown indentation for unordered list items (#569)
built from commit 8a417e5579
 dated 2026-04-21 00:02:47 +0800
 by 林博仁 Buo-ren Lin (Buo.Ren.Lin@gmail.com)

 Signed-off-by: 林博仁(Buo-ren Lin) <buo.ren.lin@gmail.com>
2026-04-20 16:05:45 +00:00
github-actions[bot] b7b0efa773 doc: add Jump Conditional Code (JCC) Erratum to the unsupported list
built from commit b7a6182a65
 dated 2026-04-20 17:47:50 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
2026-04-20 15:49:22 +00:00
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
11 changed files with 1109 additions and 625 deletions
-36
View File
@@ -1,36 +0,0 @@
name: autoupdate
on:
workflow_dispatch:
schedule:
- cron: '42 9 * * *'
permissions:
pull-requests: write
jobs:
autoupdate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install prerequisites
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends iucode-tool sqlite3 unzip
- name: Update microcode versions
run: ./spectre-meltdown-checker.sh --update-builtin-fwdb
- name: Check git diff
id: diff
run: |
echo change="$(git diff spectre-meltdown-checker.sh | awk '/MCEDB/ { if(V) { print V" to "$4; exit } else { V=$4 } }')" >> "$GITHUB_OUTPUT"
echo nbdiff="$(git diff spectre-meltdown-checker.sh | grep -cE -- '^\+# [AI],')" >> "$GITHUB_OUTPUT"
git diff
cat "$GITHUB_OUTPUT"
- name: Create Pull Request if needed
if: steps.diff.outputs.nbdiff != '0'
uses: peter-evans/create-pull-request@v7
with:
branch: autoupdate-fwdb
commit-message: "update: fwdb from ${{ steps.diff.outputs.change }}, ${{ steps.diff.outputs.nbdiff }} microcode changes"
title: "[Auto] Update fwdb from ${{ steps.diff.outputs.change }}"
body: |
Automated PR to update fwdb from ${{ steps.diff.outputs.change }}
Detected ${{ steps.diff.outputs.nbdiff }} microcode changes
-199
View File
@@ -1,199 +0,0 @@
# Daily transient-execution vulnerability scan
You are a scheduled agent running inside a GitHub Actions job. Your job
is to audit public news/advisory sources for **transient-execution and
CPU side-channel vulnerabilities** that may need to be added to
**spectre-meltdown-checker** (this repository).
## What counts as "relevant"
spectre-meltdown-checker detects, reports, and suggests mitigations for
CPU vulnerabilities such as: Spectre v1/v2/v4, Meltdown, Foreshadow/L1TF,
MDS (ZombieLoad/RIDL/Fallout), TAA, SRBDS, iTLB Multihit, Zenbleed,
Downfall (GDS), Retbleed, Inception, SRSO, BHI, RFDS, Reptar, FP-DSS,
and any similar microarchitectural side-channel or speculative-execution
issue on x86 (Intel/AMD) or ARM CPUs. It also surfaces related hardware
mitigation features (SMAP/SMEP/UMIP/IBPB/eIBRS/STIBP…) when they gate
the remediation for a tracked CVE.
It does **not** track generic software CVEs, GPU driver bugs, networking
stacks, filesystem bugs, userspace crypto issues, or unrelated kernel
subsystems.
## Inputs handed to you by the workflow
- Working directory: the repo root (`/github/workspace` in Actions, or
wherever `actions/checkout` placed it). You may `grep` the repo to
check whether a CVE or codename is already covered.
- `state/seen.json` — memory carried over from the previous run, with
shape:
```json
{
"last_run": "2026-04-17T08:00:12Z",
"seen": {
"<stable-id-1>": { "bucket": "unrelated", "seen_at": "2026-04-17T08:00:12Z", "source": "phoronix" },
"<stable-id-2>": { "bucket": "tocheck", "seen_at": "2026-04-17T08:00:12Z", "source": "oss-sec", "cve": "CVE-2026-1234" }
}
}
```
On the very first run, or when the prior artifact has expired,
the file exists but `seen` is empty and `last_run` is `null`.
- Environment: `SCAN_DATE` (ISO-8601 timestamp of the run start, set by
the workflow). Treat this as "now" for all time-window decisions.
## Time window
This is a belt-and-suspenders design — use **both** mechanisms:
1. **Primary: stable-id dedup.** If an item's stable identifier (see
below) is already present in `state.seen`, skip it entirely — it
was classified on a previous day.
2. **Secondary: 25-hour window.** Among *new* items, prefer those whose
publication/update timestamp is within the last 25 h relative to
`SCAN_DATE`. This bounds work when the prior artifact expired
(90-day retention) or when `last_run` is stale (missed runs).
If `last_run` is older than 25 h, widen the window to
`now - last_run + 1h` so no items are lost across missed runs.
3. Items without a parseable timestamp: include them (fail-safe).
## Sources to poll
Fetch each URL with
`curl -sS -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" -L --max-time 20`.
On non-2xx or timeout, record the failure in the run summary and
continue — do not abort.
### RSS / Atom feeds (primary — parse feed timestamps)
| Short name | URL |
|-----------------|-----|
| phoronix | https://www.phoronix.com/rss.php |
| oss-sec | https://seclists.org/rss/oss-sec.rss |
| lwn | https://lwn.net/headlines/newrss |
| project-zero | https://googleprojectzero.blogspot.com/feeds/posts/default |
| vusec | https://www.vusec.net/feed/ |
| comsec-eth | https://comsec.ethz.ch/category/news/feed/ |
| msrc | https://msrc.microsoft.com/update-guide/rss |
| cisa | https://www.cisa.gov/cybersecurity-advisories/all.xml |
| cert-cc | https://www.kb.cert.org/vuls/atomfeed/ |
### HTML pages (no RSS — fetch, extract dated entries)
| Short name | URL |
|-----------------|-----|
| intel-psirt | https://www.intel.com/content/www/us/en/security-center/default.html |
| amd-psirt | https://www.amd.com/en/resources/product-security.html |
| arm-spec | https://developer.arm.com/Arm%20Security%20Center/Speculative%20Processor%20Vulnerability |
| transient-fail | https://transient.fail/ |
For HTML pages: look for advisory tables or listings with dates. Extract
the advisory title, permalink, and date. If a page has no dates at all,
compare its content against `state.seen` — any new advisory IDs not yet
classified count as "new this run".
## Stable identifier per source
Use the first available of these, in order, as the dedup key:
1. Vendor advisory ID (`INTEL-SA-01234`, `AMD-SB-7001`, `ARM-2024-0042`,
`VU#123456`, `CVE-YYYY-NNNNN`)
2. RSS `<guid>` / Atom `<id>`
3. Permalink URL (`<link>`)
Always also record the permalink URL in the output file so a human can
click through.
## Classification rules
For each **new** item (not in `state.seen`) that passes the time window,
pick exactly one bucket:
- **toimplement** — a clearly-identified new transient-execution / CPU
side-channel vulnerability in scope, **and not already covered by
this repo**. Verify the second half by grepping the repo for the CVE
ID *and* the codename before classifying; if either matches existing
code, demote to `tocheck`.
- **tocheck** — plausibly in-scope but ambiguous: mitigation-only
feature (LASS, IBT, APIC-virt, etc.); item seemingly already
implemented but worth confirming scope; unclear applicability
(e.g. embedded-only ARM SKU); CVE-ID pending; contradictory info
across sources. State clearly what would resolve the ambiguity.
- **unrelated** — everything else.
Tie-breakers: prefer `tocheck` over `unrelated` when uncertain. Prefer
`tocheck` over `toimplement` when the CVE ID is still "reserved" /
"pending" — false positives in `toimplement` waste human time more than
false positives in `tocheck`.
## Outputs
Compute `TODAY=$(date -u -d "$SCAN_DATE" +%F)`. Write these files under
the repo root, overwriting if they already exist (they shouldn't unless
the workflow re-ran the same day):
- `rss_${TODAY}_toimplement.md`
- `rss_${TODAY}_tocheck.md`
- `rss_${TODAY}_unrelated.md`
Each file uses level-2 headers per source short-name, then one bullet
per item: the stable ID (if any), the permalink URL, and 12 sentences.
Keep entries terse — a human skims these daily.
```markdown
## oss-sec
- **CVE-2026-1234** — https://www.openwall.com/lists/oss-security/2026/04/18/3
New Intel transient-execution bug "Foo" disclosed today; affects
Redwood Cove cores, microcode fix pending. Not yet covered by this
repo (grepped for CVE-2026-1234 and "Foo" — no matches).
## phoronix
- https://www.phoronix.com/news/Some-Article
Linux 7.2 drops a compiler-target flag; unrelated to CPU side channels.
```
If a bucket has no items, write the file with a single line
`(no new items in this window)` so it is obvious the job ran.
### Run summary
Append this block to the **tocheck** file (creating it if empty):
```markdown
## Run summary
- SCAN_DATE: <value>
- window cutoff: <computed cutoff>
- prior state size: <N> entries, last_run=<value>
- per-source new item counts: phoronix=<n>, oss-sec=<n>, lwn=<n>, ...
- fetch failures: <list, or "none">
- total classified this run: toimplement=<n>, tocheck=<n>, unrelated=<n>
```
### State update
Rewrite `state/seen.json` with:
- `last_run` = `SCAN_DATE`
- `seen` = union of (pruned prior `seen`) (all items classified this
run, keyed by stable ID, with `{bucket, seen_at=SCAN_DATE, source, cve?}`)
Pruning (keep state bounded): drop any entry whose `seen_at` is older
than 30 days before `SCAN_DATE`. The workflow step also does this as
a safety net, but do it here too so the in-memory view is consistent.
## Guardrails
- Do NOT modify any repo source code. Only write the three markdown
output files and `state/seen.json`.
- Do NOT create commits, branches, or PRs.
- Do NOT call any tool that posts externally (Slack, GitHub comments,
issues, email, etc.).
- Do NOT follow links off-site for deeper investigation unless strictly
needed to resolve a `tocheck` ambiguity — budget of at most 5 such
follow-ups per run.
- If a source returns unexpectedly large content, truncate to the first
~200 items before parsing.
- If total runtime exceeds 15 minutes, finish whatever you can,
write partial outputs, and note it in the run summary.
-33
View File
@@ -1,33 +0,0 @@
name: 'Manage stale issues and PRs'
on:
schedule:
- cron: '37 7 * * *'
workflow_dispatch:
inputs:
action:
description: "dry-run"
required: true
default: "dryrun"
type: choice
options:
- dryrun
- apply
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
any-of-labels: 'needs-more-info,answered'
labels-to-remove-when-unstale: 'needs-more-info,answered'
days-before-stale: 30
days-before-close: 7
stale-issue-label: stale
remove-stale-when-updated: true
debug-only: ${{ case(inputs.action == 'dryrun', true, false) }}
-129
View File
@@ -1,129 +0,0 @@
name: Online search for vulns
on:
schedule:
- cron: '42 8 * * *'
workflow_dispatch: {} # allow manual trigger
permissions:
contents: read
actions: read # needed to list/download previous run artifacts
id-token: write # needed to mint OIDC token
concurrency:
group: vuln-scan
cancel-in-progress: true
jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout repository (for grep-based dedup against existing checks)
uses: actions/checkout@v5
with:
fetch-depth: 1
persist-credentials: false
# ---- Load previous state ---------------------------------------------
# Find the most recent successful run of THIS workflow (other than the
# current one) and pull its `vuln-scan-state` artifact. On the very
# first run there will be none — that's fine, we start empty.
- name: Find previous successful run id
id: prev
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
run_id=$(gh run list \
--workflow="${{ github.workflow }}" \
--status=success \
--limit 1 \
--json databaseId \
--jq '.[0].databaseId // empty')
echo "run_id=${run_id}" >> "$GITHUB_OUTPUT"
if [ -n "$run_id" ]; then
echo "Found previous successful run: $run_id"
else
echo "No previous successful run — starting from empty state."
fi
- name: Download previous state artifact
if: steps.prev.outputs.run_id != ''
uses: actions/download-artifact@v4
continue-on-error: true # tolerate retention expiry
with:
name: vuln-scan-state
path: state/
run-id: ${{ steps.prev.outputs.run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Ensure state file exists
run: |
mkdir -p state
if [ ! -f state/seen.json ]; then
echo '{"last_run": null, "seen": {}}' > state/seen.json
echo "Initialized empty state."
fi
echo "State size: $(wc -c < state/seen.json) bytes"
# ---- Run the scan ----------------------------------------------------
# Runs Claude Code against daily_vuln_scan_prompt.md.
# That prompt file fully specifies: sources to poll, how to read
# state/seen.json, the 25-hour window, the output files to write,
# and how to rewrite state/seen.json at the end of the run.
- name: Research for online mentions of new vulns
id: scan
uses: anthropics/claude-code-action@v1
env:
SCAN_DATE: ${{ github.run_started_at }}
with:
claude_args: |
--model claude-opus-4-7 --allowedTools "Read,Write,Edit,Bash,Grep,Glob,WebFetch"
prompt: |
Read the full task instructions from .github/workflows/daily_vuln_scan_prompt.md and execute them end-to-end. That file fully specifies: sources to poll, how to read and update state/seen.json, the 25-hour window, which rss_YYYY-MM-DD_*.md files to write, and the run guardrails. Use $SCAN_DATE (env var) as "now" for time-window decisions.
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
- name: Upload Claude execution log
if: ${{ always() && steps.scan.outputs.execution_file != '' }}
uses: actions/upload-artifact@v4
with:
name: claude-execution-log-${{ github.run_id }}
path: ${{ steps.scan.outputs.execution_file }}
retention-days: 30
if-no-files-found: warn
# ---- Persist outputs -------------------------------------------------
- name: Prune state (keep only entries from the last 30 days)
run: |
python3 - <<'PY'
import json, datetime, pathlib
p = pathlib.Path("state/seen.json")
data = json.loads(p.read_text())
cutoff = (datetime.datetime.utcnow() - datetime.timedelta(days=30)).isoformat()
before = len(data.get("seen", {}))
data["seen"] = {
k: v for k, v in data.get("seen", {}).items()
if v.get("seen_at", "9999") >= cutoff
}
after = len(data["seen"])
p.write_text(json.dumps(data, indent=2, sort_keys=True))
print(f"Pruned state: {before} -> {after} entries")
PY
- name: Upload new state artifact
uses: actions/upload-artifact@v4
with:
name: vuln-scan-state
path: state/seen.json
retention-days: 90
if-no-files-found: error
- name: Upload daily report
uses: actions/upload-artifact@v4
with:
name: vuln-scan-report-${{ github.run_id }}
path: rss_*.md
retention-days: 90
if-no-files-found: warn
+19 -11
View File
@@ -40,6 +40,14 @@ CVE | Name | Aliases
[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
The following entries are ARM64 silicon errata that the kernel actively works around. They have no assigned CVE; they are tracked only by ARM's erratum numbers. Select them with `--errata <number>` or the associated `--variant` mnemonic.
ID | Name | Affected cores
-- | ---- | --------------
CVE-0001-0001 | Speculative AT TLB corruption (errata 1165522, 1319367, 1319537, 1530923) | Cortex-A55/A57/A72/A76
CVE-0001-0002 | Speculative unprivileged load (errata 2966298, 3117295) | Cortex-A510/A520
CVE-0001-0003 | MSR SSBS not self-synchronizing (erratum 3194386 + siblings) | Cortex-A76/A77/A78/A78C/A710/A715/A720/A720AE/A725, X1/X1C/X2/X3/X4/X925, Neoverse-N1/N2/N3/V1/V2/V3/V3AE
## 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.
@@ -272,23 +280,23 @@ In **Hardware-only** mode, the script only reports CPU information and per-CVE h
- 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
```
```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
```
```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
```
```bash
chmod +x spectre-meltdown-checker.sh
sudo ./spectre-meltdown-checker.sh
```
### Using a docker container
+44
View File
@@ -188,6 +188,18 @@ Observable timing discrepancy in some Intel processors allows an authenticated u
**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-26314 / CVE-2021-26313 — Floating-Point Value Injection (FPVI) and Speculative Code Store Bypass (SCSB)
- **Bulletin:** [AMD-SB-1003](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-1003.html) (FPVI and SCSB); [AMD-SB-7050](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7050.html) (FPVI variant, informational)
- **Intel advisory:** [Floating Point Value Injection](https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/floating-point-value-injection.html)
- **Research paper:** [Rage Against the Machine Clear (FPVI/SCSB) — VUSec, USENIX Security '21](https://www.vusec.net/projects/fpvi-scsb/)
- **Affected CPUs:** All supported AMD CPU products; Intel CPUs (FPVI)
- **CVSS:** 5.5 (Medium) for both
FPVI (CVE-2021-26314) lets an attacker inject arbitrary floating-point values into the transient execution window opened by a floating-point machine clear, so that dependent operations transiently compute on attacker-influenced values that can then be inferred through a microarchitectural covert channel. SCSB (CVE-2021-26313) is the companion vulnerability where overwritten instructions may still be executed speculatively. AMD-SB-7050 documents an FPVI variant (from the "TREVEX" detection-framework paper) that can be triggered without denormal inputs; AMD considers it to fall within the existing scope of CVE-2021-26314 and assigned it no new CVE, classifying it as informational only.
**Why out of scope:** The mitigation responsibility falls on individual software, not on the kernel or microcode. Both AMD and Intel recommend that software vendors analyze their code for vulnerable speculative floating-point sequences and insert an `LFENCE` to serialize execution. No microcode update, no CPUID flag, no MSR, and no kernel configuration option was issued, and there is no `/sys/devices/system/cpu/vulnerabilities/` entry for FPVI or SCSB — the kernel never added one, because the fix is not a kernel-level control. This is the same situation as [SLAM (CVE-2020-12965)](#cve-2020-12965--transient-execution-of-non-canonical-accesses-slam) and "Take A Way": the vendor's guidance is "software inserts LFENCE in its own code," leaving nothing for this tool to check. The AMD-SB-7050 variant adds nothing detectable, as it is informational and reuses the existing (software-only) FPVI guidance.
## CVE-2021-26318 — AMD Prefetch Attacks through Power and Time
- **Issue:** [#412](https://github.com/speed47/spectre-meltdown-checker/issues/412)
@@ -307,3 +319,35 @@ A weakness in AMD's microcode signature verification (AES-CMAC hash) allows load
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.
## CVE-2025-52533 — AMD On-Chip Debug Interface Improper Access Control
- **Advisory:** [NVD CVE-2025-52533](https://nvd.nist.gov/vuln/detail/CVE-2025-52533)
- **Affected CPUs:** AMD (various; on-chip debug/test interface)
- **CVSS:** 8.7 (High)
- **CWE:** [CWE-1191 (On-Chip Debug and Test Interface With Improper Access Control)](https://cwe.mitre.org/data/definitions/1191.html)
Improper access control in an on-chip debug interface could allow a privileged attacker to enable a debug interface and potentially compromise data confidentiality or integrity.
**Why out of scope:** Not a transient or speculative execution vulnerability — this is an access-control flaw in a hardware debug/test interface (CWE-1191), with no side-channel or speculative execution component, and it requires a privileged attacker. There is no Linux kernel sysfs entry, no CPUID flag, and no kernel-side mitigation: the fix is delivered as platform/PSP firmware and proven via remote attestation against AMD's Key Distribution Service (KDS), with several SKUs marked "no fix planned." None of this is detectable by this tool, which inspects OS-loadable microcode revisions, CPUID/MSR bits, kernel capabilities, and sysfs.
## CVE-2026-46174 — AMD Zen 2 Op Cache Improper Resource Isolation
- **Bulletin:** [AMD-SB-7052](https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7052.html) (CPU OP Cache Corruption)
- **Kernel fix:** [commit 1e23b30a80b1](https://github.com/torvalds/linux/commit/1e23b30a80b14e5764657401ee2cca030525ae8e) — `x86/CPU/AMD: Prevent improper isolation of shared resources in Zen2's op cache`
- **Affected CPUs:** AMD Zen 2
- **CVSS:** 8.8 (High)
Resources in the Zen 2 micro-op (op) cache can be improperly shared, causing instruction corruption that may be leveraged to execute instructions at a higher privilege level (userspace-to-kernel escalation). The Linux fix sets a bug-fix bit (bit 33) in the AMD `BP_CFG` model-specific register (`0xc001102e`) via `msr_set_bit()` in `init_amd_zen2()`, and only on bare metal (skipped when `X86_FEATURE_HYPERVISOR` is set, as the mitigation is the host's responsibility for guests).
**Why out of scope:** Not a transient or speculative execution vulnerability — this is an op-cache resource-isolation bug that causes *instruction corruption* (an integrity/correctness erratum), with no side-channel or speculative data-leak component, which places it outside the vulnerability class this tool detects. It is also undetectable by this tool's standard framework: the kernel deliberately adds no `/sys/devices/system/cpu/vulnerabilities/` entry, no `X86_BUG_*` flag (so nothing in `/proc/cpuinfo`), no dmesg message, and no kernel command-line parameter. The mitigation is an unconditional inline MSR bit-set with no greppable named symbol, so it leaves no handle for no-runtime (kernel image / `System.map`) detection. The only possible check would be a live read of `BP_CFG` bit 33, which requires root and the `msr` module, works on bare metal only (guests report `N/A`), and would be a bespoke one-off outside the established CVE-detection model — the same situation as the [JCC Erratum](#no-cve--jump-conditional-code-jcc-erratum) below, but for AMD.
## No CVE — Jump Conditional Code (JCC) Erratum
- **Issue:** [#329](https://github.com/speed47/spectre-meltdown-checker/issues/329)
- **Intel whitepaper:** [Mitigations for Jump Conditional Code Erratum](https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf)
- **Affected CPUs:** Intel 6th through 10th generation Core and Xeon processors (Skylake through Cascade Lake)
A microarchitectural correctness erratum where a conditional jump instruction that straddles or ends at a 64-byte instruction fetch boundary can corrupt the branch predictor state, potentially causing incorrect execution. Intel addressed this in a November 2019 microcode update. Compilers and assemblers (GCC, LLVM, binutils) also introduced alignment options (`-mbranch-alignment`, `-x86-branches-within-32B-boundaries`) to pad jump instructions away from boundary conditions, preserving performance on CPUs with updated microcode.
**Why out of scope:** The JCC erratum is a microarchitectural correctness bug, not a transient or speculative execution side-channel vulnerability. No CVE was ever assigned. Red Hat noted that privilege escalation "has not been ruled out" but made no definitive security finding, and no exploit has been demonstrated. There is no Linux sysfs entry, no CPUID bit, and no MSR flag exposing the mitigation status. The microcode fix introduces no detectable hardware indicator, so checking for it would require maintaining a per-CPU-stepping minimum microcode version table (the design principle 3 exception) — costly to maintain without a CVE anchor or confirmed exploitability to justify the ongoing work. The kernel compiler mitigation is a build-time-only change (instruction alignment) with no observable runtime state.
+5 -3
View File
@@ -102,7 +102,9 @@ boundaries by a malicious guest. Prioritise remediation where
### `cpu`
CPU hardware identification. `null` when `--no-hw` is active.
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
@@ -140,7 +142,7 @@ fields from the other architecture.
#### `cpu.x86.capabilities`
Each capability is a **tri-state**: `true` (present), `false` (absent), or
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).
@@ -238,7 +240,7 @@ with an unknown CVE ID).
| `status` | string | `"OK"` / `"VULN"` / `"UNK"` | Check outcome (see below) |
| `vulnerable` | boolean \| null | `false` / `true` / `null` | `false`=OK, `true`=VULN, `null`=UNK |
| `info` | string | | Human-readable description of the specific mitigation state or reason |
| `sysfs_status` | string \| null | `"OK"` / `"VULN"` / `"UNK"` / null | Status as reported by the kernel via `/sys/devices/system/cpu/vulnerabilities/`; null if sysfs was not consulted for this CVE |
| `sysfs_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
+7 -7
View File
@@ -127,7 +127,7 @@
},
"cpu": {
"description": "CPU hardware identification. Null when --no-hw is active. Contains an 'arch' discriminator ('x86' or 'arm') and a matching arch-specific sub-object with identification fields and capabilities.",
"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" },
{
@@ -180,16 +180,16 @@
"type": ["string", "null"]
},
"capabilities": {
"description": "CPU feature flags detected via CPUID and MSR reads. Each value is true (present), false (absent), or null (not applicable or could not be read).",
"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": "Indirect Branch Restricted Speculation" },
"ibpb": { "type": ["boolean", "null"], "description": "Indirect Branch Prediction Barrier" },
"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": "Single Thread Indirect Branch Predictors" },
"ssbd": { "type": ["boolean", "null"], "description": "Speculative Store Bypass Disable" },
"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" },
@@ -231,7 +231,7 @@
"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)" },
"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)" }
}
+7 -2
View File
@@ -51,6 +51,7 @@ STATUS: summary | perfdata
| 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)
@@ -59,15 +60,19 @@ Never parsed by the monitoring core; safe to add or reorder.
#### Context notes
Printed before per-CVE details when applicable:
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 a VM host (KVM, Xen, VMware…) |
| `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
+46 -16
View File
@@ -90,13 +90,16 @@ smc_build_info{version="25.30.0250400123",mode="live",run_as_root="true",paranoi
Operating system and kernel metadata. Always value `1`.
Absent in offline mode when neither `uname -r` nor `uname -m` is available.
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` (live mode only) |
| `kernel_arch` | string | Output of `uname -m` (live mode only) |
| `hypervisor_host` | `true` / `false` | Whether this machine is detected as a hypervisor host (running KVM, Xen, VMware, etc.) |
| `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:**
```
@@ -114,26 +117,47 @@ a malicious guest. Always prioritise remediation on hosts where
### `smc_cpu_info`
CPU hardware and microcode metadata. Always value `1`. Absent when `--no-hw`
is used.
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. `Intel`, `AuthenticAMD`) |
| `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`); absent on some ARM CPUs |
| `codename` | string | Intel CPU codename (e.g. `Coffee Lake`); absent on AMD and ARM |
| `smt` | `true` / `false` | Whether SMT (HyperThreading) is currently enabled |
| `microcode` | hex string | Installed microcode version (e.g. `0xf4`) |
| `microcode_latest` | hex string | Latest known-good microcode version from the firmware database |
| `microcode_up_to_date` | `true` / `false` | Whether `microcode == microcode_latest` |
| `microcode_blacklisted` | `true` / `false` | Whether the installed microcode is known to cause problems and should be rolled back |
| `cpuid` | hex string | Full CPUID value (e.g. `0x000906ed`) |
| `codename` | string | Intel CPU codename (e.g. `Coffee Lake`); absent on AMD/Hygon |
**Example:**
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="Intel",model="Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz",family="6",model_id="158",stepping="13",cpuid="0x000906ed",codename="Coffee Lake",smt="true",microcode="0xf4",microcode_latest="0xf4",microcode_up_to_date="true",microcode_blacklisted="false"} 1
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:**
@@ -352,9 +376,15 @@ 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_vuln` metrics appear. `mode="hw-only"` in
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`**
File diff suppressed because it is too large Load Diff