diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index ebb6d391f82..791459edfe2 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -2439,7 +2439,9 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_RESOLVING_NAME, (LPWSTR) lpszServerName, strlenW(lpszServerName)); - if (!GetAddress(lpszServerName, nServerPort, &socketAddr)) + sock_namelen = sizeof(socketAddr); + if (!GetAddress(lpszServerName, nServerPort, + (struct sockaddr *)&socketAddr, &sock_namelen)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); goto lerror; diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 1b8d585521a..4ff4be7c8b7 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1452,14 +1452,16 @@ static BOOL HTTP_ResolveName(LPWININETHTTPREQW lpwhr) { char szaddr[32]; LPWININETHTTPSESSIONW lpwhs = lpwhr->lpHttpSession; + socklen_t sa_len; INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_RESOLVING_NAME, lpwhs->lpszServerName, strlenW(lpwhs->lpszServerName)+1); + sa_len = sizeof(lpwhs->socketAddress); if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort, - &lpwhs->socketAddress)) + (struct sockaddr *)&lpwhs->socketAddress, &sa_len)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); return FALSE; diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 3d87a735504..b1def60ece9 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -2750,14 +2750,15 @@ BOOL WINAPI InternetCheckConnectionW( LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRe if (dwFlags & FLAG_ICC_FORCE_CONNECTION) { struct sockaddr_in sin; + socklen_t sa_len = sizeof(sin); int fd; - if (!GetAddress(hostW, port, &sin)) + if (!GetAddress(hostW, port, (struct sockaddr *)&sin, &sa_len)) goto End; fd = socket(sin.sin_family, SOCK_STREAM, 0); if (fd != -1) { - if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == 0) + if (connect(fd, (struct sockaddr *)&sin, sa_len) == 0) rc = TRUE; close(fd); } diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index e01e8de68f9..53e971512a1 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -381,7 +381,7 @@ HINTERNET HTTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, DWORD dwInternalFlags); BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr_in *psa); + struct sockaddr *psa, socklen_t *sa_len); void INTERNET_SetLastError(DWORD dwError); DWORD INTERNET_GetLastError(void); diff --git a/dlls/wininet/utility.c b/dlls/wininet/utility.c index 5afdeb29667..2c443bffdec 100644 --- a/dlls/wininet/utility.c +++ b/dlls/wininet/utility.c @@ -145,7 +145,7 @@ time_t ConvertTimeString(LPCWSTR asctime) BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr_in *psa) + struct sockaddr *psa, socklen_t *sa_len) { WCHAR *found; char *name; @@ -155,6 +155,7 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, int ret; #else struct hostent *phe; + struct sockaddr_in *sin = (struct sockaddr_in *)psa; #endif TRACE("%s\n", debugstr_w(lpszServerName)); @@ -186,10 +187,17 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret)); return FALSE; } + if (*sa_len < sizeof(struct sockaddr_in)) + { + WARN("address too small\n"); + freeaddrinfo( res ); + return FALSE; + } + *sa_len = sizeof(struct sockaddr_in); memset( psa, 0, sizeof(struct sockaddr_in) ); - memcpy( &psa->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr) ); - psa->sin_family = res->ai_family; - psa->sin_port = htons(nServerPort); + memcpy( &((struct sockaddr_in *)psa)->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr) ); + ((struct sockaddr_in *)psa)->sin_family = res->ai_family; + ((struct sockaddr_in *)psa)->sin_port = htons(nServerPort); freeaddrinfo( res ); #else @@ -203,10 +211,17 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LeaveCriticalSection( &cs_gethostbyname ); return FALSE; } - memset(psa,0,sizeof(struct sockaddr_in)); - memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length); - psa->sin_family = phe->h_addrtype; - psa->sin_port = htons(nServerPort); + if (*sa_len < sizeof(struct sockaddr_in)) + { + WARN("address too small\n"); + LeaveCriticalSection( &cs_gethostbyname ); + return FALSE; + } + *sa_len = sizeof(struct sockaddr_in); + memset(sin,0,sizeof(struct sockaddr_in)); + memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length); + sin->sin_family = phe->h_addrtype; + sin->sin_port = htons(nServerPort); LeaveCriticalSection( &cs_gethostbyname ); #endif