PCI: acpiphp_ibm: Fix null dereferences on null ibm_slot
authorColin Ian King <colin.king@canonical.com>
Sat, 2 Jan 2016 00:27:01 +0000 (00:27 +0000)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 8 Jan 2016 18:12:33 +0000 (12:12 -0600)
ibm_slot_from_id() can return null if the des header signature is not
"aPCI" or if the kmalloc() for the return ACPI descriptor fails, causing
potential null pointer dereferences on the return null descriptor.

Handle the null case with appropriate check and error return.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/hotplug/acpiphp_ibm.c

index 6ca23998ee8f36b1d486dcaa4c50c77ae74c8979..9d16c9dbd76e9d6f94f389ef7dbe38a1bd9c6009 100644 (file)
@@ -154,7 +154,8 @@ static union apci_descriptor *ibm_slot_from_id(int id)
 ibm_slot_done:
        if (ret) {
                ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
-               memcpy(ret, des, sizeof(union apci_descriptor));
+               if (ret)
+                       memcpy(ret, des, sizeof(union apci_descriptor));
        }
        kfree(table);
        return ret;
@@ -175,8 +176,13 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
        acpi_status stat;
        unsigned long long rc;
        union apci_descriptor *ibm_slot;
+       int id = hpslot_to_sun(slot);
 
-       ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
+       ibm_slot = ibm_slot_from_id(id);
+       if (!ibm_slot) {
+               pr_err("APLS null ACPI descriptor for slot %d\n", id);
+               return -ENODEV;
+       }
 
        pr_debug("%s: set slot %d (%d) attention status to %d\n", __func__,
                        ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
@@ -215,8 +221,13 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
 static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
 {
        union apci_descriptor *ibm_slot;
+       int id = hpslot_to_sun(slot);
 
-       ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
+       ibm_slot = ibm_slot_from_id(id);
+       if (!ibm_slot) {
+               pr_err("APLS null ACPI descriptor for slot %d\n", id);
+               return -ENODEV;
+       }
 
        if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
                *status = 1;