mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-04-26 18:43:20 +02:00
Compare commits
72 Commits
source-bui
...
7e5eee74ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e5eee74ac | ||
|
|
9bef6ec533 | ||
|
|
f587d9355e | ||
|
|
83be8fd544 | ||
|
|
9383287fc6 | ||
|
|
a2823830a6 | ||
|
|
6212de226a | ||
|
|
f8873048fc | ||
|
|
463e33d61c | ||
|
|
4d1af90420 | ||
|
|
e8a3c7d7f5 | ||
|
|
8ae598802c | ||
|
|
48a4c0e49c | ||
|
|
1557bbee42 | ||
|
|
4530f39fae | ||
|
|
d247733496 | ||
|
|
fc66ee567a | ||
|
|
072b98cefd | ||
|
|
bceb62f982 | ||
|
|
aacdd35c57 | ||
|
|
c0a389b086 | ||
|
|
726f9e54f5 | ||
|
|
11210ab772 | ||
|
|
624aef4a46 | ||
|
|
b6a7ee2345 | ||
|
|
5698711b3d | ||
|
|
e0f9aeab81 | ||
|
|
2f550ba8cd | ||
|
|
3f60773ec4 | ||
|
|
acaf3b684f | ||
|
|
0ec51090ae | ||
|
|
e9cb988409 | ||
|
|
c147f3f7d4 | ||
|
|
065f19e313 | ||
|
|
1214e63687 | ||
|
|
67be7eb116 | ||
|
|
b4db134e49 | ||
|
|
d7cd9e8b6b | ||
|
|
a4c3900ef0 | ||
|
|
1d00acbc9a | ||
|
|
90a8a3057c | ||
|
|
40b7ae9098 | ||
|
|
27ac93dd39 | ||
|
|
dab7bebd3c | ||
|
|
8f76537159 | ||
|
|
fd7083cb08 | ||
|
|
8ef4c71d36 | ||
|
|
240d6db210 | ||
|
|
fbfdb89e7a | ||
|
|
5c571bacc6 | ||
|
|
6f8112c700 | ||
|
|
f46c743cad | ||
|
|
33bdd0688d | ||
|
|
7f87ade3fe | ||
|
|
e2d4d14e14 | ||
|
|
ddf2f2c723 | ||
|
|
fe376887ab | ||
|
|
7b41bcca2b | ||
|
|
151dd12e3e | ||
|
|
15ea90f312 | ||
|
|
5fd6a20ebb | ||
|
|
e7df6a3e30 | ||
|
|
ba24551c56 | ||
|
|
7c2699c01a | ||
|
|
6663b6422e | ||
|
|
fe55c70658 | ||
|
|
d0822e1f9d | ||
|
|
10e5b5749e | ||
|
|
4f7f83a40e | ||
|
|
4bbbd71564 | ||
|
|
c174a8b754 | ||
|
|
0f36203b5f |
36
.github/workflows/autoupdate.yml
vendored
Normal file
36
.github/workflows/autoupdate.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
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
|
||||
2
.github/workflows/expected_cve_count
vendored
2
.github/workflows/expected_cve_count
vendored
@@ -1 +1 @@
|
||||
32
|
||||
31
|
||||
|
||||
33
.github/workflows/stale.yml
vendored
Normal file
33
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
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) }}
|
||||
145
FAQ.md
145
FAQ.md
@@ -1,145 +0,0 @@
|
||||
# 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 offline mode), and completely ignores the advertised kernel version, to tell whether a given kernel mitigates vulnerabilities. This is especially useful for non-vanilla kernel, where patches might be backported, sometimes silently (this has already happened, too).
|
||||
|
||||
- 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.
|
||||
@@ -38,7 +38,6 @@ CVE | Name | Aliases
|
||||
[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?
|
||||
|
||||
@@ -78,7 +77,6 @@ CVE-2024-36350 (TSA-SQ) | 💥 | 💥 (1) | 💥 | 💥 (1) | Microcode + kernel
|
||||
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.
|
||||
|
||||
@@ -209,10 +207,6 @@ After a guest VM exits to the host, stale branch predictions from the guest can
|
||||
|
||||
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
|
||||
|
||||
@@ -124,17 +124,6 @@ A branch predictor initialization issue specific to Intel's Lion Cove microarchi
|
||||
|
||||
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)
|
||||
|
||||
@@ -102,9 +102,7 @@ boundaries by a malicious guest. Prioritise remediation where
|
||||
|
||||
### `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).
|
||||
CPU hardware identification. `null` when `--no-hw` is active.
|
||||
|
||||
The object uses `arch` as a discriminator: `"x86"` for Intel/AMD/Hygon CPUs,
|
||||
`"arm"` for ARM/Cavium/Phytium. Arch-specific fields live under a matching
|
||||
@@ -142,7 +140,7 @@ fields from the other architecture.
|
||||
|
||||
#### `cpu.x86.capabilities`
|
||||
|
||||
Every capability is a **tri-state**: `true` (present), `false` (absent), or
|
||||
Each capability is a **tri-state**: `true` (present), `false` (absent), or
|
||||
`null` (not applicable or could not be read, e.g. when not root or on AMD for
|
||||
Intel-specific features).
|
||||
|
||||
@@ -240,7 +238,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, or if the CVE's check read sysfs in silent/quiet mode (raw message is still captured in `sysfs_message`) |
|
||||
| `sysfs_status` | string \| null | `"OK"` / `"VULN"` / `"UNK"` / null | Status as reported by the kernel via `/sys/devices/system/cpu/vulnerabilities/`; null if sysfs was not consulted for this CVE |
|
||||
| `sysfs_message` | string \| null | | Raw text from the sysfs file (e.g. `"Mitigation: PTI"`); null if sysfs was not consulted |
|
||||
|
||||
#### Status values
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
},
|
||||
|
||||
"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.",
|
||||
"description": "CPU hardware identification. Null when --no-hw is active. Contains an 'arch' discriminator ('x86' or 'arm') and a matching arch-specific sub-object with identification fields and capabilities.",
|
||||
"oneOf": [
|
||||
{ "type": "null" },
|
||||
{
|
||||
@@ -180,16 +180,16 @@
|
||||
"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.",
|
||||
"description": "CPU feature flags detected via CPUID and MSR reads. Each value is true (present), false (absent), or null (not applicable or could not be read).",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"spec_ctrl": { "type": ["boolean", "null"], "description": "SPEC_CTRL MSR present (Intel; enables IBRS + IBPB via WRMSR)" },
|
||||
"ibrs": { "type": ["boolean", "null"], "description": "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)" },
|
||||
"ibrs": { "type": ["boolean", "null"], "description": "Indirect Branch Restricted Speculation" },
|
||||
"ibpb": { "type": ["boolean", "null"], "description": "Indirect Branch Prediction Barrier" },
|
||||
"ibpb_ret": { "type": ["boolean", "null"], "description": "IBPB on return (enhanced form)" },
|
||||
"stibp": { "type": ["boolean", "null"], "description": "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)" },
|
||||
"stibp": { "type": ["boolean", "null"], "description": "Single Thread Indirect Branch Predictors" },
|
||||
"ssbd": { "type": ["boolean", "null"], "description": "Speculative Store Bypass Disable" },
|
||||
"l1d_flush": { "type": ["boolean", "null"], "description": "L1D cache flush instruction" },
|
||||
"md_clear": { "type": ["boolean", "null"], "description": "VERW clears CPU buffers (MDS mitigation)" },
|
||||
"arch_capabilities": { "type": ["boolean", "null"], "description": "IA32_ARCH_CAPABILITIES MSR is present" },
|
||||
@@ -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): 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)" },
|
||||
"sbpb": { "type": ["boolean", "null"], "description": "Selective Branch Predictor Barrier (AMD Inception mitigation)" },
|
||||
"avx2": { "type": ["boolean", "null"], "description": "AVX2 supported (relevant to Downfall / GDS)" },
|
||||
"avx512": { "type": ["boolean", "null"], "description": "AVX-512 supported (relevant to Downfall / GDS)" }
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ 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)
|
||||
|
||||
@@ -60,19 +59,15 @@ 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:
|
||||
Printed before per-CVE details when applicable:
|
||||
|
||||
| Note | Condition |
|
||||
|---|---|
|
||||
| `NOTE: paranoid mode active, stricter mitigation requirements applied` | `--paranoid` was used |
|
||||
| `NOTE: hypervisor host detected (reason); L1TF/MDS severity is elevated` | System is detected as a VM host (KVM, Xen, VMware…) |
|
||||
| `NOTE: hypervisor host detected (reason); L1TF/MDS severity is elevated` | System is a VM host (KVM, Xen, VMware…) |
|
||||
| `NOTE: not a hypervisor host` | System is confirmed not a VM host |
|
||||
| `NOTE: not running as root; MSR reads skipped, results may be incomplete` | Script ran without root privileges |
|
||||
|
||||
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
|
||||
|
||||
@@ -90,16 +90,13 @@ smc_build_info{version="25.30.0250400123",mode="live",run_as_root="true",paranoi
|
||||
|
||||
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.
|
||||
Absent in offline mode when neither `uname -r` nor `uname -m` is available.
|
||||
|
||||
| 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`) |
|
||||
| `kernel_release` | string | Output of `uname -r` (live mode only) |
|
||||
| `kernel_arch` | string | Output of `uname -m` (live mode only) |
|
||||
| `hypervisor_host` | `true` / `false` | Whether this machine is detected as a hypervisor host (running KVM, Xen, VMware, etc.) |
|
||||
|
||||
**Example:**
|
||||
```
|
||||
@@ -117,47 +114,26 @@ 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 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):
|
||||
is used.
|
||||
|
||||
| Label | Values | Meaning |
|
||||
|---|---|---|
|
||||
| `vendor` | string | CPU vendor (e.g. `GenuineIntel`, `AuthenticAMD`, `HygonGenuine`, `ARM`) |
|
||||
| `vendor` | string | CPU vendor (e.g. `Intel`, `AuthenticAMD`) |
|
||||
| `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 |
|
||||
| `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 |
|
||||
|
||||
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:**
|
||||
**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
|
||||
smc_cpu_info{vendor="Intel",model="Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz",family="6",model_id="158",stepping="13",cpuid="0x000906ed",codename="Coffee Lake",smt="true",microcode="0xf4",microcode_latest="0xf4",microcode_up_to_date="true",microcode_blacklisted="false"} 1
|
||||
```
|
||||
|
||||
**Microcode labels:**
|
||||
@@ -376,15 +352,9 @@ 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
|
||||
is emitted but no `smc_vuln` metrics appear. `mode="hw-only"` in
|
||||
`smc_build_info` signals this.
|
||||
|
||||
**`--sysfs-only`**
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#
|
||||
# Stephane Lesimple
|
||||
#
|
||||
VERSION='26.33.0420460'
|
||||
VERSION='26.32.0410743'
|
||||
|
||||
# --- Common paths and basedirs ---
|
||||
readonly VULN_SYSFS_BASE="/sys/devices/system/cpu/vulnerabilities"
|
||||
@@ -208,12 +208,6 @@ g_smc_cpu_info_line=''
|
||||
|
||||
# CVE Registry: single source of truth for all CVE metadata.
|
||||
# Fields: cve_id|json_key_name|affected_var_suffix|complete_name_and_aliases
|
||||
#
|
||||
# Two ranges of placeholder IDs are reserved when no real CVE applies:
|
||||
# CVE-0000-NNNN: permanent placeholder for supplementary checks (--extra only)
|
||||
# that will never receive a real CVE (e.g. SLS, compile-time hardening).
|
||||
# CVE-9999-NNNN: temporary placeholder for real vulnerabilities awaiting CVE
|
||||
# assignment. Rename across the codebase once the real CVE is issued.
|
||||
readonly CVE_REGISTRY='
|
||||
CVE-2017-5753|SPECTRE VARIANT 1|variant1|Spectre Variant 1, bounds check bypass
|
||||
CVE-2017-5715|SPECTRE VARIANT 2|variant2|Spectre Variant 2, branch target injection
|
||||
@@ -247,7 +241,6 @@ CVE-2025-40300|VMSCAPE|vmscape|VMScape, VM-exit stale branch prediction
|
||||
CVE-2023-28746|RFDS|rfds|Register File Data Sampling (RFDS)
|
||||
CVE-2024-45332|BPI|bpi|Branch Privilege Injection (BPI)
|
||||
CVE-0000-0001|SLS|sls|Straight-Line Speculation (SLS)
|
||||
CVE-2025-54505|FPDSS|fpdss|FPDSS, AMD Zen1 Floating-Point Divider Stale Data Leak
|
||||
'
|
||||
|
||||
# Derive the supported CVE list from the registry
|
||||
@@ -745,9 +738,8 @@ is_cpu_affected() {
|
||||
affected_srbds=''
|
||||
affected_mmio=''
|
||||
affected_sls=''
|
||||
# DIV0, FPDSS, Zenbleed and Inception are all AMD specific, look for "is_amd" below:
|
||||
# DIV0, Zenbleed and Inception are all AMD specific, look for "is_amd" below:
|
||||
_set_immune div0
|
||||
_set_immune fpdss
|
||||
_set_immune zenbleed
|
||||
_set_immune inception
|
||||
# TSA is AMD specific (Zen 3/4), look for "is_amd" below:
|
||||
@@ -1245,23 +1237,13 @@ is_cpu_affected() {
|
||||
fi
|
||||
_set_immune variantl1tf
|
||||
|
||||
# DIV0 (Zen1/Zen+)
|
||||
# DIV0 (Zen1 only)
|
||||
# 77245f1c3c64 (v6.5, initial model list): family 0x17 models 0x00-0x2f, 0x50-0x5f
|
||||
# bfff3c6692ce (v6.8): moved to init_amd_zen1(), unconditional for all ZEN1-flagged CPUs
|
||||
# The kernel's X86_FEATURE_ZEN1 covers family 0x17 models 0x00-0x2f and 0x50-0x5f,
|
||||
# which spans both Zen1 (Summit Ridge, Naples, Raven Ridge, Snowy Owl) and Zen+
|
||||
# (Pinnacle Ridge, Picasso, Dali, Colfax) products -- all using the same divider silicon.
|
||||
# bfff3c6692ce (v6.8): moved to init_amd_zen1(), unconditional for all Zen1
|
||||
# All Zen1 CPUs are family 0x17, models 0x00-0x2f and 0x50-0x5f
|
||||
amd_legacy_erratum "$(amd_model_range 0x17 0x00 0x0 0x2f 0xf)" && _set_vuln div0
|
||||
amd_legacy_erratum "$(amd_model_range 0x17 0x50 0x0 0x5f 0xf)" && _set_vuln div0
|
||||
|
||||
# FPDSS: same Zen1/Zen+ cohort as DIV0 (both applied unconditionally in init_amd_zen1()).
|
||||
# e55d98e77561 (v7.1): unconditional in init_amd_zen1(); CVE-2025-54505 / AMD-SB-7053.
|
||||
# AMD-SB-7053 only enumerates a subset (EPYC 7001, EPYC Embedded 3000, Athlon/Ryzen 3000
|
||||
# with Radeon, Ryzen PRO 3000 with Radeon Vega), but the kernel mitigates the full
|
||||
# ZEN1 cohort, so we flag all of it to match the kernel's behavior.
|
||||
# shellcheck disable=SC2154
|
||||
[ "$affected_div0" = 0 ] && _set_vuln fpdss
|
||||
|
||||
# Zenbleed
|
||||
amd_legacy_erratum "$(amd_model_range 0x17 0x30 0x0 0x4f 0xf)" && _set_vuln zenbleed
|
||||
amd_legacy_erratum "$(amd_model_range 0x17 0x60 0x0 0x7f 0xf)" && _set_vuln zenbleed
|
||||
@@ -1471,7 +1453,7 @@ is_cpu_affected() {
|
||||
pr_debug "is_cpu_affected: final results: variant1=$affected_variant1 variant2=$affected_variant2 variant3=$affected_variant3 variant3a=$affected_variant3a"
|
||||
pr_debug "is_cpu_affected: final results: variant4=$affected_variant4 variantl1tf=$affected_variantl1tf msbds=$affected_msbds mfbds=$affected_mfbds"
|
||||
pr_debug "is_cpu_affected: final results: mlpds=$affected_mlpds mdsum=$affected_mdsum taa=$affected_taa itlbmh=$affected_itlbmh srbds=$affected_srbds"
|
||||
pr_debug "is_cpu_affected: final results: div0=$affected_div0 fpdss=$affected_fpdss zenbleed=$affected_zenbleed inception=$affected_inception retbleed=$affected_retbleed tsa=$affected_tsa downfall=$affected_downfall reptar=$affected_reptar rfds=$affected_rfds its=$affected_its"
|
||||
pr_debug "is_cpu_affected: final results: div0=$affected_div0 zenbleed=$affected_zenbleed inception=$affected_inception retbleed=$affected_retbleed tsa=$affected_tsa downfall=$affected_downfall reptar=$affected_reptar rfds=$affected_rfds its=$affected_its"
|
||||
pr_debug "is_cpu_affected: final results: vmscape=$affected_vmscape bpi=$affected_bpi sls=$affected_sls mmio=$affected_mmio"
|
||||
}
|
||||
affected_variantl1tf_sgx="$affected_variantl1tf"
|
||||
@@ -2167,7 +2149,7 @@ while [ -n "${1:-}" ]; do
|
||||
case "$2" in
|
||||
help)
|
||||
echo "The following parameters are supported for --variant (can be used multiple times):"
|
||||
echo "1, 2, 3, 3a, 4, msbds, mfbds, mlpds, mdsum, l1tf, taa, mcepsc, srbds, mmio, sbdr, sbds, drpw, div0, fpdss, zenbleed, downfall, retbleed, inception, reptar, rfds, tsa, tsa-sq, tsa-l1, its, vmscape, bpi, sls"
|
||||
echo "1, 2, 3, 3a, 4, msbds, mfbds, mlpds, mdsum, l1tf, taa, mcepsc, srbds, mmio, sbdr, sbds, drpw, div0, zenbleed, downfall, retbleed, inception, reptar, rfds, tsa, tsa-sq, tsa-l1, its, vmscape, bpi, sls"
|
||||
exit 0
|
||||
;;
|
||||
1)
|
||||
@@ -2242,10 +2224,6 @@ while [ -n "${1:-}" ]; do
|
||||
opt_cve_list="$opt_cve_list CVE-2023-20588"
|
||||
opt_cve_all=0
|
||||
;;
|
||||
fpdss)
|
||||
opt_cve_list="$opt_cve_list CVE-2025-54505"
|
||||
opt_cve_all=0
|
||||
;;
|
||||
zenbleed)
|
||||
opt_cve_list="$opt_cve_list CVE-2023-20593"
|
||||
opt_cve_all=0
|
||||
@@ -2402,17 +2380,15 @@ _prom_escape() {
|
||||
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' | tr '\n' ' '
|
||||
}
|
||||
|
||||
# Convert a shell capability value to a JSON boolean token
|
||||
# Args: $1=value (1=true, 0=false, -1/empty=null, any other non-empty string=true)
|
||||
# Prints: JSON token (true/false/null)
|
||||
# Note: capability variables can be set to arbitrary strings internally to carry
|
||||
# detection-path context (e.g. cap_ssbd='Intel SSBD'); for the JSON output those
|
||||
# are normalized to true so consumers see a clean boolean | null type.
|
||||
# Convert a shell capability value to a JSON token
|
||||
# Args: $1=value (1=true, 0=false, -1/empty=null, other string=quoted string)
|
||||
# Prints: JSON token
|
||||
_json_cap() {
|
||||
case "${1:-}" in
|
||||
1) printf 'true' ;;
|
||||
0) printf 'false' ;;
|
||||
-1 | '') printf 'null' ;;
|
||||
*) printf 'true' ;;
|
||||
*) printf '"%s"' "$(_json_escape "$1")" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -2515,7 +2491,7 @@ _build_json_system() {
|
||||
# Sets: g_json_cpu
|
||||
# shellcheck disable=SC2034
|
||||
_build_json_cpu() {
|
||||
local cpuid_hex codename caps arch_sub arch_type sbpb_norm
|
||||
local cpuid_hex codename caps arch_sub arch_type
|
||||
if [ -n "${cpu_cpuid:-}" ]; then
|
||||
cpuid_hex=$(printf '0x%08x' "$cpu_cpuid")
|
||||
else
|
||||
@@ -2526,15 +2502,6 @@ _build_json_cpu() {
|
||||
codename=$(get_intel_codename 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
# cap_sbpb uses non-standard encoding (1=YES, 2=NO, 3=UNKNOWN) because the
|
||||
# CVE-2023-20569 check distinguishes the unknown case. Normalize for JSON.
|
||||
case "${cap_sbpb:-}" in
|
||||
1) sbpb_norm=1 ;;
|
||||
2) sbpb_norm=0 ;;
|
||||
3) sbpb_norm=-1 ;;
|
||||
*) sbpb_norm='' ;;
|
||||
esac
|
||||
|
||||
# Determine architecture type and build the arch-specific sub-object
|
||||
case "${cpu_vendor:-}" in
|
||||
GenuineIntel | AuthenticAMD | HygonGenuine)
|
||||
@@ -2588,7 +2555,7 @@ _build_json_cpu() {
|
||||
"$(_json_cap "${cap_tsa_l1_no:-}")" \
|
||||
"$(_json_cap "${cap_verw_clear:-}")" \
|
||||
"$(_json_cap "${cap_autoibrs:-}")" \
|
||||
"$(_json_cap "$sbpb_norm")" \
|
||||
"$(_json_cap "${cap_sbpb:-}")" \
|
||||
"$(_json_cap "${cap_avx2:-}")" \
|
||||
"$(_json_cap "${cap_avx512:-}")")
|
||||
arch_sub=$(printf '{"family":%s,"model":%s,"stepping":%s,"cpuid":%s,"platform_id":%s,"hybrid":%s,"codename":%s,"capabilities":%s}' \
|
||||
@@ -12013,160 +11980,6 @@ check_CVE_2025_40300_bsd() {
|
||||
fi
|
||||
}
|
||||
|
||||
# >>>>>> vulns/CVE-2025-54505.sh <<<<<<
|
||||
|
||||
# vim: set ts=4 sw=4 sts=4 et:
|
||||
###############################
|
||||
# CVE-2025-54505, FPDSS, AMD Zen1 Floating-Point Divider Stale Data Leak
|
||||
|
||||
check_CVE_2025_54505() {
|
||||
check_cve 'CVE-2025-54505'
|
||||
}
|
||||
|
||||
# Print remediation advice for FPDSS when reporting VULN
|
||||
# Callers: check_CVE_2025_54505_linux
|
||||
_cve_2025_54505_explain_fix() {
|
||||
explain "Update your kernel to one that carries commit e55d98e77561 (\"x86/CPU: Fix FPDSS on Zen1\", mainline Linux 7.1),\n " \
|
||||
"or the equivalent backport from your distribution. The kernel sets bit 9 of MSR 0xc0011028 unconditionally on\n " \
|
||||
"every Zen1 CPU at boot, which disables the hardware optimization responsible for the leak.\n " \
|
||||
"To manually mitigate the issue right now, you may use the following command:\n " \
|
||||
"\`wrmsr -a 0xc0011028 \$((\$(rdmsr -c 0xc0011028) | (1<<9)))\`,\n " \
|
||||
"however note that this manual mitigation will only be active until the next reboot.\n " \
|
||||
"No microcode update is required: the chicken bit is present on every Zen1 CPU."
|
||||
}
|
||||
|
||||
check_CVE_2025_54505_linux() {
|
||||
local status sys_interface_available msg kernel_mitigated dmesg_fpdss msr_fpdss ret
|
||||
status=UNK
|
||||
sys_interface_available=0
|
||||
msg=''
|
||||
# No sysfs interface exists for this vulnerability (no /sys/devices/system/cpu/vulnerabilities/fpdss).
|
||||
# sys_interface_available stays 0.
|
||||
#
|
||||
# Kernel source inventory for FPDSS, traced via git blame:
|
||||
#
|
||||
# --- sysfs messages ---
|
||||
# none: this vulnerability has no sysfs entry
|
||||
#
|
||||
# --- Kconfig symbols ---
|
||||
# none: the mitigation is unconditional, not configurable (no CONFIG_* knob)
|
||||
#
|
||||
# --- kernel functions (for $opt_map / System.map) ---
|
||||
# none: the fix is two inline lines in init_amd_zen1(), no dedicated function
|
||||
#
|
||||
# --- dmesg ---
|
||||
# e55d98e77561 (v7.1, initial fix): "AMD Zen1 FPDSS bug detected, enabling mitigation."
|
||||
# (printed via pr_notice_once on every Zen1 CPU)
|
||||
#
|
||||
# --- /proc/cpuinfo bugs field ---
|
||||
# none: no X86_BUG_FPDSS flag defined; no cpuinfo exposure
|
||||
#
|
||||
# --- MSR ---
|
||||
# e55d98e77561 (v7.1): MSR_AMD64_FP_CFG = 0xc0011028, bit 9 = ZEN1_DENORM_FIX_BIT
|
||||
# kernel calls msr_set_bit() unconditionally on any Zen1 CPU in init_amd_zen1().
|
||||
# The bit is present in Zen1 silicon independently of microcode (no microcode
|
||||
# revision gate in the kernel, unlike Zenbleed which uses amd_zenbleed_microcode[]).
|
||||
#
|
||||
# --- CPU affection logic (for is_cpu_affected) ---
|
||||
# e55d98e77561 (v7.1): applied unconditionally in init_amd_zen1(), i.e. all Zen1
|
||||
# AMD: family 0x17 models 0x00-0x2f, 0x50-0x5f (same cohort as DIV0)
|
||||
# vendor scope: AMD only (Zen1 microarchitecture)
|
||||
#
|
||||
# --- stable backports ---
|
||||
# as of this writing, no stable/LTS backport has landed; only mainline (Linux 7.1).
|
||||
|
||||
if [ "$opt_sysfs_only" != 1 ]; then
|
||||
pr_info_nol "* Kernel supports FPDSS mitigation: "
|
||||
kernel_mitigated=''
|
||||
if [ -n "$g_kernel_err" ]; then
|
||||
pstatus yellow UNKNOWN "$g_kernel_err"
|
||||
elif is_x86_kernel && grep -q 'AMD Zen1 FPDSS bug detected' "$g_kernel"; then
|
||||
kernel_mitigated="found FPDSS mitigation message in kernel image"
|
||||
pstatus green YES "$kernel_mitigated"
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
|
||||
pr_info_nol "* FPDSS mitigation enabled and active: "
|
||||
msr_fpdss=''
|
||||
dmesg_fpdss=''
|
||||
if [ "$g_mode" = live ] && is_x86_cpu && is_cpu_affected "$cve"; then
|
||||
# guard with is_cpu_affected to avoid #GP on non-Zen1 CPUs where 0xc0011028 is undefined
|
||||
read_msr 0xc0011028
|
||||
ret=$?
|
||||
if [ "$ret" = "$READ_MSR_RET_OK" ]; then
|
||||
if [ $((ret_read_msr_value_lo >> 9 & 1)) -eq 1 ]; then
|
||||
msr_fpdss=1
|
||||
pstatus green YES "ZEN1_DENORM_FIX_BIT set in FP_CFG MSR"
|
||||
else
|
||||
msr_fpdss=0
|
||||
pstatus yellow NO "ZEN1_DENORM_FIX_BIT is cleared in FP_CFG MSR"
|
||||
fi
|
||||
else
|
||||
# MSR unreadable (lockdown, no msr module, etc.): fall back to dmesg
|
||||
dmesg_grep 'AMD Zen1 FPDSS bug detected'
|
||||
ret=$?
|
||||
if [ "$ret" -eq 0 ]; then
|
||||
dmesg_fpdss=1
|
||||
pstatus green YES "FPDSS mitigation message found in dmesg"
|
||||
elif [ "$ret" -eq 2 ]; then
|
||||
pstatus yellow UNKNOWN "couldn't read MSR and dmesg is truncated"
|
||||
else
|
||||
pstatus yellow UNKNOWN "couldn't read MSR and no FPDSS message in dmesg"
|
||||
fi
|
||||
fi
|
||||
elif [ "$g_mode" = live ]; then
|
||||
pstatus blue N/A "CPU is incompatible"
|
||||
else
|
||||
pstatus blue N/A "not testable in no-runtime mode"
|
||||
fi
|
||||
elif [ "$sys_interface_available" = 0 ]; then
|
||||
msg="/sys vulnerability interface use forced, but it's not available!"
|
||||
status=UNK
|
||||
fi
|
||||
|
||||
if ! is_cpu_affected "$cve"; then
|
||||
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
||||
elif [ -z "$msg" ]; then
|
||||
if [ "$opt_sysfs_only" != 1 ]; then
|
||||
if [ "$g_mode" = live ]; then
|
||||
if [ "$msr_fpdss" = 1 ] || [ "$dmesg_fpdss" = 1 ]; then
|
||||
pvulnstatus "$cve" OK "ZEN1_DENORM_FIX_BIT is set in FP_CFG MSR, mitigation is active"
|
||||
elif [ "$msr_fpdss" = 0 ]; then
|
||||
pvulnstatus "$cve" VULN "ZEN1_DENORM_FIX_BIT is cleared in FP_CFG MSR, FPDSS can leak data between threads"
|
||||
_cve_2025_54505_explain_fix
|
||||
elif [ -n "$kernel_mitigated" ]; then
|
||||
# MSR unreadable at runtime, but kernel image carries the mitigation code
|
||||
# and init_amd_zen1() sets the bit unconditionally, so mitigation is active
|
||||
pvulnstatus "$cve" OK "kernel image carries FPDSS mitigation code (init_amd_zen1 sets the MSR bit unconditionally at boot)"
|
||||
else
|
||||
pvulnstatus "$cve" VULN "your kernel doesn't support FPDSS mitigation"
|
||||
_cve_2025_54505_explain_fix
|
||||
fi
|
||||
else
|
||||
if [ -n "$kernel_mitigated" ]; then
|
||||
pvulnstatus "$cve" OK "Mitigation: FPDSS message found in kernel image"
|
||||
else
|
||||
pvulnstatus "$cve" VULN "your kernel doesn't support FPDSS mitigation"
|
||||
_cve_2025_54505_explain_fix
|
||||
fi
|
||||
fi
|
||||
else
|
||||
pvulnstatus "$cve" "$status" "no sysfs interface available for this CVE, use --no-sysfs to check"
|
||||
fi
|
||||
else
|
||||
pvulnstatus "$cve" "$status" "$msg"
|
||||
fi
|
||||
}
|
||||
|
||||
check_CVE_2025_54505_bsd() {
|
||||
if ! is_cpu_affected "$cve"; then
|
||||
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
||||
else
|
||||
pvulnstatus "$cve" UNK "your CPU is affected, but mitigation detection has not yet been implemented for BSD in this script"
|
||||
fi
|
||||
}
|
||||
|
||||
# >>>>>> main.sh <<<<<<
|
||||
|
||||
# vim: set ts=4 sw=4 sts=4 et:
|
||||
@@ -12562,7 +12375,7 @@ exit 0 # ok
|
||||
# with X being either I for Intel, or A for AMD
|
||||
# When the date is unknown it defaults to 20000101
|
||||
|
||||
# %%% MCEDB v349+i20260227+1cce
|
||||
# %%% MCEDB v349+i20260227+615b
|
||||
# I,0x00000611,0xFF,0x00000B27,19961218
|
||||
# I,0x00000612,0xFF,0x000000C6,19961210
|
||||
# I,0x00000616,0xFF,0x000000C6,19961210
|
||||
|
||||
Reference in New Issue
Block a user