[haiku-commits] haiku: hrev52963 - src/add-ons/kernel/busses/usb

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 4 Mar 2019 16:12:41 -0500 (EST)

hrev52963 adds 3 changesets to branch 'master'
old head: 3fe76c19f50d60356b9902fa4193580b242e51ed
new head: a40a4c0d39da8d0cfe37263d3b82c4ba84414d37
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=a40a4c0d39da+%5E3fe76c19f50d

----------------------------------------------------------------------------

1533bd88b1ba: XHCI: Style cleanup and dead code removal.
  
  No functional change (besides some tweaked tracing) intended.

6b4d0adcd0b8: XHCI: Clear the device struct after tearing down its state.
  
  This clears out the area_ids, the pointers to them, and a variety
  of other state information that will be invalid following the
  deletion of the device.
  
  Turns #12929 from a use-after-free into a NULL dereference panic.

a40a4c0d39da: XHCI: Don't try to submit transfers to non-existent endpoints.
  
  Fixes #12929. The underlying issue that caused it still remains, though.

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

1 file changed, 39 insertions(+), 32 deletions(-)
src/add-ons/kernel/busses/usb/xhci.cpp | 71 ++++++++++++++++--------------

############################################################################

Commit:      1533bd88b1baf82c0aadd1a47f7b6214d30c14dc
URL:         https://git.haiku-os.org/haiku/commit/?id=1533bd88b1ba
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Mon Mar  4 04:45:19 2019 UTC

XHCI: Style cleanup and dead code removal.

No functional change (besides some tweaked tracing) intended.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index 395e6a1a40..c70bb63227 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -715,7 +715,8 @@ XHCI::SubmitNormalRequest(Transfer *transfer)
                return status;
 
        int32 trbCount = 0;
-       xhci_td *descriptor = CreateDescriptorChain(transfer->DataLength(), 
trbCount);
+       xhci_td *descriptor = CreateDescriptorChain(transfer->DataLength(),
+               trbCount);
        if (descriptor == NULL)
                return B_NO_MEMORY;
 
@@ -739,7 +740,8 @@ XHCI::SubmitNormalRequest(Transfer *transfer)
                }
                // link next td, if any
                if (td_chain->next_chain != NULL) {
-                       td_chain->trbs[td_chain->trb_count].qwtrb0 = 
td_chain->next_chain->this_phy;
+                       td_chain->trbs[td_chain->trb_count].qwtrb0 =
+                               td_chain->next_chain->this_phy;
                        td_chain->trbs[td_chain->trb_count].dwtrb2 = 
TRB_2_IRQ(0);
                        td_chain->trbs[td_chain->trb_count].dwtrb3
                                = 
B_HOST_TO_LENDIAN_INT32(TRB_3_TYPE(TRB_TYPE_LINK)
@@ -822,10 +824,6 @@ XHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
 status_t
 XHCI::AddTo(Stack *stack)
 {
-#ifdef TRACE_USB
-       set_dprintf_enabled(true);
-#endif
-
        if (!sPCIModule) {
                status_t status = get_module(B_PCI_MODULE_NAME,
                        (module_info **)&sPCIModule);
@@ -923,8 +921,8 @@ XHCI::CreateDescriptorChain(size_t bufferSize, int32 
&trbCount)
                TRACE("CreateDescriptorChain trbs %d for td %" B_PRId32 "\n", 
trbs, i);
                for (int j = 0; j < trbs; j++) {
                        if (fStack->AllocateChunk(&descriptor->buffer_log[j],
-                               &descriptor->buffer_phy[j],
-                               min_c(packetSize, bufferSize)) < B_OK) {
+                                       &descriptor->buffer_phy[j],
+                                       min_c(packetSize, bufferSize)) < B_OK) {
                                TRACE_ERROR("unable to allocate space for the 
buffer (size %"
                                        B_PRIuSIZE ")\n", bufferSize);
                                return NULL;
@@ -954,7 +952,7 @@ XHCI::CreateDescriptor(size_t bufferSize)
        phys_addr_t physicalAddress;
 
        if (fStack->AllocateChunk((void **)&result, &physicalAddress,
-               sizeof(xhci_td)) < B_OK) {
+                       sizeof(xhci_td)) < B_OK) {
                TRACE_ERROR("failed to allocate a transfer descriptor\n");
                return NULL;
        }
@@ -972,7 +970,7 @@ XHCI::CreateDescriptor(size_t bufferSize)
        }
 
        if (fStack->AllocateChunk(&result->buffer_log[0],
-               &result->buffer_phy[0], bufferSize) < B_OK) {
+                       &result->buffer_phy[0], bufferSize) < B_OK) {
                TRACE_ERROR("unable to allocate space for the buffer (size 
%ld)\n",
                        bufferSize);
                fStack->FreeChunk(result, result->this_phy, sizeof(xhci_td));
@@ -980,7 +978,7 @@ XHCI::CreateDescriptor(size_t bufferSize)
        }
 
        TRACE("CreateDescriptor allocated buffer_size %ld %p\n",
-                               result->buffer_size[0], result->buffer_log[0]);
+               result->buffer_size[0], result->buffer_log[0]);
 
        return result;
 }
