[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] pci: fail device assignment if phantom functions cannot be assigned



commit cb4ecb3cc17b02c2814bc817efd05f3f3ba33d1e
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Tue Jan 30 14:28:01 2024 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jan 30 14:28:01 2024 +0100

    pci: fail device assignment if phantom functions cannot be assigned
    
    The current behavior is that no error is reported if (some) phantom 
functions
    fail to be assigned during device add or assignment, so the operation 
succeeds
    even if some phantom functions are not correctly setup.
    
    This can lead to devices possibly being successfully assigned to a domU 
while
    some of the device phantom functions are still assigned to dom0.  Even when 
the
    device is assigned domIO before being assigned to a domU phantom functions
    might fail to be assigned to domIO, and also fail to be assigned to the 
domU,
    leaving them assigned to dom0.
    
    Since the device can generate requests using the IDs of those phantom
    functions, given the scenario above a device in such state would be in 
control
    of a domU, but still capable of generating transactions that use a context 
ID
    targeting dom0 owned memory.
    
    Modify device assign in order to attempt to deassign the device if phantom
    functions failed to be assigned.
    
    Note that device addition is not modified in the same way, as in that case 
the
    device is assigned to a trusted domain, and hence partial assign can lead to
    device malfunction but not a security issue.
    
    This is XSA-449 / CVE-2023-46839
    
    Fixes: 4e9950dc1bd2 ('IOMMU: add phantom function support')
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/drivers/passthrough/pci.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 1439d1ef2b..47c0eee7bd 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -1488,11 +1488,10 @@ static int assign_device(struct domain *d, u16 seg, u8 
bus, u8 devfn, u32 flag)
 
     pdev->fault.count = 0;
 
-    if ( (rc = iommu_call(hd->platform_ops, assign_device, d, devfn,
-                          pci_to_dev(pdev), flag)) )
-        goto done;
+    rc = iommu_call(hd->platform_ops, assign_device, d, devfn, 
pci_to_dev(pdev),
+                    flag);
 
-    for ( ; pdev->phantom_stride; rc = 0 )
+    while ( pdev->phantom_stride && !rc )
     {
         devfn += pdev->phantom_stride;
         if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
@@ -1503,8 +1502,24 @@ static int assign_device(struct domain *d, u16 seg, u8 
bus, u8 devfn, u32 flag)
 
  done:
     if ( rc )
-        printk(XENLOG_G_WARNING "%pd: assign (%pp) failed (%d)\n",
-               d, &PCI_SBDF(seg, bus, devfn), rc);
+    {
+        printk(XENLOG_G_WARNING "%pd: assign %s(%pp) failed (%d)\n",
+               d, devfn != pdev->devfn ? "phantom function " : "",
+               &PCI_SBDF(seg, bus, devfn), rc);
+
+        if ( devfn != pdev->devfn && deassign_device(d, seg, bus, pdev->devfn) 
)
+        {
+            /*
+             * Device with phantom functions that failed to both assign and
+             * rollback.  Mark the device as broken and crash the target 
domain,
+             * as the state of the functions at this point is unknown and Xen
+             * has no way to assert consistent context assignment among them.
+             */
+            pdev->broken = true;
+            if ( !is_hardware_domain(d) && d != dom_io )
+                domain_crash(d);
+        }
+    }
     /* The device is assigned to dom_io so mark it as quarantined */
     else if ( d == dom_io )
         pdev->quarantine = true;
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.