On 10/06/19 19:20, Alejandro Jimenez wrote:
> The bits set in x86_spec_ctrl_mask are used to calculate the
> guest's value of SPEC_CTRL that is written to the MSR before
> VMENTRY, and control which mitigations the guest can enable.
> In the case of SSBD, unless the host has enabled SSBD always
> on mode (by passing "spec_store_bypass_disable=on" in the
> kernel parameters), the SSBD bit is not set in the mask and
> the guest can not properly enable the SSBD always on
> mitigation mode.
>
> This is confirmed by running the SSBD PoC on a guest using
> the SSBD always on mitigation mode (booted with kernel
> parameter "spec_store_bypass_disable=on"), and verifying
> that the guest is vulnerable unless the host is also using
> SSBD always on mode. In addition, the guest OS incorrectly
> reports the SSB vulnerability as mitigated.
>
> Always set the SSBD bit in x86_spec_ctrl_mask when the host
> CPU supports it, allowing the guest to use SSBD whether or
> not the host has chosen to enable the mitigation in any of
> its modes.
>
> Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez(a)oracle.com>
> Reviewed-by: Liam Merwick <liam.merwick(a)oracle.com>
> Cc: stable(a)vger.kernel.org
Reviewed-by: Paolo Bonzini <pbonzini(a)redhat.com>
> ---
> arch/x86/kernel/cpu/bugs.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index 03b4cc0..66ca906 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -836,6 +836,16 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
> }
>
> /*
> + * If SSBD is controlled by the SPEC_CTRL MSR, then set the proper
> + * bit in the mask to allow guests to use the mitigation even in the
> + * case where the host does not enable it.
> + */
> + if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
> + static_cpu_has(X86_FEATURE_AMD_SSBD)) {
> + x86_spec_ctrl_mask |= SPEC_CTRL_SSBD;
> + }
> +
> + /*
> * We have three CPU feature flags that are in play here:
> * - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible.
> * - X86_FEATURE_SSBD - CPU is able to turn off speculative store bypass
> @@ -852,7 +862,6 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
> x86_amd_ssb_disable();
> } else {
> x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
> - x86_spec_ctrl_mask |= SPEC_CTRL_SSBD;
> wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
> }
> }
>
The interrupt handler `dt282x_interrupt()` causes a null pointer
dereference for those supported boards that have no analog output
support. For these boards, `dev->write_subdev` will be `NULL` and
therefore the `s_ao` subdevice pointer variable will be `NULL`. In that
case, the following call near the end of the interrupt handler results
in a null pointer dereference:
comedi_handle_events(dev, s_ao);
Fix it by only calling the above function if `s_ao` is valid.
(There are other uses of `s_ao` by the interrupt handler that may or may
not be reached depending on values of hardware registers. Trust that
they are reliable for now.)
Note:
commit 4f6f009b204f ("staging: comedi: dt282x: use comedi_handle_events()")
propagates an earlier error from
commit f21c74fa4cfe ("staging: comedi: dt282x: use cfc_handle_events()").
Fixes: 4f6f009b204f ("staging: comedi: dt282x: use comedi_handle_events()")
Cc: <stable(a)vger.kernel.org> # v3.19+
Signed-off-by: Ian Abbott <abbotti(a)mev.co.uk>
---
Note: A similar patch will be required for stable v3.16.x, but that
calls cfc_handle_events() instead of comedi_handle_events().
---
drivers/staging/comedi/drivers/dt282x.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 3be927f1d3a9..e15e33ed94ae 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -557,7 +557,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
}
#endif
comedi_handle_events(dev, s);
- comedi_handle_events(dev, s_ao);
+ if (s_ao)
+ comedi_handle_events(dev, s_ao);
return IRQ_RETVAL(handled);
}
--
2.20.1
The interrupt handler `pci230_interrupt()` causes a null pointer
dereference for a PCI260 card. There is no analog output subdevice for
a PCI260. The `dev->write_subdev` subdevice pointer and therefore the
`s_ao` subdevice pointer variable will be `NULL` for a PCI260. The
following call near the end of the interrupt handler results in the null
pointer dereference for a PCI260:
comedi_handle_events(dev, s_ao);
Fix it by only calling the above function if `s_ao` is valid.
Note that the other uses of `s_ao` in the calls
`pci230_handle_ao_nofifo(dev, s_ao);` and `pci230_handle_ao_fifo(dev,
s_ao);` will never be reached for a PCI260, so they are safe.
Fixes: 39064f23284c ("staging: comedi: amplc_pci230: use comedi_handle_events()")
Cc: <stable(a)vger.kernel.org> # v3.19+
Signed-off-by: Ian Abbott <abbotti(a)mev.co.uk>
---
drivers/staging/comedi/drivers/amplc_pci230.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index 65f60c2b702a..f7e673121864 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -2330,7 +2330,8 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
devpriv->intr_running = false;
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- comedi_handle_events(dev, s_ao);
+ if (s_ao)
+ comedi_handle_events(dev, s_ao);
comedi_handle_events(dev, s_ai);
return IRQ_HANDLED;
--
2.20.1