@@ -990,7 +988,6 @@ void
 XHCI::FreeDescriptor(xhci_td *descriptor)
 {
        while (descriptor != NULL) {
-
                for (int i = 0; i < descriptor->buffer_count; i++) {
                        if (descriptor->buffer_size[i] == 0)
                                continue;
@@ -1450,7 +1447,7 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe)
        TRACE("_InsertEndpointForPipe endpoint address %" B_PRId8 "\n",
                pipe->EndpointAddress());
        if (pipe->ControllerCookie() != NULL
-               || pipe->Parent()->Type() != USB_OBJECT_DEVICE) {
+                       || pipe->Parent()->Type() != USB_OBJECT_DEVICE) {
                // default pipe is already referenced
                return B_OK;
        }
@@ -1523,16 +1520,6 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe)
                        return status;
                }
 
-#if 0
-               /* These commands error with "Context state" on some devices,
-                * and on others break transfers altogether. So just disable 
them
-                * for now. */
-               StopEndpoint(false, endpoint, device->slot);
-               SetTRDequeue(device->endpoints[id].trb_addr, 0, endpoint,
-                       device->slot);
-               ResetEndpoint(false, endpoint, device->slot);
-#endif
-
                _WriteContext(&device->input_ctx->input.dropFlags, 0);
                _WriteContext(&device->input_ctx->input.addFlags,
                        (1 << endpoint) | (1 << 0));
@@ -2011,6 +1998,7 @@ XHCI::Ring(uint8 slot, uint8 endpoint)
                panic("Ring() invalid slot/endpoint combination\n");
        if (slot > fSlotCount || endpoint >= XHCI_MAX_ENDPOINTS)
                panic("Ring() invalid slot or endpoint\n");
+
        WriteDoorReg32(XHCI_DOORBELL(slot), XHCI_DOORBELL_TARGET(endpoint)
                | XHCI_DOORBELL_STREAMID(0));
        /* Flush PCI posted writes */
