Commit c1dddbea authored by Alexandre Julliard's avatar Alexandre Julliard

RegEnumValue[AW] need to update the data size on buffer overflow

(spotted by Massimo <max@veneto.com>).
parent 1d8f92c8
...@@ -1076,7 +1076,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_co ...@@ -1076,7 +1076,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_co
if (info->NameLength/sizeof(WCHAR) >= *val_count) if (info->NameLength/sizeof(WCHAR) >= *val_count)
{ {
status = STATUS_BUFFER_OVERFLOW; status = STATUS_BUFFER_OVERFLOW;
goto done; goto overflow;
} }
memcpy( value, info->Name, info->NameLength ); memcpy( value, info->Name, info->NameLength );
*val_count = info->NameLength / sizeof(WCHAR); *val_count = info->NameLength / sizeof(WCHAR);
...@@ -1088,7 +1088,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_co ...@@ -1088,7 +1088,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_co
if (total_size - info->DataOffset > *count) if (total_size - info->DataOffset > *count)
{ {
status = STATUS_BUFFER_OVERFLOW; status = STATUS_BUFFER_OVERFLOW;
goto done; goto overflow;
} }
memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset ); memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type)) if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type))
...@@ -1102,6 +1102,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_co ...@@ -1102,6 +1102,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_co
} }
else status = STATUS_SUCCESS; else status = STATUS_SUCCESS;
overflow:
if (type) *type = info->Type; if (type) *type = info->Type;
if (count) *count = info->DataLength; if (count) *count = info->DataLength;
...@@ -1154,21 +1155,6 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou ...@@ -1154,21 +1155,6 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou
if (status) goto done; if (status) goto done;
if (value)
{
DWORD len;
RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
if (len >= *val_count)
{
status = STATUS_BUFFER_OVERFLOW;
goto done;
}
RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
value[len] = 0;
*val_count = len;
}
if (is_string(info->Type)) if (is_string(info->Type))
{ {
DWORD len; DWORD len;
...@@ -1176,17 +1162,16 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou ...@@ -1176,17 +1162,16 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou
total_size - info->DataOffset ); total_size - info->DataOffset );
if (data && len) if (data && len)
{ {
if (len > *count) if (len > *count) status = STATUS_BUFFER_OVERFLOW;
else
{ {
status = STATUS_BUFFER_OVERFLOW;
goto done;
}
RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset), RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
total_size - info->DataOffset ); total_size - info->DataOffset );
/* if the type is REG_SZ and data is not 0-terminated /* if the type is REG_SZ and data is not 0-terminated
* and there is enough space in the buffer NT appends a \0 */ * and there is enough space in the buffer NT appends a \0 */
if (len < *count && data[len-1]) data[len] = 0; if (len < *count && data[len-1]) data[len] = 0;
} }
}
info->DataLength = len; info->DataLength = len;
} }
else if (data) else if (data)
...@@ -1194,6 +1179,29 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou ...@@ -1194,6 +1179,29 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou
if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW; if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW;
else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset ); else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
} }
if (value && !status)
{
DWORD len;
RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
if (len >= *val_count)
{
status = STATUS_BUFFER_OVERFLOW;
if (*val_count)
{
len = *val_count - 1;
RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
value[len] = 0;
}
}
else
{
RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
value[len] = 0;
*val_count = len;
}
}
} }
else status = STATUS_SUCCESS; else status = STATUS_SUCCESS;
......
...@@ -533,21 +533,6 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou ...@@ -533,21 +533,6 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou
if (status) goto done; if (status) goto done;
if (value)
{
DWORD len;
RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
if (len >= *val_count)
{
status = STATUS_BUFFER_OVERFLOW;
goto done;
}
RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
value[len] = 0;
*val_count = len;
}
if (is_string(info->Type)) if (is_string(info->Type))
{ {
DWORD len; DWORD len;
...@@ -555,17 +540,16 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou ...@@ -555,17 +540,16 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou
total_size - info->DataOffset ); total_size - info->DataOffset );
if (data && len) if (data && len)
{ {
if (len > *count) if (len > *count) status = STATUS_BUFFER_OVERFLOW;
else
{ {
status = STATUS_BUFFER_OVERFLOW;
goto done;
}
RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset), RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
total_size - info->DataOffset ); total_size - info->DataOffset );
/* if the type is REG_SZ and data is not 0-terminated /* if the type is REG_SZ and data is not 0-terminated
* and there is enough space in the buffer NT appends a \0 */ * and there is enough space in the buffer NT appends a \0 */
if (len < *count && data[len-1]) data[len] = 0; if (len < *count && data[len-1]) data[len] = 0;
} }
}
info->DataLength = len; info->DataLength = len;
} }
else if (data) else if (data)
...@@ -573,6 +557,29 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou ...@@ -573,6 +557,29 @@ DWORD WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_cou
if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW; if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW;
else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset ); else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
} }
if (value && !status)
{
DWORD len;
RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
if (len >= *val_count)
{
status = STATUS_BUFFER_OVERFLOW;
if (*val_count)
{
len = *val_count - 1;
RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
value[len] = 0;
}
}
else
{
RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
value[len] = 0;
*val_count = len;
}
}
} }
else status = STATUS_SUCCESS; else status = STATUS_SUCCESS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment