Fix segfault when calling OCCancel ()
authorMandeep Shetty <mandeep.shetty@intel.com>
Thu, 24 Sep 2015 20:42:39 +0000 (13:42 -0700)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Fri, 25 Sep 2015 18:27:28 +0000 (18:27 +0000)
This fixes the client side crash in IOT-733.
OCCancel () allocates a pointer that is free'd in routingutility.c.
Although the pointer was passed in as reference into routingutility and
is re-assigned with a new malloc'ed pointer, OCCancel() free's the old
pointer.
This is because there two structs that are being passed around. The
pointer that is double free'd is free'd twice as part of two DIFFERENT
structs. Got rid of the extra struct to keep things consistent and
resolve the crash.

If accepted, this changeset should be cherrypicked to 1.0.0-dev.

Change-Id: I8c961776406c02dbe7706a787bb19db53ba83853
Signed-off-by: Mandeep Shetty <mandeep.shetty@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/3055
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
Reviewed-by: Gabriel Schulhof <gabriel.schulhof@intel.com>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
resource/csdk/stack/src/ocstack.c

index e8f89e4..f6d2e70 100644 (file)
@@ -2534,7 +2534,6 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
      */
     OCStackResult ret = OC_STACK_OK;
     CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
-    CAInfo_t requestData = {.type = CA_MSG_CONFIRM};
     CARequestInfo_t requestInfo = {.method = CA_GET};
 
     if(!handle)
@@ -2545,14 +2544,15 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
     ClientCB *clientCB = GetClientCB(NULL, 0, handle, NULL);
     if (!clientCB)
     {
-        OC_LOG(ERROR, TAG, "Client callback not found. Called OCCancel twice?");
-        goto Error;
+        OC_LOG(ERROR, TAG, "Callback not found. Called OCCancel on same resource twice?");
+        return OC_STACK_ERROR;
     }
 
     switch (clientCB->method)
     {
         case OC_REST_OBSERVE:
         case OC_REST_OBSERVE_ALL:
+
             OC_LOG_V(INFO, TAG, "Canceling observation for resource %s",
                                         clientCB->requestUri);
             if (qos != OC_HIGH_QOS)
@@ -2560,29 +2560,34 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
                 FindAndDeleteClientCB(clientCB);
                 break;
             }
-            else
-            {
-                OC_LOG(INFO, TAG, "Cancelling observation as CONFIRMABLE");
-            }
 
-            requestData.type = qualityOfServiceToMessageType(qos);
-            requestData.token = clientCB->token;
-            requestData.tokenLength = clientCB->tokenLength;
-            if (CreateObserveHeaderOption (&(requestData.options),
+            OC_LOG(INFO, TAG, "Cancelling observation as CONFIRMABLE");
+
+            requestInfo.info.type = qualityOfServiceToMessageType(qos);
+            requestInfo.info.token = clientCB->token;
+            requestInfo.info.tokenLength = clientCB->tokenLength;
+
+            if (CreateObserveHeaderOption (&(requestInfo.info.options),
                     options, numOptions, OC_OBSERVE_DEREGISTER) != OC_STACK_OK)
             {
                 return OC_STACK_ERROR;
             }
-            requestData.numOptions = numOptions + 1;
-            requestData.resourceUri = OICStrdup (clientCB->requestUri);
-
-            requestInfo.method = CA_GET;
-            requestInfo.info = requestData;
+            requestInfo.info.numOptions = numOptions + 1;
+            requestInfo.info.resourceUri = OICStrdup (clientCB->requestUri);
 
             CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint);
 
-            // send request
             ret = OCSendRequest(&endpoint, &requestInfo);
+
+            if (requestInfo.info.options)
+            {
+                OICFree (requestInfo.info.options);
+            }
+            if (requestInfo.info.resourceUri)
+            {
+                OICFree (requestInfo.info.resourceUri);
+            }
+
             break;
 
 #ifdef WITH_PRESENCE
@@ -2596,15 +2601,6 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
             break;
     }
 
-Error:
-    if (requestData.numOptions > 0)
-    {
-        OICFree(requestData.options);
-    }
-    if (requestData.resourceUri)
-    {
-        OICFree (requestData.resourceUri);
-    }
     return ret;
 }