ACPI / CPPC: Fix per-CPU pointer management in acpi_cppc_processor_probe()
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 9 Dec 2016 23:52:28 +0000 (00:52 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 12 Dec 2016 22:52:34 +0000 (23:52 +0100)
Fix a possible use-after-free scenario in acpi_cppc_processor_probe()
that can happen if the function returns without cleaning up the
per-CPU pointer set by it previously.

Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/cppc_acpi.c

index ae2ad6e..3ca0729 100644 (file)
@@ -776,9 +776,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
                init_waitqueue_head(&pcc_data.pcc_write_wait_q);
        }
 
-       /* Plug PSD data into this CPUs CPC descriptor. */
-       per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
-
        /* Everything looks okay */
        pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
 
@@ -789,10 +786,15 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
                goto out_free;
        }
 
+       /* Plug PSD data into this CPUs CPC descriptor. */
+       per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
+
        ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
                        "acpi_cppc");
-       if (ret)
+       if (ret) {
+               per_cpu(cpc_desc_ptr, pr->id) = NULL;
                goto out_free;
+       }
 
        kfree(output.pointer);
        return 0;