From nobody Wed Feb 11 07:07:43 2026 Received: from mail-il1-f172.google.com (mail-il1-f172.google.com [209.85.166.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A20961DF963; Sat, 26 Apr 2025 21:28:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.166.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745702903; cv=none; b=NhuXlN7mwKCtzecaN50Gi5kwJ8JpvJobsH0kP3l/Dixi0di+LFWEeMs1emzUp2cRGHTGbZCGRtchHfGXaSfLfIryoEn9en6wtstrSY0PtdEMPLeVRLZZ9udO59UCzktVxiOC/WECUuNCqGfdQShS2vfEav0C6EYV94SN0U5GBpM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745702903; c=relaxed/simple; bh=KS6IxRQOo53L6l7MBOMdtjRUdNTRenmkZtpkH+eCvT4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DaIk3gUwfbax8N+z0Yupk8UXKIoh95crjPawjsyY2iBO6NTqggSnXFE6UAvJB7+Debs2pEtDiEVXzNV2H/QNLwfGkarlGvyrAgJG9qP3Ut5REbwvCd/THxtKtysZRf7skNWlp3UuIs9akdFw7Bn9E56UXSoptf7ezFc9g09Te8Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WmRvBFHS; arc=none smtp.client-ip=209.85.166.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WmRvBFHS" Received: by mail-il1-f172.google.com with SMTP id e9e14a558f8ab-3d589ed2b47so10012215ab.2; Sat, 26 Apr 2025 14:28:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1745702900; x=1746307700; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cYvI4jQPOlvT7mZsy2WDSn1H0pl95kjlr5q63pD49S8=; b=WmRvBFHSRun0WpXX8qc5BGkDk/kjLbTxWeVKVbjvxpOFw5I4nmrpW0QwmeXT4GXgBf RCUBLlyEZYx1j48ieV+TSMFXdtljOKahSnC3R0z0LHIQ2PP6ZiOxbS/RPXE3+N8gDrcx JXWAIxfpjE0JobGAKVIdz1ZaGlbvK0YW10pfyByg8ZebOiUEX6pngGIsfVSkyDs7EBMz lAXirkAXREZTasex+r7kYzosVREMdd8CSQzigxfYu0FvN3dC8t41TBr4A6Eg2LMlkHsA 9HfszZkkkD7a/y68k7ncLYQOkVx4rjy8GX9NjF0EgPRIhUp3S2pCp5li0CFaDmXvHgN/ iSow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745702900; x=1746307700; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cYvI4jQPOlvT7mZsy2WDSn1H0pl95kjlr5q63pD49S8=; b=cm1xeCJE6uqcgBvcAWBJUCO3YvA5rqe2u28aGkQCjeRSNQ4kVUIpP3zn5W5T6d0I76 PRq//lCHrS9uncg9GnlHOcdZdfgqkpDqZd75YCBsTMzW3kW7IxbZm8f3czFyG9WbE4Dg 0xH5E3NleIlaaFB3ZwEX+Me48c8TON/G4wY8sCJI+vkjXFSMUsfcyE+t3YRxhxS2AEyV Opxs0VoT9uITnpvxgJq7dyklJb1C1V1LxVGm1Po38YZWv0sub4Jz0j1JX5onwIZ+TcBy sWp+3ZOascpL9erXzzmtWzjl6TVQhP7yhdQ1kuYK6NP9nLXYztrUvqC9zGDMctwBImUi 81lQ== X-Forwarded-Encrypted: i=1; AJvYcCVbNYSolQMK7bSL1m7y1HuCkO0fK1JJBdtAVbmOe2FPl0iEG7tsaMtGKDcSm0ICud4si6LV1w==@vger.kernel.org, AJvYcCW9GbAKCv5b1x7tehVtaEfP1Qe80RZjLChHE0sQdMP6qLgPJfpW0WGgDiIqekfOSaEM1pamwflFq7rzq6E3@vger.kernel.org X-Gm-Message-State: AOJu0YwSjwiNbgyUJCjjhcpAslOJOxlUw6VPDMqIOsmty/WCPDjIaKaC dMmG0D9OmIUa/XFcSjjn/B4HkN4dUFwUCIi0tcuNCrRVyJcIYIfIi8VJZ3mh X-Gm-Gg: ASbGnctJisDfLeLCQY+kiuKQUZ3FByQLNG8C54QY+57hqwU3QwuSQkKHgk148ldLkeV J73MR0FLF0hr//JTEV8yeYyoexm3acBzszyW2+8AH2oX77Aon5MwV6ucH8Lh4iPB50evSX1XZa9 qIV2o+U9Vc4I/1c3RHkLf7PpiKd0Uh+FLiP34m+6B0bjc07Q4CbSoT3DNLOXZDoksQLQ0m9hpaD B1dH1S7xmPhuvnsnNsVzU7XRX75RgOMWRS7F4/iKAXpjPCpZf5Q9L/x3rIUzxHCcqjidFQzx1rf wWt+zgZnWzADNsB9zab0prKwQ4Znu589SnZut1ejRJrm3+zb/3D+1R6ILSbVDiqFd5EqxgtC6J9 1ZobsGnxoZGtBBVt+s5FKZJPCluSlyHBp/onb8vZ1izkvhdzu X-Google-Smtp-Source: AGHT+IECLxryZVKrPnvFtvzexD7loHDqTcwBsRIfhNKLF5nKIC/s1ftfJKlrS9cIQohTFPwQ8u9izA== X-Received: by 2002:a05:6e02:180f:b0:3d8:2023:d048 with SMTP id e9e14a558f8ab-3d93b615afemr73072015ab.22.1745702900572; Sat, 26 Apr 2025 14:28:20 -0700 (PDT) Received: from master.chath-253561.iommu-security-pg0.wisc.cloudlab.us (sm220u-10s10539.wisc.cloudlab.us. [128.105.146.46]) by smtp.gmail.com with ESMTPSA id 8926c6da1cb9f-4f824ba34c1sm1454482173.126.2025.04.26.14.28.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 26 Apr 2025 14:28:20 -0700 (PDT) From: Chathura Rajapaksha X-Google-Original-From: Chathura Rajapaksha To: kvm@vger.kernel.org Cc: Chathura Rajapaksha , William Wang , Alex Williamson , Paul Moore , Eric Paris , Xin Zeng , Yahui Cao , Giovanni Cabiddu , Bjorn Helgaas , Niklas Schnelle , Yunxiang Li , Dongdong Zhang , Kevin Tian , Avihai Horon , linux-kernel@vger.kernel.org, audit@vger.kernel.org Subject: [RFC PATCH 1/2] block accesses to unassigned PCI config regions Date: Sat, 26 Apr 2025 21:22:48 +0000 Message-Id: <20250426212253.40473-2-chath@bu.edu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250426212253.40473-1-chath@bu.edu> References: <20250426212253.40473-1-chath@bu.edu> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some PCIe devices trigger PCI bus errors when accesses are made to unassigned regions within their PCI configuration space. On certain platforms, this can lead to host system hangs or reboots. The current vfio-pci driver allows guests to access unassigned regions in the PCI configuration space. Therefore, when such a device is passed through to a guest, the guest can induce a host system hang or reboot through crafted configuration space accesses, posing a threat to system availability. This patch introduces support for blocking guest accesses to unassigned PCI configuration space, and the ability to bypass this access control for specific devices. The patch introduces three module parameters: block_pci_unassigned_write: Blocks write accesses to unassigned config space regions. block_pci_unassigned_read: Blocks read accesses to unassigned config space regions. uaccess_allow_ids: Specifies the devices for which the above access control is bypassed. The value is a comma-separated list of device IDs in : format. Example usage: To block guest write accesses to unassigned config regions for all passed through devices except for the device with vendor ID 0x1234 and device ID 0x5678: block_pci_unassigned_write=3D1 uaccess_allow_ids=3D1234:5678 Co-developed by: William Wang Signed-off-by: William Wang Signed-off-by: Chathura Rajapaksha --- drivers/vfio/pci/vfio_pci_config.c | 122 ++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci= _config.c index 8f02f236b5b4..cb4d11aa5598 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -120,6 +120,106 @@ struct perm_bits { #define NO_WRITE 0 #define ALL_WRITE 0xFFFFFFFFU =20 +static bool block_pci_unassigned_write; +module_param(block_pci_unassigned_write, bool, 0644); +MODULE_PARM_DESC(block_pci_unassigned_write, + "Block write accesses to unassigned PCI config regions."); + +static bool block_pci_unassigned_read; +module_param(block_pci_unassigned_read, bool, 0644); +MODULE_PARM_DESC(block_pci_unassigned_read, + "Block read accesses from unassigned PCI config regions."); + +static char *uaccess_allow_ids; +module_param(uaccess_allow_ids, charp, 0444); +MODULE_PARM_DESC(uaccess_allow_ids, "PCI IDs to allow access to unassigned= PCI config regions, format is \"vendor:device\" and multiple comma separat= ed entries can be specified"); + +static LIST_HEAD(allowed_device_ids); +static DEFINE_SPINLOCK(device_ids_lock); + +struct uaccess_device_id { + struct list_head slot_list; + unsigned short vendor; + unsigned short device; +}; + +static void pci_uaccess_add_device(struct uaccess_device_id *new, + int vendor, int device) +{ + struct uaccess_device_id *pci_dev_id; + unsigned long flags; + int found =3D 0; + + spin_lock_irqsave(&device_ids_lock, flags); + + list_for_each_entry(pci_dev_id, &allowed_device_ids, slot_list) { + if (pci_dev_id->vendor =3D=3D vendor && + pci_dev_id->device =3D=3D device) { + found =3D 1; + break; + } + } + + if (!found) { + new->vendor =3D vendor; + new->device =3D device; + list_add_tail(&new->slot_list, &allowed_device_ids); + } + + spin_unlock_irqrestore(&device_ids_lock, flags); + + if (found) + kfree(new); +} + +static bool pci_uaccess_lookup(struct pci_dev *dev) +{ + struct uaccess_device_id *pdev_id; + unsigned long flags; + bool found =3D false; + + spin_lock_irqsave(&device_ids_lock, flags); + list_for_each_entry(pdev_id, &allowed_device_ids, slot_list) { + if (pdev_id->vendor =3D=3D dev->vendor && + pdev_id->device =3D=3D dev->device) { + found =3D true; + break; + } + } + spin_unlock_irqrestore(&device_ids_lock, flags); + + return found; +} + +static int __init pci_uaccess_init(void) +{ + char *p, *id; + int fields; + int vendor, device; + struct uaccess_device_id *pci_dev_id; + + /* add ids specified in the module parameter */ + p =3D uaccess_allow_ids; + while ((id =3D strsep(&p, ","))) { + if (!strlen(id)) + continue; + + fields =3D sscanf(id, "%x:%x", &vendor, &device); + + if (fields !=3D 2) { + pr_warn("Invalid id string \"%s\"\n", id); + continue; + } + + pci_dev_id =3D kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); + if (!pci_dev_id) + return -ENOMEM; + + pci_uaccess_add_device(pci_dev_id, vendor, device); + } + return 0; +} + static int vfio_user_config_read(struct pci_dev *pdev, int offset, __le32 *val, int count) { @@ -335,6 +435,18 @@ static struct perm_bits unassigned_perms =3D { .writefn =3D vfio_raw_config_write }; =20 +/* + * Read/write access to PCI unassigned config regions can be blocked + * using the block_pci_unassigned_read and block_pci_unassigned_write + * module parameters. The uaccess_allow_ids module parameter can be used + * to whitelist devices (i.e., bypass the block) when either of the + * above parameters is specified. + */ +static struct perm_bits block_unassigned_perms =3D { + .readfn =3D NULL, + .writefn =3D NULL +}; + static struct perm_bits virt_perms =3D { .readfn =3D vfio_virt_config_read, .writefn =3D vfio_virt_config_write @@ -1108,6 +1220,9 @@ int __init vfio_pci_init_perm_bits(void) ecap_perms[PCI_EXT_CAP_ID_VNDR].writefn =3D vfio_raw_config_write; ecap_perms[PCI_EXT_CAP_ID_DVSEC].writefn =3D vfio_raw_config_write; =20 + /* Device list allowed to access unassigned PCI regions */ + ret |=3D pci_uaccess_init(); + if (ret) vfio_pci_uninit_perm_bits(); =20 @@ -1896,7 +2011,12 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_cor= e_device *vdev, char __user cap_id =3D vdev->pci_config_map[*ppos]; =20 if (cap_id =3D=3D PCI_CAP_ID_INVALID) { - perm =3D &unassigned_perms; + if (((iswrite && block_pci_unassigned_write) || + (!iswrite && block_pci_unassigned_read)) && + !pci_uaccess_lookup(pdev)) + perm =3D &block_unassigned_perms; + else + perm =3D &unassigned_perms; cap_start =3D *ppos; } else if (cap_id =3D=3D PCI_CAP_ID_INVALID_VIRT) { perm =3D &virt_perms; --=20 2.34.1 From nobody Wed Feb 11 07:07:43 2026 Received: from mail-il1-f169.google.com (mail-il1-f169.google.com [209.85.166.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 051D21F5619; Sat, 26 Apr 2025 21:28:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.166.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745702924; cv=none; b=ZxsMThBlx+NzUk6ApfenVs2TRgMZM9W4Wov0cpYAIhDFqBpeuLoo8VPkWBTFnJ0dGwyeV6CGwMqBBKbt4Z/R6ZtijoTnLFQ1mT2hw+7/FpbqY8P5xv+EUaYtHMs0DJ3bSP+/H+W6oRyo5s5xvRhC9i3S1l39pAOq4hbuz4sbus0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745702924; c=relaxed/simple; bh=4qDv12GpymzV9cqm+5wc+FH3p/oXtI26viWEferrXSk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aY5DEDVadHqnRcNedPTS8sj7sG/FAjc4uTq9JQiJgOG77TAgx7VAtGrP25QcJpntJLEf1/hRIQ8cVA0204JMirntkwwH3YOZimngivo+bW4PeBRO4s7XKp1kBq54WfhkW7QYK/KuQ1KceTcz/jhzuHVhnxxjTiKMguXFDRSWibc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=C1KLpmg9; arc=none smtp.client-ip=209.85.166.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="C1KLpmg9" Received: by mail-il1-f169.google.com with SMTP id e9e14a558f8ab-3d813c1c39eso32089405ab.0; Sat, 26 Apr 2025 14:28:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1745702922; x=1746307722; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=in3Jc9pC1jNw19VgvSAZdkrPc3LvG10mRUdoc1WL8qI=; b=C1KLpmg9kXxweCLjSFkM0u7RuqaZ+IO+NSl/DmdWrNlYXU53kp6lxlmhP2CJSQHbi2 FpbTnBTpHC1k5xUxJkvoC7h1R0akrkLTkFgVNnFs2HgL0sFQNNayxXbJx7schJAHCarE XtmJmPaWsheEKXasasMog4AXWPljE8ypTIQNcU7qAUZbde1a43PVJ3TUPFIpHhAWqwRb 9QMF5c3r3Q3XCc4YvUoqCZFoDSzpf83iNlQyxuYcOZ3VRf0OraEgVx8RX5wwHjXhvNVg 0wDHCGHuZXwh3HHKt9tqsuBfq4ji7pnSef5jzfZXI+3YXHNqBj3qIDcZCHH21jzz8BAc 5MOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745702922; x=1746307722; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=in3Jc9pC1jNw19VgvSAZdkrPc3LvG10mRUdoc1WL8qI=; b=QyYX8rGCJTRz/LZZVzzZlCWgZhGHntJbR4Pn+HL1kWbJ1smlRJBDTNOotzRm5tOliO DiyTF+7MMYw0ZkV1VTOsiI3H6YVcyRu90taEXKBZRcRE8CpY6Yz29jI4r/R4eivDo36b WxVizVv+1aMPDwj+/irtX8h8NxIp5NwAaxwDlwwFi0yETb3yEgPPlwrnHRpH2ajwenqq 0RvIBgmsfVhbtpuNLQYNf7v6aq3aoFhi5F5FEKffn4u1kNSuBl0cjSu6LXjdkXlEjfan bbYRUIfZAMlWp+T3VfILfaEAzgQBpXz+DQfD8oSsMat5sKMDTa1zQjf90ovmP0wuGmw1 Ss4w== X-Forwarded-Encrypted: i=1; AJvYcCXdNnn+sN2+kk26T/z/AJKVr1yxfbywRkh04F1igA24rjSMPCXqpmN/gdYGxfeOb+aW8EGrMg==@vger.kernel.org, AJvYcCXwPbZQ3/DhClp5N+BZoYlK58Wek1ZOyVMHLzZHgJMVqaVRjxC/S8n8XwDBHkAdLB7qiTbfUcK5SdSe5bLG@vger.kernel.org X-Gm-Message-State: AOJu0YxPqgZ7rwxrzUuV27P6Eg0LdBBTHI9hA0+yjsEsDHdscZYU4EsM I5kxOIKypHRzBWiWs8TnjqBh49cguNyHC/OFQQ4Cwqk3AkmaRUq7po7ocC/s X-Gm-Gg: ASbGncuMwB6o4NwQVW3hLQMFstLDaVSY1OKtKnjwrDxbCNWyzil8Q9CwqiravURdKMQ BjoPQ0uZSj/JqXnu7oDhRJFH5ZDOfP3rpCyJaRTczjCInUeK4d/4xx7bIyNdvaNlJl5Vexaz/7L E6oa258U6bTMIGEh7csFBPFs4dJh7V9c6IhTx8QRijuK8dvyE0C3+8jtm5byNk+C7pkM29IEaTk u3Ub3w5PfFBlXqwzrr0q3YSXSpV6lw57lB39evMT3bE/ous/AhVpNUJ+TRzKNCG2fIngHyX18zu jjnt6Eq6X112BMRma/w1bu+F7eCquiCockcemnMpRJkrhoPKCZoq8yrV2MFmOymQrbLYsDTEnao /tlR0OJLabV2Gks8pz9yvEpwVhFkVNn9NP5Gqjta9ywGHlTPB X-Google-Smtp-Source: AGHT+IEBsK1Ip7zewga42fow2XKfAMr6aAeFPtYTe8aj7FYt3FMb9QHjB7XcLkdoWDnjTaV1NaN4+g== X-Received: by 2002:a05:6e02:12e8:b0:3d0:1fc4:edf0 with SMTP id e9e14a558f8ab-3d942e12849mr42783385ab.15.1745702921897; Sat, 26 Apr 2025 14:28:41 -0700 (PDT) Received: from master.chath-253561.iommu-security-pg0.wisc.cloudlab.us (sm220u-10s10539.wisc.cloudlab.us. [128.105.146.46]) by smtp.gmail.com with ESMTPSA id 8926c6da1cb9f-4f824ba34c1sm1454482173.126.2025.04.26.14.28.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 26 Apr 2025 14:28:41 -0700 (PDT) From: Chathura Rajapaksha X-Google-Original-From: Chathura Rajapaksha To: kvm@vger.kernel.org Cc: Chathura Rajapaksha , William Wang , Alex Williamson , Paul Moore , Eric Paris , Niklas Schnelle , Xin Zeng , Kevin Tian , Bjorn Helgaas , Yahui Cao , Yunxiang Li , Dongdong Zhang , Avihai Horon , linux-kernel@vger.kernel.org, audit@vger.kernel.org Subject: [RFC PATCH 2/2] audit accesses to unassigned PCI config regions Date: Sat, 26 Apr 2025 21:22:49 +0000 Message-Id: <20250426212253.40473-3-chath@bu.edu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250426212253.40473-1-chath@bu.edu> References: <20250426212253.40473-1-chath@bu.edu> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some PCIe devices trigger PCI bus errors when accesses are made to unassigned regions within their PCI configuration space. On certain platforms, this can lead to host system hangs or reboots. The current vfio-pci driver allows guests to access unassigned regions in the PCI configuration space. Therefore, when such a device is passed through to a guest, the guest can induce a host system hang or reboot through crafted configuration space accesses, posing a threat to system availability. This patch introduces auditing support for config space accesses to unassigned regions. When enabled, this logs such accesses for all passthrough devices.=20 This feature is controlled via a new Kconfig option: CONFIG_VFIO_PCI_UNASSIGNED_ACCESS_AUDIT A new audit event type, AUDIT_VFIO, has been introduced to support this, allowing administrators to monitor and investigate suspicious behavior by guests. Co-developed by: William Wang Signed-off-by: William Wang Signed-off-by: Chathura Rajapaksha --- drivers/vfio/pci/Kconfig | 12 ++++++++ drivers/vfio/pci/vfio_pci_config.c | 46 ++++++++++++++++++++++++++++-- include/uapi/linux/audit.h | 1 + 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig index c3bcb6911c53..7f9f16262b90 100644 --- a/drivers/vfio/pci/Kconfig +++ b/drivers/vfio/pci/Kconfig @@ -42,6 +42,18 @@ config VFIO_PCI_IGD and LPC bridge config space. =20 To enable Intel IGD assignment through vfio-pci, say Y. + +config VFIO_PCI_UNASSIGNED_ACCESS_AUDIT + bool "Audit accesses to unassigned PCI configuration regions" + depends on AUDIT && VFIO_PCI_CORE + help + Some PCIe devices are known to cause bus errors when accessing + unassigned PCI configuration space, potentially leading to host + system hangs on certain platforms. When enabled, this option + audits accesses to unassigned PCI configuration regions. + + If you don't know what to do here, say N. + endif =20 config VFIO_PCI_ZDEV_KVM diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci= _config.c index cb4d11aa5598..ddd10904d60f 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -25,6 +25,7 @@ #include #include #include +#include =20 #include "vfio_pci_priv.h" =20 @@ -1980,6 +1981,37 @@ static size_t vfio_pci_cap_remaining_dword(struct vf= io_pci_core_device *vdev, return i; } =20 +enum vfio_audit { + VFIO_AUDIT_READ, + VFIO_AUDIT_WRITE, + VFIO_AUDIT_MAX, +}; + +static const char * const vfio_audit_str[VFIO_AUDIT_MAX] =3D { + [VFIO_AUDIT_READ] =3D "READ", + [VFIO_AUDIT_WRITE] =3D "WRITE", +}; + +static void vfio_audit_access(const struct pci_dev *pdev, + size_t count, loff_t *ppos, bool blocked, unsigned int op) +{ + struct audit_buffer *ab; + + if (WARN_ON_ONCE(op >=3D VFIO_AUDIT_MAX)) + return; + if (audit_enabled =3D=3D AUDIT_OFF) + return; + ab =3D audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_VFIO); + if (unlikely(!ab)) + return; + audit_log_format(ab, + "device=3D%04x:%02x:%02x.%d access=3D%s offset=3D0x%llx size=3D%ld blo= cked=3D%u\n", + pci_domain_nr(pdev->bus), pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + vfio_audit_str[op], *ppos, count, blocked); + audit_log_end(ab); +} + static ssize_t vfio_config_do_rw(struct vfio_pci_core_device *vdev, char _= _user *buf, size_t count, loff_t *ppos, bool iswrite) { @@ -1989,6 +2021,7 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_core= _device *vdev, char __user int cap_start =3D 0, offset; u8 cap_id; ssize_t ret; + bool blocked; =20 if (*ppos < 0 || *ppos >=3D pdev->cfg_size || *ppos + count > pdev->cfg_size) @@ -2011,13 +2044,22 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_co= re_device *vdev, char __user cap_id =3D vdev->pci_config_map[*ppos]; =20 if (cap_id =3D=3D PCI_CAP_ID_INVALID) { - if (((iswrite && block_pci_unassigned_write) || + blocked =3D (((iswrite && block_pci_unassigned_write) || (!iswrite && block_pci_unassigned_read)) && - !pci_uaccess_lookup(pdev)) + !pci_uaccess_lookup(pdev)); + if (blocked) perm =3D &block_unassigned_perms; else perm =3D &unassigned_perms; cap_start =3D *ppos; + if (IS_ENABLED(CONFIG_VFIO_PCI_UNASSIGNED_ACCESS_AUDIT)) { + if (iswrite) + vfio_audit_access(pdev, count, ppos, blocked, + VFIO_AUDIT_WRITE); + else + vfio_audit_access(pdev, count, ppos, blocked, + VFIO_AUDIT_READ); + } } else if (cap_id =3D=3D PCI_CAP_ID_INVALID_VIRT) { perm =3D &virt_perms; cap_start =3D *ppos; diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 9a4ecc9f6dc5..c0aace7384f3 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -122,6 +122,7 @@ #define AUDIT_OPENAT2 1337 /* Record showing openat2 how args */ #define AUDIT_DM_CTRL 1338 /* Device Mapper target control */ #define AUDIT_DM_EVENT 1339 /* Device Mapper events */ +#define AUDIT_VFIO 1340 /* VFIO events */ =20 #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ --=20 2.34.1