[PATCH v2 1/6] PCI: Prevent overflow in proc_bus_pci_{read,write}()

From: Ziming Du

Date: Wed Jul 29 2026 - 23:05:09 EST


proc_bus_pci_read() and proc_bus_pci_write() receive the file position
as a 64-bit loff_t, but store it in 32-bit variables before validating
the configuration-space bounds.

In proc_bus_pci_read(), pos is an unsigned int, so an offset such as
0x100000000 is truncated to zero. The truncated value passes the bounds
check and causes the function to read from the beginning of PCI
configuration space instead of returning EOF.

In proc_bus_pci_write(), pos is an int, so an offset greater than
INT_MAX may become negative. The negative value bypasses the
pos >= size check and is then mixed with the unsigned nbytes value.
The bounds adjustment may consequently expand a small request into a
very large transfer, causing the write loop to use invalid negative
configuration offsets and run for an excessive amount of time.

Fix this by changing the type of pos to loff_t.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
Signed-off-by: Yongqiang Liu <liuyongqiang13@xxxxxxxxxx>
Signed-off-by: Ziming Du <duziming2@xxxxxxxxxx>
---
drivers/pci/proc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 71ad289fcb8e3..cad749924dd89 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -30,7 +30,7 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
{
struct pci_dev *dev = pde_data(file_inode(file));
- unsigned int pos = *ppos;
+ loff_t pos = *ppos;
unsigned int cnt, size;

/*
@@ -114,7 +114,7 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
{
struct inode *ino = file_inode(file);
struct pci_dev *dev = pde_data(ino);
- int pos = *ppos;
+ loff_t pos = *ppos;
int size = dev->cfg_size;
int cnt, ret;

--
2.43.0