diff mbox series

[v1,1/2] PCI/sysfs: Change read permissions for VPD attributes

Message ID f93e6b2393301df6ac960ef6891b1b2812da67f3.1731005223.git.leonro@nvidia.com (mailing list archive)
State New
Headers show
Series Fix read permissions for VPD attributes | expand

Commit Message

Leon Romanovsky Nov. 7, 2024, 6:56 p.m. UTC
From: Leon Romanovsky <leonro@nvidia.com>

The Vital Product Data (VPD) attribute is not readable by regular
user without root permissions. Such restriction is not really needed
for many devices in the world, as data presented in that VPD is not
sensitive and access to the HW is safe and tested.

This change aligns the permissions of the VPD attribute to be accessible
for read by all users, while write being restricted to root only.

For the driver, there is a need to opt-in in order to allow this
functionality.

Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
 drivers/pci/vpd.c   | 9 ++++++++-
 include/linux/pci.h | 7 ++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index e4300f5f304f..7c70930abaa0 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -156,6 +156,7 @@  static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
 			    void *arg, bool check_size)
 {
 	struct pci_vpd *vpd = &dev->vpd;
+	struct pci_driver *drv;
 	unsigned int max_len;
 	int ret = 0;
 	loff_t end = pos + count;
@@ -167,6 +168,12 @@  static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
 	if (pos < 0)
 		return -EINVAL;
 
+	if (!capable(CAP_SYS_ADMIN)) {
+		drv = to_pci_driver(dev->dev.driver);
+		if (!drv || !drv->downgrade_vpd_read)
+			return -EPERM;
+	}
+
 	max_len = check_size ? vpd->len : PCI_VPD_MAX_SIZE;
 
 	if (pos >= max_len)
@@ -317,7 +324,7 @@  static ssize_t vpd_write(struct file *filp, struct kobject *kobj,
 
 	return ret;
 }
-static BIN_ATTR(vpd, 0600, vpd_read, vpd_write, 0);
+static BIN_ATTR_RW(vpd, 0);
 
 static struct bin_attribute *vpd_attrs[] = {
 	&bin_attr_vpd,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 573b4c4c2be6..b8fed74e742e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -943,6 +943,10 @@  struct module;
  *		how to manage the DMA themselves and set this flag so that
  *		the IOMMU layer will allow them to setup and manage their
  *		own I/O address space.
+ * @downgrade_vpd_read: Device doesn't require root permissions from the users
+ *              to read VPD information. The driver doesn't expose any sensitive
+ *              information through that interface and safe to be accessed by
+ *              unprivileged users.
  */
 struct pci_driver {
 	const char		*name;
@@ -960,7 +964,8 @@  struct pci_driver {
 	const struct attribute_group **dev_groups;
 	struct device_driver	driver;
 	struct pci_dynids	dynids;
-	bool driver_managed_dma;
+	bool driver_managed_dma : 1;
+	bool downgrade_vpd_read : 1;
 };
 
 #define to_pci_driver(__drv)	\