[Networkbearerselection] Fixes for prevent issues
authorPiotr Kosko <p.kosko@samsung.com>
Fri, 12 Jun 2015 06:33:32 +0000 (08:33 +0200)
committerPiotr Kosko <p.kosko@samsung.com>
Fri, 12 Jun 2015 09:07:57 +0000 (11:07 +0200)
[Feature] gethostbyname and inet_ntoa are not thread safety and were replaced.
  prevent issues CID: 445928 and 445469

[Verification] TCT passrate 100%.

Change-Id: Iee71db238c4c2751ba19543439fcbb58a3a16718
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
src/networkbearerselection/networkbearerselection_manager.cc

index 61d4b343955c7eca511bbfd8b7944444ab7262ab..8b4d141e4909c8a9519a8ad59f9b0ee1363c8635 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <netdb.h>
 #include <arpa/inet.h>
+#include <memory>
 
 namespace extension {
 namespace networkbearerselection {
@@ -324,11 +325,12 @@ void NetworkBearerSelectionManager::registStateChangeListener(
   LoggerD("enter");
   char* interfaceName = nullptr;
   char* hostAddr = nullptr;
-  struct hostent* host_entry;
+  std::unique_ptr<char, void(*)(void*)> host_addr_ptr(nullptr, &std::free);
+  struct addrinfo* servinfo = nullptr;
 
   if (connection_profile_get_network_interface_name(
           m_profileHandle, &interfaceName) != CONNECTION_ERROR_NONE) {
-    LoggerD("Fail to get interface name!");
+    LoggerE("Fail to get interface name!");
     if (m_profileHandle) {
       connection_profile_destroy(m_profileHandle);
       m_profileHandle = nullptr;
@@ -340,27 +342,41 @@ void NetworkBearerSelectionManager::registStateChangeListener(
 
   LoggerD("Domain name to be resolved: %s", domain_name.c_str());
 
-  host_entry = gethostbyname(domain_name.c_str());
-
-  if (!host_entry) {
-    LoggerD("gethostbyname is failed");
-    makeErrorCallback(domain_name, kInvalidValuesError);
-    if (connection_close_profile(m_connectionHandle,
-                                 m_profileHandle,
-                                 connection_closed_callback2,
-                                 nullptr) != CONNECTION_ERROR_NONE) {
-      LoggerD("connection close failed");
-      makeErrorCallback(domain_name, kPlatformError);
-    }
+  int ret_val = getaddrinfo(domain_name.c_str() , nullptr , nullptr , &servinfo);
+  if (0 != ret_val) {
+    LoggerE("Error while calling getaddrinfo(): %s", gai_strerror(ret_val));
     if (m_profileHandle) {
       connection_profile_destroy(m_profileHandle);
       m_profileHandle = nullptr;
     }
+    makeErrorCallback(domain_name, kPlatformError);
     return;
-  }
+  } else {
+    hostAddr = new char[servinfo->ai_addrlen + 1];
+    host_addr_ptr.reset(hostAddr);
+
+    struct in_addr  *addr = nullptr;
+    if (AF_INET == servinfo->ai_family) {
+      struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr;
+      addr = &(ipv->sin_addr);
+    } else {
+      struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)servinfo->ai_addr;
+      addr = (struct in_addr *) &(ipv6->sin6_addr);
+    }
+    if (nullptr == inet_ntop(servinfo->ai_family, addr, hostAddr, servinfo->ai_addrlen)) {
+      LoggerE("Error while calling inet_ntop()");
+      if (m_profileHandle) {
+        connection_profile_destroy(m_profileHandle);
+        m_profileHandle = nullptr;
+      }
+      makeErrorCallback(domain_name, kPlatformError);
+      freeaddrinfo(servinfo);
+      return;
+    }
+    LoggerD("hostAddr : %s", hostAddr);
 
-  hostAddr = inet_ntoa(*(struct in_addr*)host_entry->h_addr_list[0]);
-  LoggerD("hostAddr : %s", hostAddr);
+    freeaddrinfo(servinfo);
+  }
 
   NetworkBearerSelectionRequestEvent* event =
       new NetworkBearerSelectionRequestEvent(domain_name);