From: Russell King Date: Fri, 20 Mar 2015 17:20:38 +0000 (+0000) Subject: PM / domains: avoid potential oops in pm_genpd_remove_device() X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=df6a0d6f633d684ef62bd92038c01a1781894f85;p=deliverable%2Flinux.git PM / domains: avoid potential oops in pm_genpd_remove_device() pm_genpd_remove_device() tries hard to validate the generic PM domain passed to it, but the validation is not complete. dev->pm_domain contains a struct dev_pm_domain, which is the "base class" of generic PM domains. Other users of dev_pm_domains include stuff like vga_switheroo. Hence, a device could have a generic PM domain or a vga_switcheroo PM domain in dev->pm_domain. We need ot be certain that the PM domain is actually valid before we try to remove it. We can do this easily as we have a way to get the current validated generic PM domain for a struct device. This must match the generic PM domain being requested for removal. Convert the code to use this alternative validation method instead. Signed-off-by: Russell King Acked-by: Kevin Hilman Acked-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index da25c0630789..2327613d4539 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1542,9 +1542,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, dev_dbg(dev, "%s()\n", __func__); - if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev) - || IS_ERR_OR_NULL(dev->pm_domain) - || pd_to_genpd(dev->pm_domain) != genpd) + if (!genpd || genpd != pm_genpd_lookup_dev(dev)) return -EINVAL; /* The above validation also means we have existing domain_data. */