From khali@linux-fr.org Sat Apr 7 08:22:18 2007 From: Jean Delvare Date: Sat, 7 Apr 2007 17:21:28 +0200 Subject: PCI: Require vendor and device for new_id To: Grant Grundler Cc: Greg Kroah-Hartman , linux-pci@atrey.karlin.mff.cuni.cz Message-ID: <20070407172128.4dda49c7.khali@linux-fr.org> Currently, there is no minimum number of fields required when adding a new device ID to a PCI driver through the new_id sysfs file. It is possible to add a new ID with only the vendor ID set, causing the driver to attempt to attach to all PCI devices from that vendor. This has been reported to happen accidentally: http://lists.lm-sensors.org/pipermail/lm-sensors/2007-March/019366.html It is even possible to not even set the vendor ID field, causing the driver to attempt to attach to _all_ the PCI devices. This sounds dangerous and I fail to see any valid use of this "feature". Thus I suggest that we now require at least the first two fields (vendor ID and device ID) to be set. For what it's worth, this is what the USB subsystem does. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- Documentation/pci.txt | 6 +++--- drivers/pci/pci-driver.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -163,9 +163,9 @@ echo "vendor device subvendor subdevice /sys/bus/pci/drivers/{driver}/new_id All fields are passed in as hexadecimal values (no leading 0x). -Users need pass only as many fields as necessary: - o vendor, device, subvendor, and subdevice fields default - to PCI_ANY_ID (FFFFFFFF), +The vendor and device fields are mandatory, the others are optional. Users +need pass only as many optional fields as necessary: + o subvendor and subdevice fields default to PCI_ANY_ID (FFFFFFFF) o class and classmask fields default to 0 o driver_data defaults to 0UL. --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -52,7 +52,7 @@ store_new_id(struct device_driver *drive { struct pci_dynid *dynid; struct pci_driver *pdrv = to_pci_driver(driver); - __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, + __u32 vendor, device, subvendor=PCI_ANY_ID, subdevice=PCI_ANY_ID, class=0, class_mask=0; unsigned long driver_data=0; int fields=0; @@ -61,7 +61,7 @@ store_new_id(struct device_driver *drive fields = sscanf(buf, "%x %x %x %x %x %x %lux", &vendor, &device, &subvendor, &subdevice, &class, &class_mask, &driver_data); - if (fields < 0) + if (fields < 2) return -EINVAL; dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);