forked from luck/tmp_suning_uos_patched
PCI: Check dynids driver_data value for validity
Only accept dynids whose driver_data value matches one of the driver's pci_driver_id entries. This prevents the user from accidentally passing values the drivers do not expect. Cc: Milton Miller <miltonm@bga.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
edbc25caaa
commit
b41d6cf38e
@ -163,6 +163,10 @@ need pass only as many optional fields as necessary:
|
|||||||
o class and classmask fields default to 0
|
o class and classmask fields default to 0
|
||||||
o driver_data defaults to 0UL.
|
o driver_data defaults to 0UL.
|
||||||
|
|
||||||
|
Note that driver_data must match the value used by any of the pci_device_id
|
||||||
|
entries defined in the driver. This makes the driver_data field mandatory
|
||||||
|
if all the pci_device_id entries have a non-zero driver_data value.
|
||||||
|
|
||||||
Once added, the driver probe routine will be invoked for any unclaimed
|
Once added, the driver probe routine will be invoked for any unclaimed
|
||||||
PCI devices listed in its (newly updated) pci_ids list.
|
PCI devices listed in its (newly updated) pci_ids list.
|
||||||
|
|
||||||
|
@ -332,10 +332,6 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
|
|||||||
int error;
|
int error;
|
||||||
u8 temp;
|
u8 temp;
|
||||||
|
|
||||||
/* driver_data might come from user-space, so check it */
|
|
||||||
if (id->driver_data >= ARRAY_SIZE(chipname))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (amd756_ioport) {
|
if (amd756_ioport) {
|
||||||
dev_err(&pdev->dev, "Only one device supported "
|
dev_err(&pdev->dev, "Only one device supported "
|
||||||
"(you have a strange motherboard, btw)\n");
|
"(you have a strange motherboard, btw)\n");
|
||||||
|
@ -332,10 +332,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
|
|||||||
unsigned char temp;
|
unsigned char temp;
|
||||||
int error = -ENODEV;
|
int error = -ENODEV;
|
||||||
|
|
||||||
/* driver_data might come from user-space, so check it */
|
|
||||||
if (id->driver_data & 1 || id->driver_data > 0xff)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Determine the address of the SMBus areas */
|
/* Determine the address of the SMBus areas */
|
||||||
if (force_addr) {
|
if (force_addr) {
|
||||||
vt596_smba = force_addr & 0xfff0;
|
vt596_smba = force_addr & 0xfff0;
|
||||||
|
@ -43,18 +43,32 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
|
|||||||
{
|
{
|
||||||
struct pci_dynid *dynid;
|
struct pci_dynid *dynid;
|
||||||
struct pci_driver *pdrv = to_pci_driver(driver);
|
struct pci_driver *pdrv = to_pci_driver(driver);
|
||||||
|
const struct pci_device_id *ids = pdrv->id_table;
|
||||||
__u32 vendor, device, subvendor=PCI_ANY_ID,
|
__u32 vendor, device, subvendor=PCI_ANY_ID,
|
||||||
subdevice=PCI_ANY_ID, class=0, class_mask=0;
|
subdevice=PCI_ANY_ID, class=0, class_mask=0;
|
||||||
unsigned long driver_data=0;
|
unsigned long driver_data=0;
|
||||||
int fields=0;
|
int fields=0;
|
||||||
int retval = 0;
|
int retval;
|
||||||
|
|
||||||
fields = sscanf(buf, "%x %x %x %x %x %x %lux",
|
fields = sscanf(buf, "%x %x %x %x %x %x %lx",
|
||||||
&vendor, &device, &subvendor, &subdevice,
|
&vendor, &device, &subvendor, &subdevice,
|
||||||
&class, &class_mask, &driver_data);
|
&class, &class_mask, &driver_data);
|
||||||
if (fields < 2)
|
if (fields < 2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Only accept driver_data values that match an existing id_table
|
||||||
|
entry */
|
||||||
|
retval = -EINVAL;
|
||||||
|
while (ids->vendor || ids->subvendor || ids->class_mask) {
|
||||||
|
if (driver_data == ids->driver_data) {
|
||||||
|
retval = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ids++;
|
||||||
|
}
|
||||||
|
if (retval) /* No match */
|
||||||
|
return retval;
|
||||||
|
|
||||||
dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
|
dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
|
||||||
if (!dynid)
|
if (!dynid)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
Loading…
Reference in New Issue
Block a user