From 17f42bc1d9dad54da45ba8821d0c486b7874dedf Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 9 Sep 2021 18:02:37 -0400 Subject: [PATCH] XHCI: Check earlier on that the endpoint is actually valid. This may catch the "division by zero" KDLs earlier. Related to #14943, #16794, and #16878. --- src/add-ons/kernel/busses/usb/xhci.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index ba31dc15f9..216089a460 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -715,9 +715,14 @@ XHCI::SubmitControlRequest(Transfer *transfer) xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); if (endpoint == NULL) { - TRACE_ERROR("invalid endpoint!\n"); + TRACE_ERROR("control pipe has no endpoint!\n"); return B_BAD_VALUE; } + if (endpoint->device == NULL) { + panic("endpoint is not initialized!"); + return B_NO_INIT; + } + status_t status = transfer->InitKernelAccess(); if (status != B_OK) return status; @@ -793,8 +798,14 @@ XHCI::SubmitNormalRequest(Transfer *transfer) bool directionIn = (pipe->Direction() == Pipe::In); xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); - if (endpoint == NULL) + if (endpoint == NULL) { + TRACE_ERROR("pipe has no endpoint!\n"); return B_BAD_VALUE; + } + if (endpoint->device == NULL) { + panic("endpoint is not initialized!"); + return B_NO_INIT; + } status_t status = transfer->InitKernelAccess(); if (status != B_OK) @@ -1824,13 +1835,6 @@ XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) { TRACE("link descriptor for pipe\n"); - // We must check this before we lock the endpoint, because if it is - // NULL, the mutex is probably uninitialized, too. - if (endpoint->device == NULL) { - TRACE_ERROR("trying to submit a transfer to a non-existent endpoint!\n"); - return B_NO_INIT; - } - // Use mutex_trylock first, in case we are in KDL. if (mutex_trylock(&endpoint->lock) != B_OK) mutex_lock(&endpoint->lock);