summaryrefslogtreecommitdiff
path: root/Kernel/Devices
diff options
context:
space:
mode:
authorBrian Gianforcaro <bgianf@serenityos.org>2021-05-14 21:23:59 -0700
committerAndreas Kling <kling@serenityos.org>2021-05-15 09:46:41 +0200
commitd76dedb381275613f2c5fa655c59973770dfcf39 (patch)
tree6d233019a28bd9a502169e28abc17b38d9907307 /Kernel/Devices
parent3ba3d2ddfdb44e28323b4f6f5a1d7f98d8b4be23 (diff)
downloadserenity-d76dedb381275613f2c5fa655c59973770dfcf39.zip
Kernel: Fix UHCIController singleton startup null-deref race condition.
The following KUBSAN crash on startup was reported on discord: ``` UHCI: Started KUBSAN: reference binding to null pointer of type struct UHCIController KUBSAN: at ../../Kernel/Devices/USB/UHCIController.cpp, line 67 ``` After inspecting the code, it became clear that there's a window of time where the kernel task which monitors the UHCI port can startup and start executing before the UHCIController constructor completes. This leaves the singleton pointing to nullptr, thus in the duration of this race window the "UHCI port proc" thread will go an and de-reference the null pointer when trying to read for status changes on the UHCI root ports. Reported-by: @stelar7 Reported-by: @bcoles Fixes: #6154
Diffstat (limited to 'Kernel/Devices')
-rw-r--r--Kernel/Devices/USB/UHCIController.cpp8
1 files changed, 4 insertions, 4 deletions
diff --git a/Kernel/Devices/USB/UHCIController.cpp b/Kernel/Devices/USB/UHCIController.cpp
index bcbed565b7..0859aac1fe 100644
--- a/Kernel/Devices/USB/UHCIController.cpp
+++ b/Kernel/Devices/USB/UHCIController.cpp
@@ -77,8 +77,10 @@ UNMAP_AFTER_INIT void UHCIController::detect()
return;
if (PCI::get_class(address) == 0xc && PCI::get_subclass(address) == 0x03 && PCI::get_programming_interface(address) == 0) {
- if (!s_the)
+ if (!s_the) {
s_the = new UHCIController(address, id);
+ s_the->spawn_port_proc();
+ }
}
});
}
@@ -93,8 +95,6 @@ UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address, PCI::ID id
reset();
start();
-
- spawn_port_proc();
}
UNMAP_AFTER_INIT UHCIController::~UHCIController()
@@ -134,7 +134,7 @@ void UHCIController::reset()
UNMAP_AFTER_INIT void UHCIController::create_structures()
{
- // Let's allocate memory for botht the QH and TD pools
+ // Let's allocate memory for both the QH and TD pools
// First the QH pool and all of the Interrupt QH's
auto qh_pool_vmobject = ContiguousVMObject::create_with_size(2 * PAGE_SIZE);
m_qh_pool = MemoryManager::the().allocate_kernel_region_with_vmobject(*qh_pool_vmobject, 2 * PAGE_SIZE, "UHCI Queue Head Pool", Region::Access::Write);