[ADVAPI32]

* Fix bug in RegQueryValueExA, which causes buffer overflow
* Fixes systeminfo in ReactOS
See issue #6050 for more details.

svn path=/trunk/; revision=51222
This commit is contained in:
Rafal Harabien 2011-04-01 22:10:52 +00:00
parent 7c126a9a69
commit f4f2b68256

View file

@ -3988,7 +3988,7 @@ RegQueryValueExA(HKEY hKey,
LPDWORD lpcbData) LPDWORD lpcbData)
{ {
UNICODE_STRING ValueName; UNICODE_STRING ValueName;
UNICODE_STRING ValueData; LPWSTR lpValueBuffer;
LONG ErrorCode; LONG ErrorCode;
DWORD Length; DWORD Length;
DWORD Type; DWORD Type;
@ -4003,39 +4003,42 @@ RegQueryValueExA(HKEY hKey,
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
Length = (lpcbData == NULL || lpData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
if (lpData) if (lpData)
{ {
ValueData.Length = 0; lpValueBuffer = RtlAllocateHeap(ProcessHeap,
ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
0, 0,
ValueData.MaximumLength); Length + sizeof(WCHAR));
if (!ValueData.Buffer) if (!lpValueBuffer)
{ {
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
} }
else else
{ {
ValueData.Buffer = NULL; lpValueBuffer = NULL;
ValueData.Length = 0;
ValueData.MaximumLength = 0;
if (lpcbData) if (lpcbData)
*lpcbData = 0; *lpcbData = 0;
} }
RtlCreateUnicodeStringFromAsciiz(&ValueName, if(!RtlCreateUnicodeStringFromAsciiz(&ValueName,
(LPSTR)lpValueName); (LPSTR)lpValueName))
{
ERR("RtlCreateUnicodeStringFromAsciiz failed!\n");
ErrorCode = ERROR_OUTOFMEMORY;
goto cleanup;
}
Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
ErrorCode = RegQueryValueExW(hKey, ErrorCode = RegQueryValueExW(hKey,
ValueName.Buffer, ValueName.Buffer,
lpReserved, lpReserved,
&Type, &Type,
(lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer, (LPBYTE)lpValueBuffer,
&Length); &Length);
TRACE("ErrorCode %lu\n", ErrorCode); TRACE("ErrorCode %lu\n", ErrorCode);
RtlFreeUnicodeString(&ValueName); RtlFreeUnicodeString(&ValueName);
if (ErrorCode == ERROR_SUCCESS || if (ErrorCode == ERROR_SUCCESS ||
@ -4044,9 +4047,9 @@ RegQueryValueExA(HKEY hKey,
if (is_string(Type)) if (is_string(Type))
{ {
if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL) if (ErrorCode == ERROR_SUCCESS && lpValueBuffer != NULL)
{ {
Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)ValueData.Buffer, Length); Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)lpValueBuffer, Length);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
PCHAR szData = (PCHAR)lpData; PCHAR szData = (PCHAR)lpData;
@ -4063,7 +4066,7 @@ RegQueryValueExA(HKEY hKey,
Length = Length / sizeof(WCHAR); Length = Length / sizeof(WCHAR);
} }
else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL) else if (ErrorCode == ERROR_SUCCESS && lpValueBuffer != NULL)
{ {
if (*lpcbData < Length) if (*lpcbData < Length)
{ {
@ -4071,7 +4074,7 @@ RegQueryValueExA(HKEY hKey,
} }
else else
{ {
RtlMoveMemory(lpData, ValueData.Buffer, Length); RtlMoveMemory(lpData, lpValueBuffer, Length);
} }
} }
@ -4086,9 +4089,10 @@ RegQueryValueExA(HKEY hKey,
*lpType = Type; *lpType = Type;
} }
if (ValueData.Buffer != NULL) cleanup:
if (lpValueBuffer != NULL)
{ {
RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer); RtlFreeHeap(ProcessHeap, 0, lpValueBuffer);
} }
return ErrorCode; return ErrorCode;