@@ -2064,6 +2052,8 @@ XHCI::QueueCommand(xhci_trb* trb)
 void
 XHCI::HandleCmdComplete(xhci_trb* trb)
 {
+       TRACE("HandleCmdComplete trb %p\n", trb);
+
        if (fCmdAddr == trb->qwtrb0) {
                TRACE("Received command event\n");
                fCmdResult[0] = trb->dwtrb2;

############################################################################

Commit:      6b4d0adcd0b801dbdfcf5ae358f02b4629fc70c7
URL:         https://git.haiku-os.org/haiku/commit/?id=6b4d0adcd0b8
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Mon Mar  4 19:54:08 2019 UTC

Ticket:      https://dev.haiku-os.org/ticket/12929

XHCI: Clear the device struct after tearing down its state.

This clears out the area_ids, the pointers to them, and a variety
of other state information that will be invalid following the
deletion of the device.

Turns #12929 from a use-after-free into a NULL dereference panic.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index c70bb63227..89f6885897 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -1232,8 +1232,9 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
                "XHCI device context");
        if (device->device_ctx_area < B_OK) {
                TRACE_ERROR("unable to create a device context area\n");
-               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
+               memset(device, 0, sizeof(xhci_device));
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
        memset(device->device_ctx, 0, sizeof(*device->device_ctx) << 
fContextSizeShift);
@@ -1243,9 +1244,10 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
                        * XHCI_MAX_TRANSFERS, "XHCI endpoint trbs");
        if (device->trb_area < B_OK) {
                TRACE_ERROR("unable to create a device trbs area\n");
-               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
                delete_area(device->device_ctx_area);
+               memset(device, 0, sizeof(xhci_device));
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
 
@@ -1270,10 +1272,11 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
        if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0,
                        maxPacketSize, maxPacketSize & 0x7ff, speed) != B_OK) {
                TRACE_ERROR("unable to configure default control endpoint\n");
-               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
                delete_area(device->device_ctx_area);
                delete_area(device->trb_area);
+               memset(device, 0, sizeof(xhci_device));
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
 
@@ -1288,10 +1291,11 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
        // device should get to addressed state (bsr = 0)
        if (SetAddress(device->input_ctx_addr, false, slot) != B_OK) {
                TRACE_ERROR("unable to set address\n");
-               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
                delete_area(device->device_ctx_area);
                delete_area(device->trb_area);
+               memset(device, 0, sizeof(xhci_device));
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
 
@@ -1333,10 +1337,11 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
        if (actualLength != 8) {
                TRACE_ERROR("error while getting the device descriptor: %s\n",
                        strerror(status));
-               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
                delete_area(device->device_ctx_area);
                delete_area(device->trb_area);
+               memset(device, 0, sizeof(xhci_device));
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
 
@@ -1377,10 +1382,11 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
                if (actualLength != sizeof(usb_hub_descriptor)) {
                        TRACE_ERROR("error while getting the hub descriptor: 
%s\n",
                                strerror(status));
-                       device->state = XHCI_STATE_DISABLED;
                        delete_area(device->input_ctx_area);
                        delete_area(device->device_ctx_area);
                        delete_area(device->trb_area);
+                       memset(device, 0, sizeof(xhci_device));
+                       device->state = XHCI_STATE_DISABLED;
                        return NULL;
                }
 
@@ -1409,10 +1415,11 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
                } else {
                        TRACE_ERROR("device object failed to initialize\n");
                }
-               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
                delete_area(device->device_ctx_area);
                delete_area(device->trb_area);
+               memset(device, 0, sizeof(xhci_device));
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
        fPortSlots[hubPort] = slot;
@@ -1437,6 +1444,8 @@ XHCI::FreeDevice(Device *device)
        delete_area(fDevices[slot].trb_area);
        delete_area(fDevices[slot].input_ctx_area);
        delete_area(fDevices[slot].device_ctx_area);
+
+       memset(&fDevices[slot], 0, sizeof(xhci_device));
        fDevices[slot].state = XHCI_STATE_DISABLED;
 }
 

############################################################################

Revision:    hrev52963
Commit:      a40a4c0d39da8d0cfe37263d3b82c4ba84414d37
URL:         https://git.haiku-os.org/haiku/commit/?id=a40a4c0d39da
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Mon Mar  4 20:37:38 2019 UTC

Ticket:      https://dev.haiku-os.org/ticket/12929

XHCI: Don't try to submit transfers to non-existent endpoints.

Fixes #12929. The underlying issue that caused it still remains, though.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index 89f6885897..a7e8690e9f 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -621,7 +621,7 @@ XHCI::SubmitControlRequest(Transfer *transfer)
        xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
        uint8 id = XHCI_ENDPOINT_ID(pipe);
        if (id >= XHCI_MAX_ENDPOINTS) {
-               TRACE_ERROR("Invalid Endpoint");
+               TRACE_ERROR("invalid endpoint!\n");
                return B_BAD_VALUE;
        }
        status_t status = transfer->InitKernelAccess();
@@ -704,6 +704,7 @@ status_t
 XHCI::SubmitNormalRequest(Transfer *transfer)
 {
        TRACE("SubmitNormalRequest() length %ld\n", transfer->DataLength());
+
        Pipe *pipe = transfer->TransferPipe();
        uint8 id = XHCI_ENDPOINT_ID(pipe);
        if (id >= XHCI_MAX_ENDPOINTS)
@@ -1455,6 +1456,7 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe)
 {
        TRACE("_InsertEndpointForPipe endpoint address %" B_PRId8 "\n",
                pipe->EndpointAddress());
+
        if (pipe->ControllerCookie() != NULL
                        || pipe->Parent()->Type() != USB_OBJECT_DEVICE) {
                // default pipe is already referenced
@@ -1573,6 +1575,12 @@ status_t
 XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)
 {
        TRACE("_LinkDescriptorForPipe\n");
+
+       if (endpoint->device == NULL) {
+               TRACE_ERROR("trying to submit a transfer to a non-existent 
endpoint!\n");
+               return B_NO_INIT;
+       }
+
        MutexLocker endpointLocker(endpoint->lock);
        if (endpoint->used >= XHCI_MAX_TRANSFERS) {
                TRACE_ERROR("_LinkDescriptorForPipe max transfers count 
exceeded\n");
@@ -2133,7 +2141,7 @@ XHCI::HandleTransferComplete(xhci_trb* trb)
                        return;
                }
        }
-       TRACE_ERROR("TRB %" B_PRIxADDR " was not found in the endpoint!\n", 
source);
+       TRACE_ERROR("TRB 0x%" B_PRIxADDR " was not found in the endpoint!\n", 
source);
 }
 
 


Other related posts:

  • » [haiku-commits] haiku: hrev52963 - src/add-ons/kernel/busses/usb - waddlesplash