From 7ca496584efe97a2ddf0710a7e50a069fed4fd79 Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Fri, 12 Jun 2015 08:33:32 +0200 Subject: [PATCH] [Networkbearerselection] Fixes for prevent issues [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 --- .../networkbearerselection_manager.cc | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/networkbearerselection/networkbearerselection_manager.cc b/src/networkbearerselection/networkbearerselection_manager.cc index 61d4b343..8b4d141e 100644 --- a/src/networkbearerselection/networkbearerselection_manager.cc +++ b/src/networkbearerselection/networkbearerselection_manager.cc @@ -19,6 +19,7 @@ #include #include +#include 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 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); -- 2.34.1