[IOT-1627][Android]resolve ipadapter memory leak issue
authorbg.chun <bg.chun@samsung.com>
Thu, 1 Dec 2016 06:01:54 +0000 (15:01 +0900)
committerUze Choi <uzchoi@samsung.com>
Fri, 2 Dec 2016 01:10:06 +0000 (01:10 +0000)
On android ipadapter there is memory leak issue
since the function which used for free pointer
of structure does not free all pointer member

Change-Id: If44dd9dc7562f851fa3f38526830aa84e4b35491
Signed-off-by: bg.chun <bg.chun@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/14995
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Larry Sachs <larry.j.sachs@intel.com>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
resource/csdk/connectivity/src/ip_adapter/android/caifaddrs.c

index 727e692685a2f8d1c59cd1bf27e45925ed0a7fa5..72750e3e8618ceaf5bb98295760ab5d391c3e65d 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/rtnetlink.h>
 #include "logger.h"
 #define TAG "OIC_CA_ifaddrs"
+#define VERIFY_NON_NULL(arg) { if (!arg) {OIC_LOG(ERROR, TAG, #arg " is NULL"); goto exit;} }
 
 #define NETLINK_MESSAGE_LENGTH  (4096)
 #define IFC_LABEL_LOOP          "lo"
@@ -55,12 +56,15 @@ static bool CASendNetlinkMessage(int netlinkFd, const void* data, size_t len)
 
 void CAFreeIfAddrs(struct ifaddrs *ifa)
 {
-    struct ifaddrs *cur;
+    struct ifaddrs *cur = NULL;
     while (ifa)
     {
         cur = ifa;
         ifa = ifa->ifa_next;
-        free(cur);
+        OICFree(cur->ifa_name);
+        OICFree(cur->ifa_addr);
+        OICFree(cur);
+        cur = NULL;
     }
 }
 
@@ -76,10 +80,14 @@ static struct ifaddrs *CAParsingAddr(struct nlmsghdr *recvMsg)
     int ifaddrmsgLen = IFA_PAYLOAD(recvMsg);
 
     struct ifaddrs *node = (struct ifaddrs *)OICCalloc(1, sizeof(struct ifaddrs));
+    VERIFY_NON_NULL(node);
+
     char nameBuf[IFNAMSIZ] = { 0 };
     node->ifa_next = NULL;
     if_indextoname(ifaddrmsgData->ifa_index, nameBuf);
     node->ifa_name = (char *)OICCalloc(strlen(nameBuf)+1, sizeof(char));
+    VERIFY_NON_NULL(node->ifa_name);
+
     OICStrcpy(node->ifa_name, strlen(nameBuf)+1, nameBuf);
     node->ifa_flags = ifaddrmsgData->ifa_flags;
     node->ifa_flags |= (IFF_UP|IFF_RUNNING);
@@ -92,6 +100,8 @@ static struct ifaddrs *CAParsingAddr(struct nlmsghdr *recvMsg)
         {
             case IFA_ADDRESS:
                 ss = (struct sockaddr_storage*)OICCalloc(1, sizeof(struct sockaddr_storage));
+                VERIFY_NON_NULL(ss);
+
                 ss->ss_family = ifaddrmsgData-> ifa_family;
 
                 if (ifaddrmsgData-> ifa_family == AF_INET)
@@ -115,6 +125,9 @@ static struct ifaddrs *CAParsingAddr(struct nlmsghdr *recvMsg)
     }
 
     return node;
+exit:
+    CAFreeIfAddrs(node);
+    return NULL;
 }
 
 CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
@@ -127,7 +140,7 @@ CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
     *ifap = NULL;
 
     int netlinkFd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
-    int state = -1;
+    CAResult_t state = CA_STATUS_FAILED;
     if (-1 == netlinkFd)
     {
         OIC_LOG_V(ERROR, TAG, "netlink socket failed: %s", strerror(errno));
@@ -146,6 +159,7 @@ CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
     if (!CASendNetlinkMessage(netlinkFd, &req, req.msgInfo.nlmsg_len))
     {
         OIC_LOG(ERROR, TAG, "netlink send failed");
+        state = CA_SOCKET_OPERATION_FAILED;
         goto exit;
     }
 
@@ -172,17 +186,20 @@ CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
             {
                 case NLMSG_DONE:
                     OIC_LOG(DEBUG, TAG, "NLMSG_DONE");
-                    state = 0;
+                    state = CA_STATUS_OK;
                     goto exit;
 
                 case NLMSG_ERROR:
                     OIC_LOG(ERROR, TAG, "NLMSG is invalid");
-                    state = -1;
+                    state = CA_SOCKET_OPERATION_FAILED;
                     goto exit;
 
                 case RTM_NEWADDR:
                     OIC_LOG(DEBUG, TAG, "RTM_NEWADDR");
                     node = CAParsingAddr(recvMsg);
+                    state = CA_MEMORY_ALLOC_FAILED;
+                    VERIFY_NON_NULL(node);
+                    state = CA_STATUS_OK;
 
                     if (*ifap == NULL)
                     {
@@ -193,6 +210,7 @@ CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
                         node->ifa_next = *ifap;
                         *ifap = node;
                     }
+                    node = NULL;
 
                     break;
 
@@ -207,10 +225,10 @@ CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
 exit:
     // release all resources
     close(netlinkFd);
-    if (state == -1)
+    if (state != CA_STATUS_OK)
     {
         CAFreeIfAddrs(*ifap);
-        return CA_SOCKET_OPERATION_FAILED;
     }
-    return CA_STATUS_OK;
+
+    return state;
 }