doc: add an and update the accordingly

This commit is contained in:
Stéphane Lesimple 2021-05-24 20:15:32 +02:00
parent 0ba71a443e
commit a87ace1f98
2 changed files with 120 additions and 24 deletions

93 Normal file
View File

@ -0,0 +1,93 @@
# Questions
- [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)
# Answers
## 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 VM.
A more detailed video explanation is available here:
## 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?
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 that 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).
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, 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 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 script 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.

View File

@ -1,37 +1,40 @@
Spectre & Meltdown Checker
A shell script to tell if your system is vulnerable against the several "speculative execution" CVEs that were made public since 2018.
- CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1'
- CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2'
- CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3'
- CVE-2018-3640 [rogue system register read] aka 'Variant 3a'
- CVE-2018-3639 [speculative store bypass] aka 'Variant 4'
- CVE-2018-3615 [L1 terminal fault] aka 'Foreshadow (SGX)'
- CVE-2018-3620 [L1 terminal fault] aka 'Foreshadow-NG (OS)'
- CVE-2018-3646 [L1 terminal fault] aka 'Foreshadow-NG (VMM)'
- CVE-2018-12126 [microarchitectural store buffer data sampling (MSBDS)] aka 'Fallout'
- CVE-2018-12130 [microarchitectural fill buffer data sampling (MFBDS)] aka 'ZombieLoad'
- CVE-2018-12127 [microarchitectural load port data sampling (MLPDS)] aka 'RIDL'
- CVE-2019-11091 [microarchitectural data sampling uncacheable memory (MDSUM)] aka 'RIDL'
- CVE-2019-11135 [TSX asynchronous abort] aka 'TAA' aka 'ZombieLoad V2'
- CVE-2018-12207 [machine check exception on page size changes (MCEPSC)] aka 'No eXcuses' aka 'iTLB Multihit'
- CVE-2020-0543 [Special Register Buffer Data Sampling (SRBDS)]
A shell script to tell whether your system is vulnerable to the several "speculative execution" CVEs that were made public since 2018.
CVE | Name | Aliases
------------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------
[CVE-2017-5753]( | Bounds Check Bypass | Spectre Variant 1
[CVE-2017-5715]( | Branch Target Injection | Spectre Variant 2
[CVE-2017-5754]( | Rogue Data Cache Load | Meltdown, Variant 3
[CVE-2018-3640]( | Rogue System Register Read | Variant 3a
[CVE-2018-3639]( | Speculative Store Bypass | Variant 4
[CVE-2018-3615]( | L1 Terminal Fault | L1TF, Foreshadow (SGX)
[CVE-2018-3620]( | L1 Terminal Fault | L1TF, Foreshadow-NG (OS)
[CVE-2018-3646]( | L1 Terminal Fault | L1TF, Foreshadow-NG (VMM)
[CVE-2018-12126]( | Microarchitectural Store Buffer Data Sampling | MSBDS, Fallout
[CVE-2018-12130]( | Microarchitectural Fill Buffer Data Sampling | MFBDS, ZombieLoad
[CVE-2018-12127]( | Microarchitectural Load Port Data Sampling | MLPDS, RIDL
[CVE-2019-11091]( | Microarchitectural Data Sampling Uncacheable Memory | MDSUM, RIDL
[CVE-2019-11135]( | TSX asynchronous abort | TAA, ZombieLoad V2
[CVE-2018-12207]( | Machine Mheck Exception on Page Size Changes | MCEPSC, No eXcuses, iTLB Multihit
[CVE-2020-0543]( | Special Register Buffer Data Sampling | SRBDS
Supported operating systems:
- Linux (all versions, flavors and distros)
- BSD (FreeBSD, NetBSD, DragonFlyBSD)
- BSD (namely FreeBSD, NetBSD, DragonFlyBSD. Others are [not supported](
For Linux systems, the script will detect mitigations, including backported non-vanilla patches, regardless of the advertised kernel version number and the distribution (such as Debian, Ubuntu, CentOS, RHEL, Fedora, openSUSE, Arch, ...), it also works if you've compiled your own kernel. More information [here](
Other operating systems such as MacOS, Windows, ESXi, etc. [will most likely never be supported](
Supported architectures:
- x86 (32 bits)
- amd64/x86_64 (64 bits)
- ARM and ARM64
- `x86` (32 bits)
- `amd64`/`x86_64` (64 bits)
- `ARM` and `ARM64`
- other architectures will work, but mitigations (if they exist) might not always be detected
For Linux systems, the script will detect mitigations, including backported non-vanilla patches, regardless of the advertised kernel version number and the distribution (such as Debian, Ubuntu, CentOS, RHEL, Fedora, openSUSE, Arch, ...), it also works if you've compiled your own kernel.
For BSD systems, the detection will work as long as the BSD you're using supports `cpuctl` and `linprocfs` (this is not the case of OpenBSD for example).
## Easy way to run the script
- Get the latest version of the script using `curl` *or* `wget`