mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
[ADVAPI32]
- ConvertStringSidToSidW: Stop writing 1 subauthority too much. Fixes a DWORD sized buffer overflow. Should fix bug #5764. - ConvertStringSidToSidW: Don't leak an allocated SID in case of failure. [SETUPAPI] - SetupDiClassNameFromGuidExW: Rewrite to prevent a buffer overflow and pass additional winetests. Should fix bug #5474. - SetupDiClassNameFromGuidExA: Return the required buffer size in failure cases. svn path=/trunk/; revision=50066
This commit is contained in:
parent
4989fe718a
commit
8e7e8f566f
2 changed files with 87 additions and 63 deletions
|
@ -1982,16 +1982,14 @@ ConvertStringSidToSidW(IN LPCWSTR StringSid,
|
||||||
if (*StringSid == '-')
|
if (*StringSid == '-')
|
||||||
StringSid++;
|
StringSid++;
|
||||||
|
|
||||||
pisid->SubAuthority[i] = atoiW(StringSid);
|
|
||||||
|
|
||||||
while (*StringSid)
|
while (*StringSid)
|
||||||
{
|
{
|
||||||
|
pisid->SubAuthority[i++] = atoiW(StringSid);
|
||||||
|
|
||||||
while (*StringSid && *StringSid != '-')
|
while (*StringSid && *StringSid != '-')
|
||||||
StringSid++;
|
StringSid++;
|
||||||
if (*StringSid == '-')
|
if (*StringSid == '-')
|
||||||
StringSid++;
|
StringSid++;
|
||||||
|
|
||||||
pisid->SubAuthority[++i] = atoiW(StringSid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != pisid->SubAuthorityCount)
|
if (i != pisid->SubAuthorityCount)
|
||||||
|
@ -2002,7 +2000,10 @@ ConvertStringSidToSidW(IN LPCWSTR StringSid,
|
||||||
|
|
||||||
lend:
|
lend:
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
{
|
||||||
|
LocalFree(pisid);
|
||||||
SetLastError(ERROR_INVALID_SID);
|
SetLastError(ERROR_INVALID_SID);
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
|
TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1103,7 +1103,7 @@ BOOL WINAPI SetupDiClassNameFromGuidExA(
|
||||||
if (MachineName)
|
if (MachineName)
|
||||||
MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
|
MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
|
||||||
ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
|
ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
|
||||||
NULL, MachineNameW, Reserved);
|
RequiredSize, MachineNameW, Reserved);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
|
int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
|
||||||
|
@ -1113,8 +1113,6 @@ BOOL WINAPI SetupDiClassNameFromGuidExA(
|
||||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
}
|
}
|
||||||
else if (RequiredSize)
|
|
||||||
*RequiredSize = len;
|
|
||||||
}
|
}
|
||||||
MyFree(MachineNameW);
|
MyFree(MachineNameW);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1135,73 +1133,98 @@ BOOL WINAPI SetupDiClassNameFromGuidExW(
|
||||||
DWORD dwLength;
|
DWORD dwLength;
|
||||||
DWORD dwRegType;
|
DWORD dwRegType;
|
||||||
LONG rc;
|
LONG rc;
|
||||||
|
PWSTR Buffer;
|
||||||
|
|
||||||
TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassName,
|
TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassName,
|
||||||
ClassNameSize, RequiredSize, debugstr_w(MachineName), Reserved);
|
ClassNameSize, RequiredSize, debugstr_w(MachineName), Reserved);
|
||||||
|
|
||||||
hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
|
/* Make sure there's a GUID */
|
||||||
KEY_QUERY_VALUE,
|
if (ClassGuid == NULL)
|
||||||
DIOCR_INSTALLER,
|
{
|
||||||
MachineName,
|
SetLastError(ERROR_INVALID_CLASS); /* On Vista: ERROR_INVALID_USER_BUFFER */
|
||||||
Reserved);
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there's a real buffer when there's a size */
|
||||||
|
if ((ClassNameSize > 0) && (ClassName == NULL))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER); /* On Vista: ERROR_INVALID_USER_BUFFER */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the key for the GUID */
|
||||||
|
hKey = SetupDiOpenClassRegKeyExW(ClassGuid, KEY_QUERY_VALUE, DIOCR_INSTALLER, MachineName, Reserved);
|
||||||
|
|
||||||
if (hKey == INVALID_HANDLE_VALUE)
|
if (hKey == INVALID_HANDLE_VALUE)
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RequiredSize != NULL)
|
|
||||||
{
|
|
||||||
dwLength = 0;
|
|
||||||
if (RegQueryValueExW(hKey,
|
|
||||||
Class,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&dwLength))
|
|
||||||
{
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*RequiredSize = dwLength / sizeof(WCHAR) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ClassGuid)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_CLASS);
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
if (!ClassName && ClassNameSize > 0)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
dwLength = ClassNameSize * sizeof(WCHAR) - sizeof(UNICODE_NULL);
|
/* Retrieve the class name data */
|
||||||
rc = RegQueryValueExW(hKey,
|
dwLength = ClassNameSize * sizeof(WCHAR);
|
||||||
Class,
|
|
||||||
NULL,
|
do
|
||||||
&dwRegType,
|
{
|
||||||
(LPBYTE)ClassName,
|
/* Allocate a buffer to retrieve the class name data */
|
||||||
&dwLength);
|
Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
|
||||||
|
|
||||||
|
if (Buffer == NULL)
|
||||||
|
{
|
||||||
|
rc = GetLastError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Query for the class name data */
|
||||||
|
rc = RegQueryValueExW(hKey, Class, NULL, &dwRegType, (LPBYTE) Buffer, &dwLength);
|
||||||
|
|
||||||
|
/* Clean up the buffer if needed */
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||||
|
} while (rc == ERROR_MORE_DATA);
|
||||||
|
|
||||||
|
/* Close the key */
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
/* Make sure we got the data */
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
SetLastError(rc);
|
SetLastError(rc);
|
||||||
RegCloseKey(hKey);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (dwRegType != REG_SZ)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_GEN_FAILURE);
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClassNameSize > 1)
|
/* Make sure the data is a string */
|
||||||
ClassName[ClassNameSize] = UNICODE_NULL;
|
if (dwRegType != REG_SZ)
|
||||||
RegCloseKey(hKey);
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||||
|
SetLastError(ERROR_GEN_FAILURE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the length of the class name */
|
||||||
|
dwLength /= sizeof(WCHAR);
|
||||||
|
|
||||||
|
if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
|
||||||
|
/* Count the null-terminator */
|
||||||
|
dwLength++;
|
||||||
|
|
||||||
|
/* Inform the caller about the class name */
|
||||||
|
if ((ClassName != NULL) && (dwLength <= ClassNameSize))
|
||||||
|
{
|
||||||
|
memcpy(ClassName, Buffer, (dwLength - 1) * sizeof(WCHAR));
|
||||||
|
ClassName[dwLength - 1] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inform the caller about the required size */
|
||||||
|
if (RequiredSize != NULL)
|
||||||
|
*RequiredSize = dwLength;
|
||||||
|
|
||||||
|
/* Clean up the buffer */
|
||||||
|
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||||
|
|
||||||
|
/* Make sure the buffer was large enough */
|
||||||
|
if ((ClassName == NULL) || (dwLength > ClassNameSize))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue