From 4771489e89210b691ac43ad9912b03149b220998 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Mon, 29 Jan 2007 01:18:17 +0000 Subject: [PATCH] Changing from a stack allocated result struct to a heap allocated one. This removes the possibility that a timed out transfer that later still triggers the callback writes into invalid stack space. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20004 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 27 ++++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index fe057e3450..0abe8ada24 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -260,25 +260,25 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, size_t *actualLength) { - transfer_result_data transferResult; - transferResult.notify_sem = create_sem(0, "usb send request notify"); - if (transferResult.notify_sem < B_OK) + transfer_result_data *transferResult = (transfer_result_data *)malloc(sizeof(transfer_result_data)); + transferResult->notify_sem = create_sem(0, "usb send request notify"); + if (transferResult->notify_sem < B_OK) return B_NO_MORE_SEMS; status_t result = QueueRequest(requestType, request, value, index, length, - data, dataLength, SendRequestCallback, &transferResult); + data, dataLength, SendRequestCallback, transferResult); if (result < B_OK) { - delete_sem(transferResult.notify_sem); + delete_sem(transferResult->notify_sem); return result; } // the sem will be released in the callback after the result data was // filled into the provided struct. use a 5 seconds timeout to avoid // hanging applications. - if (acquire_sem_etc(transferResult.notify_sem, 1, B_RELATIVE_TIMEOUT, 5000000) < B_OK) { + if (acquire_sem_etc(transferResult->notify_sem, 1, B_RELATIVE_TIMEOUT, 5000000) < B_OK) { TRACE_ERROR(("USB ControlPipe: timeout waiting for queued request to complete\n")); - delete_sem(transferResult.notify_sem); + delete_sem(transferResult->notify_sem); if (actualLength) *actualLength = 0; @@ -286,11 +286,13 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value, return B_TIMED_OUT; } - delete_sem(transferResult.notify_sem); + delete_sem(transferResult->notify_sem); if (actualLength) - *actualLength = transferResult.actual_length; + *actualLength = transferResult->actual_length; - return transferResult.status; + result = transferResult->status; + free(transferResult); + return result; } @@ -301,7 +303,10 @@ ControlPipe::SendRequestCallback(void *cookie, status_t status, void *data, transfer_result_data *transferResult = (transfer_result_data *)cookie; transferResult->status = status; transferResult->actual_length = actualLength; - release_sem(transferResult->notify_sem); + if (release_sem(transferResult->notify_sem) < B_OK) { + // the request has timed out already - cleanup after us + free(transferResult); + } }