[winpr,registry] limit REG_SZ value length

Add a (sensible) upper limit for entries and add a warning should some
value be truncated
This commit is contained in:
akallabeth
2025-03-13 11:59:20 +01:00
parent 264e8e8ab2
commit da049b2f96

View File

@@ -35,6 +35,7 @@
#include <winpr/crt.h>
#include <winpr/assert.h>
#include <winpr/string.h>
#include "registry_reg.h"
@@ -43,6 +44,24 @@
static Reg* instance = NULL;
static size_t regsz_length(const char* key, const void* value, bool unicode)
{
/* https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-element-size-limits
*
* while not strictly limited to this size larger values should be stored to a
* file.
*/
const size_t limit = 16383;
size_t length = 0;
if (unicode)
length = _wcsnlen((const WCHAR*)value, limit);
else
length = strnlen((const char*)value, limit);
if (length >= limit)
WLog_WARN(TAG, "REG_SZ[%s] truncated to size %" PRIuz, key, length);
return length;
}
static Reg* RegGetInstance(void)
{
if (!instance)
@@ -436,7 +455,8 @@ LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWOR
goto end;
case REG_SZ:
{
const size_t length = strnlen(pValue->data.string, UINT32_MAX) * sizeof(WCHAR);
const size_t length =
regsz_length(pValue->name, pValue->data.string, TRUE) * sizeof(WCHAR);
status = ERROR_SUCCESS;
if (lpData != NULL)
@@ -508,7 +528,8 @@ LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD
return reg_read_int(pValue, lpData, lpcbData);
case REG_SZ:
{
const size_t length = strnlen(pValue->data.string, UINT32_MAX);
const size_t length = regsz_length(pValue->name, pValue->data.string, FALSE);
char* pData = (char*)lpData;
if (pData != NULL)