aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-30 07:05:05 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-30 07:05:05 -0500
commita6b5e88c0e42093b9057856f35770966c8c591e3 (patch)
tree9b0297d198ce8e690f10a61eec044532b55ea06c
parentd0c2ce16bec0afa6013b4c5220ca4c9c67210215 (diff)
ACPI / PNP: Do not crash due to stale pointer use during system resume
During resume from system suspend the 'data' field of struct pnp_dev in pnpacpi_set_resources() may be a stale pointer, due to removal of the associated ACPI device node object in the previous suspend-resume cycle. This happens, for example, if a dockable machine is booted in the docking station and then suspended and resumed and suspended again. If that happens, pnpacpi_build_resource_template() called from pnpacpi_set_resources() attempts to use that pointer and crashes. However, pnpacpi_set_resources() actually checks the device's ACPI handle, attempts to find the ACPI device node object attached to it and returns an error code if that fails, so in fact it knows what the correct value of dev->data should be. Use this observation to update dev->data with the correct value if necessary and dump a call trace if that's the case (once). We still need to fix the root cause of this issue, but preventing systems from crashing because of it is an improvement too. Reported-and-tested-by: Zdenek Kabelac <zdenek.kabelac@gmail.com> References: https://bugzilla.kernel.org/show_bug.cgi?id=51071 Cc: <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/pnp/pnpacpi/core.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 26b5d4b18dd..ec8e914f756 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -95,6 +95,9 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
95 return -ENODEV; 95 return -ENODEV;
96 } 96 }
97 97
98 if (WARN_ON_ONCE(acpi_dev != dev->data))
99 dev->data = acpi_dev;
100
98 ret = pnpacpi_build_resource_template(dev, &buffer); 101 ret = pnpacpi_build_resource_template(dev, &buffer);
99 if (ret) 102 if (ret)
100 return ret; 103 return ret;