speed47 / spectre-meltdown-checker

Reptar, Downfall, Zenbleed, ZombieLoad, RIDL, Fallout, Foreshadow, Spectre, Meltdown vulnerability/mitigation checker for Linux & BSD
3.87k stars 476 forks source link

False positives inside Xen (PVH) domU #343

Open marmarek opened 4 years ago

marmarek commented 4 years ago

When running in Xen with SMT disabled (smt=0 Xen boot option), multiple points are still reported as vulnerable with "Your microcode and kernel are both up to date for this mitigation, but your must disable SMT (Hyper-Threading) for a complete mitigation". The same applies when SMT is disabled in BIOS.

This is false positive, as in both cases Xen will never schedule anything on a secondary hyper-thread, so cross-hyper-threads attacks are not possible. I see the current SMT detection is done based on /proc/cpuinfo. Here is how it looks in this case:

grep '^proc\|^core\|^siblings\|^cpu cores' `/proc/cpuinfo`
processor   : 0
siblings    : 2
core id     : 0
cpu cores   : 2
processor   : 1
siblings    : 2
core id     : 1
cpu cores   : 2

In dom0 it looks the same (in this case both dom0 and domU has two (all) vCPUs).

As you can see, each has a distinct core id. For comparison, here is how it looks with smt=on in (PV) dom0 and also dom0 having all (4 this time) vCPUs:

$ grep '^proc\|^core\|^siblings\|^cpu cores' /proc/cpuinfo 
processor   : 0
siblings    : 4
core id     : 0
cpu cores   : 2
processor   : 1
siblings    : 4
core id     : 0
cpu cores   : 2
processor   : 2
siblings    : 4
core id     : 1
cpu cores   : 2
processor   : 3
siblings    : 4
core id     : 1
cpu cores   : 2

Here, you see each core id value appears twice.

Unfortunately, if I take a domU with 2 or 4 vCPUs, I get distinct core id each time, for example:

$ grep '^proc\|^core\|^siblings\|^cpu cores' /proc/cpuinfo 
processor   : 0
siblings    : 4
core id     : 0
cpu cores   : 4
processor   : 1
siblings    : 4
core id     : 1
cpu cores   : 4
processor   : 2
siblings    : 4
core id     : 2
cpu cores   : 4
processor   : 3
siblings    : 4
core id     : 3
cpu cores   : 4

This is because (I think) /proc/cpuinfo is based mostly on ACPI, which is constructed by Xen toolstack, with only some info taken from the real hardware. I don't know if there is any reliable method of detecting from within domU whether SMT is enabled in Xen or not.

I've also taken look at /sys/devices/system/cpu/smt/control and /sys/devices/system/cpu/smt/active:

real SMT state domain .../control .../active
off dom0 (PV) on 0
off domU (PVH) on 0
off domU (PV) on 1
on dom0 (PV) on 1
on domU (PVH) on 0
on domU (PV) on 1

As you can see, PVH always sees SMT as disabled. And PV domU always sees it enabled. BTW the script search for SMT (disabled|mitigated) in dmesg, which doesn't always match those sysfs entries. Especially here even if active is 0, there is no such line in dmesg.

Until some method is found, I propose modifying is_cpu_smt_enabled to return 2 (unknown) if Xen (PVH) domU is detected.

speed47 commented 4 years ago

Hello @marmarek,

First, sorry for the delay, and thanks for this detailed bug report! This is quite uncommon and is extremely valuable.

On a side note, there have already been a couple bug reports on Xen, and I always have a hard way getting complete information as I don't have it running anywhere. I even took a couple hours some time ago to try to build some Xen-enabled test OS on a spare hard drive I have, but couldn't get to anything satisfactory in the timeframe I gave myself to do it.

Interestingly enough, QubeOS has been on my "should look at this one day" list for quite some time, and your bug report just made me discover it's powered by Xen! I gave it a quick try last weekend, and I have to say, the work you guys have done on the user experience in quite impressive. Everything looks easy to use, and you're doing a great job hiding all the complexity. I'll probably give it a more lengthy try...

Now, back at our Xen issues with detecting SMT, thanks for the "truth table" you've made, it seems indeed complicated to properly detect the SMT status. There might be a way, but while we find it, your proposition looks reasonable. I'll look into it ASAP!

ckujau commented 3 years ago

The script appears to have more than one method to check if SMT is enabled:

To make matters even more complicated (hah!), the system was booted with nosmt and dmesg correctly states: SMT: disabled. But spectre-meltdown-checker.sh doesn't check for that and thinks:

* Hyper-Threading (SMT) is enabled:  NO 
* Mitigated according to the /sys interface:  NO  (Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown)
* SMT is either mitigated or disabled:  NO 
[...]

But simply changing the grep pattern to SMT(:|) (disabled|mitigated) did not help, maybe I looked at the wrong routine just now :-\