lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230214132157.472753-1-suweifeng1@huawei.com>
Date:   Tue, 14 Feb 2023 21:21:57 +0800
From:   Su Weifeng <suweifeng1@...wei.com>
To:     <gregkh@...uxfoundation.org>, <mst@...hat.com>
CC:     <linux-kernel@...r.kernel.org>, <shikemeng@...wei.com>,
        <liuzhiqiang26@...wei.com>, <linfeilong@...wei.com>,
        <zhanghongtao22@...wei.com>, Weifeng Su <suweifeng1@...wei.com>
Subject: [PATCH] uio:uio_pci_generic:Don't clear master bit when the process does not exit

From: Weifeng Su <suweifeng1@...wei.com>

The /dev/uioX device is used by multiple processes. The current behavior
is to clear the master bit when a process exits. This affects other
processes that use the device, resulting in command suspension and
timeout. This behavior cannot be sensed by the process itself.
The solution is to add the reference counting. The reference count is
self-incremented and self-decremented each time when the device open and
close. The master bit is cleared only when the last process exited.

Signed-off-by: Weifeng Su <suweifeng1@...wei.com>
---
 drivers/uio/uio_pci_generic.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
index e03f9b532..d36d3e08e 100644
--- a/drivers/uio/uio_pci_generic.c
+++ b/drivers/uio/uio_pci_generic.c
@@ -31,6 +31,7 @@
 struct uio_pci_generic_dev {
 	struct uio_info info;
 	struct pci_dev *pdev;
+	refcount_t  dev_refc;
 };
 
 static inline struct uio_pci_generic_dev *
@@ -39,10 +40,22 @@ to_uio_pci_generic_dev(struct uio_info *info)
 	return container_of(info, struct uio_pci_generic_dev, info);
 }
 
+static int open(struct uio_info *info, struct inode *inode)
+{
+	struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
+
+	if (gdev)
+		refcount_inc(&gdev->dev_refc);
+	return 0;
+}
+
 static int release(struct uio_info *info, struct inode *inode)
 {
 	struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
 
+	if (gdev && refcount_dec_not_one(&gdev->dev_refc))
+		return 0;
+
 	/*
 	 * This driver is insecure when used with devices doing DMA, but some
 	 * people (mis)use it with such devices.
@@ -51,7 +64,8 @@ static int release(struct uio_info *info, struct inode *inode)
 	 * Note that there's a non-zero chance doing this will wedge the device
 	 * at least until reset.
 	 */
-	pci_clear_master(gdev->pdev);
+	if (refcount_read(&gdev->dev_refc) == 1)
+		pci_clear_master(gdev->pdev);
 	return 0;
 }
 
@@ -93,7 +107,9 @@ static int probe(struct pci_dev *pdev,
 	gdev->info.name = "uio_pci_generic";
 	gdev->info.version = DRIVER_VERSION;
 	gdev->info.release = release;
+	gdev->info.open = open;
 	gdev->pdev = pdev;
+	refcount_set(&gdev->dev_refc, 1);
 	if (pdev->irq && (pdev->irq != IRQ_NOTCONNECTED)) {
 		gdev->info.irq = pdev->irq;
 		gdev->info.irq_flags = IRQF_SHARED;
-- 
2.33.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