]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
PCI: switchtec: Fix Spectre v1 vulnerability
authorKrzysztof Wilczyński <kw@linux.com>
Sat, 20 Feb 2021 06:28:37 +0000 (06:28 +0000)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 23 Mar 2021 18:49:59 +0000 (13:49 -0500)
The "partition" member of the struct switchtec_ioctl_pff_port can be
indirectly controlled from user-space through an IOCTL that the device
driver provides enabling conversion between a PCI Function Framework (PFF)
number and Switchtec logical port ID and partition number, thus allowing
for command-line tooling [1] interact with the device from user-space.

This can lead to potential exploitation of the Spectre variant 1 [2]
vulnerability since the value of the partition is then used directly as an
index to mmio_part_cfg_all[] of the struct switchtec_dev to retrieve
configuration from Switchtec for a specific partition number.

Fix this by sanitizing the value coming from user-space through the
available IOCTL before it's then used as an index to mmio_part_cfg_all[].

This issue was detected with the help of Smatch:

  drivers/pci/switch/switchtec.c:1118 ioctl_port_to_pff() warn:
  potential spectre issue 'stdev->mmio_part_cfg_all' [r] (local cap)

Notice that given that speculation windows are large, the policy is to kill
the speculation on the first load and not worry if it can be completed with
a dependent load/store [3].

Related commit 46feb6b495f7 ("switchtec: Fix Spectre v1 vulnerability").

[1] https://github.com/Microsemi/switchtec-user/blob/master/lib/platform/linux.c
[2] https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/spectre.html
[3] https://lore.kernel.org/lkml/CAPcyv4gLKYiCtXsKFX2FY+rW93aRtQt9zB8hU1hMsj770m8gxQ@mail.gmail.com/

Link: https://lore.kernel.org/r/20210220062837.1683159-1-kw@linux.com
Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
drivers/pci/switch/switchtec.c

index ba52459928f7fd796b1d389040a3f8b99a13dc26..bb6957101fc05bf20e8b27cc82778d2e52f272f0 100644 (file)
@@ -1112,12 +1112,15 @@ static int ioctl_port_to_pff(struct switchtec_dev *stdev,
        if (copy_from_user(&p, up, sizeof(p)))
                return -EFAULT;
 
-       if (p.partition == SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX)
+       if (p.partition == SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX) {
                pcfg = stdev->mmio_part_cfg;
-       else if (p.partition < stdev->partition_count)
+       } else if (p.partition < stdev->partition_count) {
+               p.partition = array_index_nospec(p.partition,
+                                                stdev->partition_count);
                pcfg = &stdev->mmio_part_cfg_all[p.partition];
-       else
+       } else {
                return -EINVAL;
+       }
 
        switch (p.port) {
        case 0: