Some old ARM processors (e.g., ARM926EJ-S) report CPU architecture
with suffix in /proc/cpuinfo (e.g., "5TEJ" for ARMv5TEJ).
This caused an "integer expression expected" error when comparing
against numeric values. Extract the numeric prefix before integer comparisons.
Fixes#505.
On ARM64 systems, /proc/cpuinfo uses different field names (CPU implementer,
CPU variant, CPU part, CPU revision) instead of x86-style fields (cpu family,
model, stepping). This left these variables empty, causing printf to fail
with 'invalid number' errors when formatting them as hex values.
Fixes#520.
The info page of GNU head says:
> For compatibility 'head' also supports an obsolete option syntax
> '-[NUM][bkm][cqv]', [...] Scripts intended for standard hosts should use
> '-c NUM' or '-n NUM' instead.
At least busybox's head does not support the `-NUM` syntax.
This contradicts our usual "if we don't know, consider vulnerable" motto,
but as this vuln is extremely specific (which is not the case for the Spectre
range of vulnerabilities, for example), this is the correct approach here.
on locked down kernels (Fedora / Red Hat feature that prevents writing
to MSRs from userspace, even if root), we can't write to FLUSH_CMD MSR
to verify that it's present. So fallback to checking the existence of
the L1D flush CPUID feature bit to infer that the microcode has been
updated in a recent enough version that also mitigates SGX (fixes for
both issues have been included in the same microcode updates for all
Intel CPUs)
When checking for CVE-2017-5715 (i.e. `check_CVE_2017_5715_linux()`),
if we can't inspect (with `readelf`) or decompress the Linux kernel
image, then we report there is no kernel image (i.e. `we need the
kernel image` or `kernel image missing`, respectively), which confuses
users when the associated file exists.
Instead use `kernel_err` to provide a correct and detailed description
of the problem (e.g. `missing '...' tool, please install it, usually
it's in the '...' package`), so the user can take the prescribed
action.
* fix --help message
Commit 7b72c20f89 added help text for the
--cve switch, and the "can be specified multiple times" note got
associated with the --cve switch instead of staying with the --variant
switch. Restore the line to belong to the --variant switch help
message.
* Add new variants to error message
Commit 8e870db4f5 added new variants but
did not add them to the error message that listed the allowable
variants. Add them now.
This change ensures we check for SMT and advise the user to disable it for maximum security.
Doing this, we'll help users mitigate a whole range of vulnerabilities taking advantage of SMT to attack purely from userland other userland processes, as seen in CVE-2018-5407 (also see #261)
On a (pre-SkyLake) system, where /sys/.../vulnerabilities/spectre_v2 is
"Mitigation: Full generic retpoline, IBPB: conditional, IBRS_FW, RSB filling"
the tool, incorrectly, reports, a couple of lines above:
* IBRS enabled and active: YES (for kernel and firmware code)
Use '\<IBRS\>', as suggested by @jirislaby, in upstream issue #275
(https://github.com/speed47/spectre-meltdown-checker/issues/275) when
checking whether IBRS is enabled/active for the kernel.
With that, the output becomes:
* IBRS enabled and active: YES (for firmware code only)
which is actually the case.
I double checked that, if the same kernel is used on a post-SkyLake
hardware, which on openSUSE uses IBRS as, even with this change, the
tool (this time correctly) reports:
* IBRS enabled and active: YES (for kernel and firmware code)
As we read sysctl values under the vmm hierarchy, the modules needs to be loaded,
so if not already done, we load it before testing for CVE-2018-3620 and CVE-2018-3646
currently, the script tries to use the wrong kernel image on Arch if an
alternative kernel (hardened, zen, or lts) is in use. Fortunately, all
the Arch kernel packages place a symlink to the kernel image as /usr/lib/modules/$(uname -r)/vmlinuz, so simply removing the guess for Arch fixes the issue.
Missing kernel information can cause all sorts of false positives or
negatives. This is worth at least a warning, and repeating immediately
following the status.
As it's seen in unmap_kernel_at_el0 (both the function definition
and its usage in arm64_features[]) from arch/arm64/kernel/cpufeature.c
the kernel reports this string:
CPU features: detected: Kernel page table isolation (KPTI)
or (before commit e0f6429dc1c0 ("arm64: cpufeature: Remove redundant "feature"
in reports")):
CPU features: detected feature: Kernel page table isolation (KPTI)
if KPTI is enabled on the system.
So on let's adjust check_variant3_linux() to make it grep these
strings if executed on an aarch64 platform.
Tested on a Cavium ThunderX2 machine.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Use platomav's MCExtractor DB as the reference to decide whether our CPU microcode is the latest or not.
We have a builtin version of the DB in the script, but an updated version can be fetched and stored locally with --update-mcedb
* Add another location of Arch Linux ARM kernel
* Fix detection of CVE-2018-3615
We change the value of variantl1tf in the line directly before so its
value will never be "immune". Instead we can directly use the value of
variantl1tf to initialize variantl1tf_sgx.
* Fix cases where a CPU ucode version is not found in $procfs/cpuinfo.
When running whithin a virtual machine, it seems like $procfs/cpuinfo doesn't contain
a 'microcode' line, which triggers a script runtime error.
Fall back to '0x0' in this case, as other part of the script seems to already this
as a default value anyway.
* Double quote to prevent globbing and word splitting.
Commit b48b2177b7 ("feat: Add Clear Linux Distro (#244)") broke kernel
detection for distros using that directory for other purposes than
storing the kernel image.
Example:
# pacman -Qo /lib/kernel
/usr/lib/kernel/ is owned by mkinitcpio 24-2
/usr/lib/kernel/ is owned by systemd 239.2-1
Signed-off-by: Laszlo Toth <laszlth@gmail.com>
When using this script on a large amount a machine (via clustershell or
instance) it can be easier to have a very short result on one line
showing only the vulnerabilities
The spectre-meltdown-checker.sh file is missing licensing information.
The SPDX identifier is a legally binding shorthand, which can be
used instead of the full boiler plate text.
* Listed the required volumes in the Dockerfile.
* Added docker-compose.yml for convenience as users won't need to manually
specify volumes and stuff when running through docker-compose.
Adjusted README.md to reflect this change.
This patch adds 0x43 check for cavium implementor id in function
parse_cpu_details. Also adds that Cavium Soc is not vulnerable to variant 3/3a
Signed-off-by: Manish Jaggi <manish.jagg@cavium.com>
* variant4 from common.c::cpu_no_spec_store_bypass
Variant 4 - Add function to 'whitelist' the hand-full of CPUs unaffected by speculative store bypass.
This would allow improved determination of variant 4 status ( #189 ) of immune CPUs while waiting for the 4.17/stable patches to be backported to distro kernels.
Source of cpu list : https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/common.c#n945)
Modeled after is_cpu_specex_free()
* amd families fix
amd families are reported by parse_cpu_details() in decimal
* remove duplicates
Only list processors which speculate and are immune to variant 4.
Avoids duplication with non-speculating CPUs listed in is_cpu_specex_free()
* ibrs can't be enabled on no ibrs cpu
If the cpu is identified, and does not support SPEC_CTRL or IBRS, then ibrs can't be enabled, even if supported by the kernel.
Instead of reporting IBRS enabled and active UNKNOWN, report IBRS enabled and active NO.
This adds a check before loading the cpuid and msr modules under linux, ensuring they are not unloaded in exit_cleanup() if they were initially present.
This test worked for some early versions of the retpoline
implementation in vanilla kernels, but the corresponding
flag has been removed from /proc/cpuinfo in latest kernels.
The full information is available in /sys instead, which
was already implemented in the script.
Based on a kernel patch that has been merged to Linus' tree.
Some of the detections we did by grepping the model name
will probably no longer be needed.
Implement detection of mitigation for Variant 1 that is
being pushed on vanilla kernel.
Current name of the patch:
"spectre variant1 mitigations for tip/x86/pti" (v6)
Also detect some distros that already backported this
patch without modifying the vulnerabilities sysfs hierarchy.
This detection is more reliable than the LFENCE one, trust
it and skip the LFENCE heuristic if a match is found.
The values used should be the ones that come from cpuinfo instead of
the test values. The following line will print the last tuple tested
instead of the actual values of the CPU.
Line 689: _debug "is_ucode_blacklisted: no ($model/$stepping/$ucode)"
Some Intel microcodes are known to cause instabilities
such as random reboots. Intel advises to revert to a
previous version if a newer one that fixes those issues
is not available. Detect such known bad microcodes.
In batch mode, $echo_cmd was not initialized early
enough, and caused this error:
./spectre-meltdown-checker.sh: 899: ./spectre-meltdown-checker.sh: -ne: not found
Fix it by initing echo_cmd unconditionally at the start
Move all the CPU checks to their own section,
for clarity. We now check for IBRS, IBPB, STIBP,
RDCL_NO and IBRS_ALL. We also show whether the
system CPU is vulnerable to the three variants,
regardless of the fact that mitigations are in
place or not, which is determined in each vuln-
specific section.
For variant3 under AMD, the debugfs vulnerabilities hierarchy
flags the system as Vulnerable, which is wrong. Trust our own
is_cpu_vulnerable() func in that case
When kernel is not compiled with retpoline option, doesn't
have the sysfs vulnerability hierarchy and our heuristic to
detect a retpoline-aware compiler didn't match, change result
for retpoline-aware compiler detection from UNKNOWN to NO.
When CONFIG_RETPOLINE is not set, a retpoline-aware compiler
won't produce different asm than a standard one anyway.
Before, when the /sys kernel vulnerability interface
was available, we would bypass all our tests and just
print the output of the vulnerability interface. Now,
we still rely on it when available, but we run our
checks anyway, except for variant 1 where the current
method of mitigation detection doesn't add much value
to the bare /sys check
In addition to IBRS (and microcode support), IBPB
must be used to mitigate variant 2, if retpoline
support is not available. The vulnerability status
of a system will be defined as "non vulnerable"
if IBRS and IBPB are both enabled, or if IBPB
is enabled with a value of 2 for RedHat kernels,
see https://access.redhat.com/articles/3311301
In offline mode, in the worst case where an invalid
config file is given, and we have no vmlinux image
nor System.map, the script was reporting Variant 2
and Variant 3 as vulnerable in the global status.
Replace this by a proper pair of UNKNOWNs
To avoid false negatives when looking for a message
in dmesg, we were previously also grepping in known
on-disk archives of dmesg (dmesg.log, kern.log).
This in turn caused false positives because we have no
guarantee that we're grepping the dmesg of the current
running kernel. Hence we now only look in the live
`dmesg`, detect if it has been truncated, and report
it to the user.
* Add special CoreOS compatibility mode
* CoreOS: refuse --coreos if we're not under CoreOS
* CoreOS: warn if launched without --coreos option
* is_coreos: make stderr silent
* CoreOS: tiny adjustments
* correct is_cpu_vulnerable() comment
As far as I can tell, the function and usage are correct for the comment
to be inverted.
Add a clarifying note as to why the value choice makes sense.
* exit on invalid varient
If this happens, it's a bug in the script. None of the calling code
checks for status 255, so don't let a scripting bug cause a false
negative.
* no need to set vulnerable CPUs
According to comment above this code:
'by default, everything is vulnerable, we work in a "whitelist" logic here.'
We were saying unknown instead of vulnerable when the count of lfence opcodes was low
This was not impacting batch mode or the final decision, just the human-readable output of the script.
With --batch json there must not be any other output on stdout, so redirect warnings to stderr will show the warning on the console and only the json output is on stdout.
In case of a busy or misconfigured server, kernel message buffer loop
can be filled with messages broadcasted later than boot time. So dmesg
command wont return boot time messages.
Grepping /var/log/dmesg fixes it and this log file location semms pretty
standard across many common distros
Rewrite the way the output is processed:
- Define verbosity level (currently warn, info (default) & verbose)
- Add a batch mode, for simple machine parsing
- Isolate file check to different elif (allowing to add more)
- Do the PTI debugfs check first (faster and supposed to be dynamic)
- If pti_enable is 0, don't trust dmesg (supposed to be dynamic)
Small issue with the USER environment variable:
$ echo $USER
thib
$ sudo sh -c 'echo $USER'
thib
$ sudo -i sh -c 'echo $USER'
root
Rather than recommending users to use sudo --login / -i, use the (very
widespread/portable) id program to retrieve the effective user ID
instead and don't change the recommendation.
$ id -u
1000
$ sudo id -u
0
$ sudo -i id -u
0
- [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.
A simple shell script to tell if your Linux installation is vulnerable
against the 3 "speculative execution" CVEs:
A shell script to assess your system's resilience against the several [transient execution](https://en.wikipedia.org/wiki/Transient_execution_CPU_vulnerability) CVEs that were published since early 2018, and give you guidance as to how to mitigate them.
Mitigation 1: new opcode via microcode update that should be used by up to date compilers to protect the BTB (by flushing indirect branch predictors)
Mitigation 2: introducing "retpoline" into compilers, and recompile software/OS with it
Performance impact of the mitigation: high for mitigation 1, medium for mitigation 2, depending on your CPU
Supported operating systems:
- Linux (all versions, flavors and distros)
- FreeBSD, NetBSD, DragonFlyBSD and derivatives (others BSDs are [not supported](FAQ.md#which-bsd-oses-are-supported))
CVE-2017-5754: rogue data cache load (Meltdown)
Impact: Kernel
Mitigation: updated kernel (with PTI/KPTI patches), updating the kernel is enough
Performance impact of the mitigation: low to medium
For Linux systems, the tool will detect mitigations, including backported non-vanilla patches, regardless of the advertised kernel version number and the distribution (such as Debian, Ubuntu, CentOS, RHEL, Fedora, openSUSE, Arch, ...), it also works if you've compiled your own kernel. More information [here](FAQ.md#how-does-this-script-work).
Example of the output of the script:
Other operating systems such as MacOS, Windows, ESXi, etc. [will most likely never be supported](FAQ.md#why-is-my-os-not-supported).
Spectre and Meltdown mitigation detection tool v0.01
Supported architectures:
-`x86` (32 bits)
-`amd64`/`x86_64` (64 bits)
-`ARM` and `ARM64`
- other architectures will work, but mitigations (if they exist) might not always be detected
- Mitigation 1: new opcode via microcode update that should be used by up to date compilers to protect the BTB (by flushing indirect branch predictors)
- Mitigation 2: introducing "retpoline" into compilers, and recompile software/OS with it
- Performance impact of the mitigation: high for mitigation 1, medium for mitigation 2, depending on your CPU
**CVE-2017-5754** rogue data cache load (Meltdown)
- Impact: Kernel
- Mitigation: updated kernel (with PTI/KPTI patches), updating the kernel is enough
- Performance impact of the mitigation: low to medium
**CVE-2018-3640** rogue system register read (Variant 3a)
- Impact: TBC
- Mitigation: microcode update only
- Performance impact of the mitigation: negligible
**CVE-2018-3639** speculative store bypass (Variant 4)
- Impact: software using JIT (no known exploitation against kernel)
- Mitigation: microcode update + kernel update making possible for affected software to protect itself
- Performance impact of the mitigation: low to medium
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.