crash_get_memory_ranges() walks memblock, which memory hotplug
modifies under device_hotplug_lock.  A caller that does not hold
the lock can race with memblock_double_array() and iterate a freed
regions array.

Add device_hotplug_lock_assert_held() so that crash code can
use it to catch such unsafe callers via lockdep.

Cc: Greg Kroah-Hartman <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Danilo Krummrich <[email protected]>
Signed-off-by: Jinjie Ruan <[email protected]>
---
 drivers/base/core.c    | 5 +++++
 include/linux/device.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4c0c373998a1..c04adc457a96 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2420,6 +2420,11 @@ void unlock_device_hotplug(void)
        mutex_unlock(&device_hotplug_lock);
 }
 
+void device_hotplug_lock_assert_held(void)
+{
+       lockdep_assert_held(&device_hotplug_lock);
+}
+
 int lock_device_hotplug_sysfs(void)
 {
        if (mutex_trylock(&device_hotplug_lock))
diff --git a/include/linux/device.h b/include/linux/device.h
index aee79fd6b32b..9cca8c8bd372 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1261,6 +1261,7 @@ do { \
 void lock_device_hotplug(void);
 void unlock_device_hotplug(void);
 int lock_device_hotplug_sysfs(void);
+void device_hotplug_lock_assert_held(void);
 int device_offline(struct device *dev);
 int device_online(struct device *dev);
 
-- 
2.34.1


Reply via email to