From 0450e7b8022c9bd7a65b271c05b155ee5703454f Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 31 May 2023 16:49:41 -0400 Subject: [PATCH] USB: Acquire the device manager lock before Explore. We must do this to prevent lock order inversion: when busses are initialized, they are started by the (locked) device manager, and then acquire the explore lock. We must do the same in Explore itself, for when called by the explore thread, we would otherwise first acquire the explore lock, then (when publishing new nodes) acquire the device lock. Should fix #18421 and #18393. --- headers/private/kernel/kdevice_manager.h | 3 +++ src/add-ons/kernel/bus_managers/usb/Stack.cpp | 6 ++++++ src/system/kernel/device_manager/device_manager.cpp | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/headers/private/kernel/kdevice_manager.h b/headers/private/kernel/kdevice_manager.h index 9113773930..1f32eadcbd 100644 --- a/headers/private/kernel/kdevice_manager.h +++ b/headers/private/kernel/kdevice_manager.h @@ -7,6 +7,7 @@ #include +#include struct kernel_args; @@ -21,6 +22,8 @@ status_t device_manager_probe(const char *path, uint32 updateCycle); status_t device_manager_init(struct kernel_args *args); status_t device_manager_init_post_modules(struct kernel_args *args); +recursive_lock* device_manager_get_lock(); + #ifdef __cplusplus } #endif diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index c324858402..31d7633118 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -11,10 +11,13 @@ #include #include #include +#include + #include "usb_private.h" #include "PhysicalMemoryAllocator.h" #include +#include Stack::Stack() @@ -214,6 +217,9 @@ Stack::ExploreThread(void *data) void Stack::Explore() { + // Acquire the device manager lock before the explore lock, to prevent lock-order inversion. + RecursiveLocker dmLocker(device_manager_get_lock()); + if (mutex_lock(&fExploreLock) != B_OK) return; diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index c0fbd0c2a8..96e88cd387 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -2489,3 +2489,10 @@ device_manager_init_post_modules(struct kernel_args* args) RecursiveLocker _(sLock); return sRootNode->Reprobe(); } + + +recursive_lock* +device_manager_get_lock() +{ + return &sLock; +}