From e8971dd4914c9d42938c4c885b4ac6d784d7e0ff Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 3 Oct 2016 23:22:36 +0200 Subject: [PATCH 2/3] csdk: move OCClientResponse from stack to heap OCClientResponse is about 50KByte and should not be stored on the stack. On LEDE with MIPS, musl libc this causes a segmentation fault. Moving this structure to the heap is the simple solution for this problem, but this structure should be shrined. There are probably more places were this is stored on the stack and will cause problems. This fixes the other issue I saw in https://jira.iotivity.org/browse/IOT-1374 Change-Id: I45d8aee4a8151fea51d3318acb1eea61ce579060 Signed-off-by: Hauke Mehrtens --- resource/csdk/stack/src/ocstack.c | 163 ++++++++++++++++++++++++-------------- 1 file changed, 102 insertions(+), 61 deletions(-) --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -1042,7 +1042,7 @@ OCStackResult HandlePresenceResponse(con OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION; ClientCB * cbNode = NULL; char *resourceTypeName = NULL; - OCClientResponse response = {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; + OCClientResponse *response = NULL; OCStackResult result = OC_STACK_ERROR; uint32_t maxAge = 0; int uriLen; @@ -1057,15 +1057,23 @@ OCStackResult HandlePresenceResponse(con return OC_STACK_ERROR; } - response.payload = NULL; - response.result = OC_STACK_OK; + response = (OCClientResponse *)OICCalloc(1, sizeof(*response)); + if (!response) + { + OIC_LOG(ERROR, TAG, "Allocating memory for response failed"); + return OC_STACK_ERROR; + } + response->devAddr.adapter = OC_DEFAULT_ADAPTER; - CopyEndpointToDevAddr(endpoint, &response.devAddr); - FixUpClientResponse(&response); + response->payload = NULL; + response->result = OC_STACK_OK; + + CopyEndpointToDevAddr(endpoint, &response->devAddr); + FixUpClientResponse(response); if (responseInfo->info.payload) { - result = OCParsePayload(&response.payload, + result = OCParsePayload(&response->payload, PAYLOAD_TYPE_PRESENCE, responseInfo->info.payload, responseInfo->info.payloadSize); @@ -1075,15 +1083,15 @@ OCStackResult HandlePresenceResponse(con OIC_LOG(ERROR, TAG, "Presence parse failed"); goto exit; } - if(!response.payload || response.payload->type != PAYLOAD_TYPE_PRESENCE) + if(!response->payload || response->payload->type != PAYLOAD_TYPE_PRESENCE) { OIC_LOG(ERROR, TAG, "Presence payload was wrong type"); result = OC_STACK_ERROR; goto exit; } - response.sequenceNumber = ((OCPresencePayload*)response.payload)->sequenceNumber; - resourceTypeName = ((OCPresencePayload*)response.payload)->resourceType; - maxAge = ((OCPresencePayload*)response.payload)->maxAge; + response->sequenceNumber = ((OCPresencePayload*)response->payload)->sequenceNumber; + resourceTypeName = ((OCPresencePayload*)response->payload)->resourceType; + maxAge = ((OCPresencePayload*)response->payload)->maxAge; } // check for unicast presence @@ -1091,6 +1099,7 @@ OCStackResult HandlePresenceResponse(con responseInfo->isMulticast); if (uriLen < 0 || (size_t)uriLen >= sizeof (presenceUri)) { + OICFree(response); return OC_STACK_INVALID_URI; } OIC_LOG(ERROR, TAG, "check for unicast presence"); @@ -1118,7 +1127,7 @@ OCStackResult HandlePresenceResponse(con if (presenceSubscribe) { - if(cbNode->sequenceNumber == response.sequenceNumber) + if(cbNode->sequenceNumber == response->sequenceNumber) { OIC_LOG(INFO, TAG, "No presence change"); ResetPresenceTTL(cbNode, maxAge); @@ -1129,7 +1138,7 @@ OCStackResult HandlePresenceResponse(con if(maxAge == 0) { OIC_LOG(INFO, TAG, "Stopping presence"); - response.result = OC_STACK_PRESENCE_STOPPED; + response->result = OC_STACK_PRESENCE_STOPPED; if(cbNode->presence) { OICFree(cbNode->presence->timeOut); @@ -1165,7 +1174,7 @@ OCStackResult HandlePresenceResponse(con ResetPresenceTTL(cbNode, maxAge); - cbNode->sequenceNumber = response.sequenceNumber; + cbNode->sequenceNumber = response->sequenceNumber; } } else @@ -1175,7 +1184,7 @@ OCStackResult HandlePresenceResponse(con if (0 == maxAge) { OIC_LOG(INFO, TAG, "Stopping presence"); - response.result = OC_STACK_PRESENCE_STOPPED; + response->result = OC_STACK_PRESENCE_STOPPED; } } @@ -1191,7 +1200,7 @@ OCStackResult HandlePresenceResponse(con OIC_LOG(INFO, TAG, "Callback for presence"); - cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &response); + cbResult = cbNode->callBack(cbNode->context, cbNode->handle, response); if (cbResult == OC_STACK_DELETE_TRANSACTION) { @@ -1199,7 +1208,8 @@ OCStackResult HandlePresenceResponse(con } exit: - OCPayloadDestroy(response.payload); + OCPayloadDestroy(response->payload); + OICFree(response); return result; } @@ -1240,36 +1250,53 @@ void OCHandleResponse(const CAEndpoint_t OIC_LOG(INFO, TAG, "Receiving A Timeout for this token"); OIC_LOG(INFO, TAG, "Calling into application address space"); - OCClientResponse response = - {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; - CopyEndpointToDevAddr(endPoint, &response.devAddr); - FixUpClientResponse(&response); - response.resourceUri = responseInfo->info.resourceUri; - memcpy(response.identity.id, responseInfo->info.identity.id, - sizeof (response.identity.id)); - response.identity.id_length = responseInfo->info.identity.id_length; + OCClientResponse *response = NULL; + + response = (OCClientResponse *)OICCalloc(1, sizeof(*response)); + if (!response) + { + OIC_LOG(ERROR, TAG, "Allocating memory for response failed"); + return; + } + + response->devAddr.adapter = OC_DEFAULT_ADAPTER; + CopyEndpointToDevAddr(endPoint, &response->devAddr); + FixUpClientResponse(response); + response->resourceUri = responseInfo->info.resourceUri; + memcpy(response->identity.id, responseInfo->info.identity.id, + sizeof (response->identity.id)); + response->identity.id_length = responseInfo->info.identity.id_length; - response.result = CAResponseToOCStackResult(responseInfo->result); + response->result = CAResponseToOCStackResult(responseInfo->result); cbNode->callBack(cbNode->context, - cbNode->handle, &response); + cbNode->handle, response); FindAndDeleteClientCB(cbNode); + OICFree(response); } else { OIC_LOG(INFO, TAG, "This is a regular response, A client call back is found"); OIC_LOG(INFO, TAG, "Calling into application address space"); - OCClientResponse response = - {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; - response.sequenceNumber = MAX_SEQUENCE_NUMBER + 1; - CopyEndpointToDevAddr(endPoint, &response.devAddr); - FixUpClientResponse(&response); - response.resourceUri = responseInfo->info.resourceUri; - memcpy(response.identity.id, responseInfo->info.identity.id, - sizeof (response.identity.id)); - response.identity.id_length = responseInfo->info.identity.id_length; + OCClientResponse *response = NULL; - response.result = CAResponseToOCStackResult(responseInfo->result); + response = (OCClientResponse *)OICCalloc(1, sizeof(*response)); + if (!response) + { + OIC_LOG(ERROR, TAG, "Allocating memory for response failed"); + return; + } + + response->devAddr.adapter = OC_DEFAULT_ADAPTER; + response->sequenceNumber = MAX_SEQUENCE_NUMBER + 1; + CopyEndpointToDevAddr(endPoint, &response->devAddr); + FixUpClientResponse(response); + response->resourceUri = responseInfo->info.resourceUri; + memcpy(response->identity.id, responseInfo->info.identity.id, + sizeof (response->identity.id)); + response->identity.id_length = responseInfo->info.identity.id_length; + + response->result = CAResponseToOCStackResult(responseInfo->result); if(responseInfo->info.payload && responseInfo->info.payloadSize) @@ -1359,21 +1386,23 @@ void OCHandleResponse(const CAEndpoint_t { OIC_LOG_V(ERROR, TAG, "Unknown Payload type: %d %s", cbNode->method, cbNode->requestUri); + OICFree(response); return; } - if(OC_STACK_OK != OCParsePayload(&response.payload, + if(OC_STACK_OK != OCParsePayload(&response->payload, type, responseInfo->info.payload, responseInfo->info.payloadSize)) { OIC_LOG(ERROR, TAG, "Error converting payload"); - OCPayloadDestroy(response.payload); + OCPayloadDestroy(response->payload); + OICFree(response); return; } } - response.numRcvdVendorSpecificHeaderOptions = 0; + response->numRcvdVendorSpecificHeaderOptions = 0; if(responseInfo->info.numOptions > 0) { int start = 0; @@ -1391,19 +1420,20 @@ void OCHandleResponse(const CAEndpoint_t observationOption = (observationOption << 8) | optionData[i]; } - response.sequenceNumber = observationOption; - response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions - 1; + response->sequenceNumber = observationOption; + response->numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions - 1; start = 1; } else { - response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions; + response->numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions; } - if(response.numRcvdVendorSpecificHeaderOptions > MAX_HEADER_OPTIONS) + if(response->numRcvdVendorSpecificHeaderOptions > MAX_HEADER_OPTIONS) { OIC_LOG(ERROR, TAG, "#header options are more than MAX_HEADER_OPTIONS"); - OCPayloadDestroy(response.payload); + OCPayloadDestroy(response->payload); + OICFree(response); return; } @@ -1411,19 +1441,19 @@ void OCHandleResponse(const CAEndpoint_t { if(&(responseInfo->info.options[i])) { - memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]), + memcpy (&(response->rcvdVendorSpecificHeaderOptions[i-start]), &(responseInfo->info.options[i]), sizeof(OCHeaderOption)); } } } if (cbNode->method == OC_REST_OBSERVE && - response.sequenceNumber > OC_OFFSET_SEQUENCE_NUMBER && + response->sequenceNumber > OC_OFFSET_SEQUENCE_NUMBER && cbNode->sequenceNumber <= MAX_SEQUENCE_NUMBER && - response.sequenceNumber <= cbNode->sequenceNumber) + response->sequenceNumber <= cbNode->sequenceNumber) { OIC_LOG_V(INFO, TAG, "Received stale notification. Number :%d", - response.sequenceNumber); + response->sequenceNumber); } else { @@ -1432,13 +1462,13 @@ void OCHandleResponse(const CAEndpoint_t char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI); if (targetUri) { - OCUpdateResourceInsWithResponse(cbNode->requestUri, &response); + OCUpdateResourceInsWithResponse(cbNode->requestUri, response); } #endif OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context, cbNode->handle, - &response); - cbNode->sequenceNumber = response.sequenceNumber; + response); + cbNode->sequenceNumber = response->sequenceNumber; if (appFeedback == OC_STACK_DELETE_TRANSACTION) { @@ -1459,7 +1489,8 @@ void OCHandleResponse(const CAEndpoint_t CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES); } - OCPayloadDestroy(response.payload); + OCPayloadDestroy(response->payload); + OICFree(response); } return; } @@ -1585,16 +1616,26 @@ void HandleCAErrorResponse(const CAEndpo errorInfo->info.tokenLength, NULL, NULL); if (cbNode) { - OCClientResponse response = { .devAddr = { .adapter = OC_DEFAULT_ADAPTER } }; - CopyEndpointToDevAddr(endPoint, &response.devAddr); - FixUpClientResponse(&response); - response.resourceUri = errorInfo->info.resourceUri; - memcpy(response.identity.id, errorInfo->info.identity.id, - sizeof (response.identity.id)); - response.identity.id_length = errorInfo->info.identity.id_length; - response.result = CAResultToOCResult(errorInfo->result); + OCClientResponse *response = NULL; + + response = (OCClientResponse *)OICCalloc(1, sizeof(*response)); + if (!response) + { + OIC_LOG(ERROR, TAG, "Allocating memory for response failed"); + return; + } + + response->devAddr.adapter = OC_DEFAULT_ADAPTER; + CopyEndpointToDevAddr(endPoint, &response->devAddr); + FixUpClientResponse(response); + response->resourceUri = errorInfo->info.resourceUri; + memcpy(response->identity.id, errorInfo->info.identity.id, + sizeof (response->identity.id)); + response->identity.id_length = errorInfo->info.identity.id_length; + response->result = CAResultToOCResult(errorInfo->result); - cbNode->callBack(cbNode->context, cbNode->handle, &response); + cbNode->callBack(cbNode->context, cbNode->handle, response); + OICFree(response); } ResourceObserver *observer = GetObserverUsingToken(errorInfo->info.token,