Author: hbelusca Date: Sun Mar 5 00:40:22 2017 New Revision: 74068
URL: http://svn.reactos.org/svn/reactos?rev=74068&view=rev Log: [WS2_32] - Fix pointers verification in WSALookupServiceNextW and WSALookupServiceNextA; - In WSALookupServiceNextA: Perform extra checks to see whether we failed the first local buffer allocation, and if so, retrieve the needed size by calling a first time WSALookupServiceNextW, then reallocate the temp buffer and redo a WSALookupServiceNextW call (if it still fails, then we bail out). CID 513448.
Modified: trunk/reactos/dll/win32/ws2_32/src/rnr.c
Modified: trunk/reactos/dll/win32/ws2_32/src/rnr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ws2_32/src/rnr.c?... ============================================================================== --- trunk/reactos/dll/win32/ws2_32/src/rnr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ws2_32/src/rnr.c [iso-8859-1] Sun Mar 5 00:40:22 2017 @@ -403,9 +403,12 @@ return SOCKET_ERROR; }
- /* Verify pointers */ + /* + * Verify pointers. Note that the size of the buffer + * pointed by lpqsResults is given by *lpdwBufferLength. + */ if (IsBadReadPtr(lpdwBufferLength, sizeof(*lpdwBufferLength)) || - IsBadWritePtr(lpqsResults, sizeof(*lpqsResults))) + IsBadWritePtr(lpqsResults, *lpdwBufferLength)) { /* It is invalid; fail */ SetLastError(WSAEFAULT); @@ -449,9 +452,12 @@
DPRINT("WSALookupServiceNextA: %lx\n", hLookup);
- /* Verify pointers */ + /* + * Verify pointers. Note that the size of the buffer + * pointed by lpqsResults is given by *lpdwBufferLength. + */ if (IsBadReadPtr(lpdwBufferLength, sizeof(*lpdwBufferLength)) || - IsBadWritePtr(lpqsResults, sizeof(*lpqsResults))) + IsBadWritePtr(lpqsResults, *lpdwBufferLength)) { /* It is invalid; fail */ SetLastError(WSAEFAULT); @@ -465,13 +471,24 @@ { /* Allocate the buffer we'll use */ UnicodeQuerySet = HeapAlloc(WsSockHeap, 0, UnicodeQuerySetSize); - if (!UnicodeQuerySet) UnicodeQuerySetSize = 0; + if (!UnicodeQuerySet) + { + /* + * We failed, possibly because the specified size was too large? + * Retrieve the needed buffer size with the WSALookupServiceNextW + * call and retry again a second time. + */ + UnicodeQuerySetSize = 0; + } } else { - /* His buffer is too small */ + /* + * The buffer is too small. Retrieve the needed buffer size with + * the WSALookupServiceNextW call and return it to the caller. + */ + UnicodeQuerySet = NULL; UnicodeQuerySetSize = 0; - UnicodeQuerySet = NULL; }
/* Call the Unicode Function */ @@ -479,13 +496,39 @@ dwControlFlags, &UnicodeQuerySetSize, UnicodeQuerySet); + + /* + * Check whether we actually just retrieved the needed buffer size + * because our previous local allocation did fail. If so, allocate + * a new buffer and retry again. + */ + if ( (!UnicodeQuerySet) && (*lpdwBufferLength >= sizeof(WSAQUERYSETW)) && + (ErrorCode == SOCKET_ERROR) && (GetLastError() == WSAEFAULT) ) + { + /* Allocate the buffer we'll use */ + UnicodeQuerySet = HeapAlloc(WsSockHeap, 0, UnicodeQuerySetSize); + if (UnicodeQuerySet) + { + /* Call the Unicode Function */ + ErrorCode = WSALookupServiceNextW(hLookup, + dwControlFlags, + &UnicodeQuerySetSize, + UnicodeQuerySet); + } + /* + * Otherwise the allocation failed and we + * fall back into the error checks below. + */ + } + if (ErrorCode == ERROR_SUCCESS) { - /* Not convert to ANSI */ + /* Now convert back to ANSI */ ErrorCode = MapUnicodeQuerySetToAnsi(UnicodeQuerySet, lpdwBufferLength, lpqsResults); - if (ErrorCode != ERROR_SUCCESS) SetLastError(ErrorCode); + if (ErrorCode != ERROR_SUCCESS) + SetLastError(ErrorCode); } else { @@ -499,10 +542,11 @@ }
/* If we had a local buffer, free it */ - if (UnicodeQuerySet) HeapFree(WsSockHeap, 0, UnicodeQuerySet); + if (UnicodeQuerySet) + HeapFree(WsSockHeap, 0, UnicodeQuerySet);
/* Return to caller */ - return ErrorCode == ERROR_SUCCESS ? ErrorCode : SOCKET_ERROR; + return (ErrorCode == ERROR_SUCCESS) ? ErrorCode : SOCKET_ERROR; }
/*