api: tighten maximum registry key path length

Maximum registry key path length is not 260 (MAX_PATH), but 255 (256
incl. zero terminator).

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2020-07-24 08:10:00 +02:00 committed by Jason A. Donenfeld
parent 43a1751b21
commit 28c135b8e1
3 changed files with 19 additions and 15 deletions

View File

@ -38,16 +38,20 @@ NciInit();
void void
NciCleanup(); NciCleanup();
#define MAX_REG_PATH \
256 /* Maximum registry path length \
https://support.microsoft.com/en-us/help/256986/windows-registry-information-for-advanced-users */
WINTUN_STATUS WINTUN_STATUS
RegistryOpenKeyWait( RegistryOpenKeyWait(
_In_ HKEY Key, _In_ HKEY Key,
_In_z_count_c_(MAX_PATH) const WCHAR *Path, _In_z_count_c_(MAX_REG_PATH) const WCHAR *Path,
_In_ DWORD Access, _In_ DWORD Access,
_In_ DWORD Timeout, _In_ DWORD Timeout,
_Out_ HKEY *KeyOut); _Out_ HKEY *KeyOut);
WINTUN_STATUS WINTUN_STATUS
RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) const WCHAR *Path, _In_ DWORD Timeout); RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_REG_PATH) const WCHAR *Path, _In_ DWORD Timeout);
WINTUN_STATUS WINTUN_STATUS
RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType); RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType);

View File

@ -510,11 +510,11 @@ cleanupKey:
* Returns the device-level registry key path. * Returns the device-level registry key path.
*/ */
static void static void
GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH + MAX_INSTANCE_ID) WCHAR *Path) GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_REG_PATH) WCHAR *Path)
{ {
_snwprintf_s( _snwprintf_s(
Path, Path,
MAX_PATH + MAX_INSTANCE_ID, MAX_REG_PATH,
_TRUNCATE, _TRUNCATE,
L"SYSTEM\\CurrentControlSet\\Enum\\%.*s", L"SYSTEM\\CurrentControlSet\\Enum\\%.*s",
MAX_INSTANCE_ID, MAX_INSTANCE_ID,
@ -525,12 +525,12 @@ GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH + MAX_
* Returns the adapter-specific TCP/IP network registry key path. * Returns the adapter-specific TCP/IP network registry key path.
*/ */
static void static void
GetTcpipAdapterRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH) WCHAR *Path) GetTcpipAdapterRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_REG_PATH) WCHAR *Path)
{ {
WCHAR Guid[MAX_GUID_STRING_LEN]; WCHAR Guid[MAX_GUID_STRING_LEN];
_snwprintf_s( _snwprintf_s(
Path, Path,
MAX_PATH, MAX_REG_PATH,
_TRUNCATE, _TRUNCATE,
L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\%.*s", L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\%.*s",
StringFromGUID2(&Adapter->CfgInstanceID, Guid, _countof(Guid)), StringFromGUID2(&Adapter->CfgInstanceID, Guid, _countof(Guid)),
@ -541,11 +541,11 @@ GetTcpipAdapterRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH)
* Returns the interface-specific TCP/IP network registry key path. * Returns the interface-specific TCP/IP network registry key path.
*/ */
static WINTUN_STATUS static WINTUN_STATUS
GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH) WCHAR *Path) GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_REG_PATH) WCHAR *Path)
{ {
DWORD Result; DWORD Result;
HKEY TcpipAdapterRegKey; HKEY TcpipAdapterRegKey;
WCHAR TcpipAdapterRegPath[MAX_PATH]; WCHAR TcpipAdapterRegPath[MAX_REG_PATH];
GetTcpipAdapterRegPath(Adapter, TcpipAdapterRegPath); GetTcpipAdapterRegPath(Adapter, TcpipAdapterRegPath);
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TcpipAdapterRegPath, 0, KEY_QUERY_VALUE, &TcpipAdapterRegKey); Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TcpipAdapterRegPath, 0, KEY_QUERY_VALUE, &TcpipAdapterRegKey);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
@ -559,7 +559,7 @@ GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PAT
Result = ERROR_NETWORK_NOT_AVAILABLE; Result = ERROR_NETWORK_NOT_AVAILABLE;
goto cleanupPaths; goto cleanupPaths;
} }
_snwprintf_s(Path, MAX_PATH, _TRUNCATE, L"SYSTEM\\CurrentControlSet\\Services\\%s", Paths); _snwprintf_s(Path, MAX_REG_PATH, _TRUNCATE, L"SYSTEM\\CurrentControlSet\\Services\\%s", Paths);
cleanupPaths: cleanupPaths:
HeapFree(GetProcessHeap(), 0, Paths); HeapFree(GetProcessHeap(), 0, Paths);
cleanupTcpipAdapterRegKey: cleanupTcpipAdapterRegKey:
@ -743,7 +743,7 @@ WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAP
/* TODO: This should use NetSetup2 so that it doesn't get unset. */ /* TODO: This should use NetSetup2 so that it doesn't get unset. */
HKEY DeviceRegKey; HKEY DeviceRegKey;
WCHAR DeviceRegPath[MAX_PATH + MAX_INSTANCE_ID]; WCHAR DeviceRegPath[MAX_REG_PATH];
GetDeviceRegPath(Adapter, DeviceRegPath); GetDeviceRegPath(Adapter, DeviceRegPath);
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DeviceRegPath, 0, KEY_SET_VALUE, &DeviceRegKey); Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DeviceRegPath, 0, KEY_SET_VALUE, &DeviceRegKey);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
@ -1056,7 +1056,7 @@ WintunCreateAdapter(
goto cleanupNetDevRegKey; goto cleanupNetDevRegKey;
HKEY TcpipAdapterRegKey; HKEY TcpipAdapterRegKey;
WCHAR TcpipAdapterRegPath[MAX_PATH]; WCHAR TcpipAdapterRegPath[MAX_REG_PATH];
GetTcpipAdapterRegPath(*Adapter, TcpipAdapterRegPath); GetTcpipAdapterRegPath(*Adapter, TcpipAdapterRegPath);
Result = RegistryOpenKeyWait( Result = RegistryOpenKeyWait(
HKEY_LOCAL_MACHINE, HKEY_LOCAL_MACHINE,
@ -1072,7 +1072,7 @@ WintunCreateAdapter(
HeapFree(Heap, 0, DummyStr); HeapFree(Heap, 0, DummyStr);
HKEY TcpipInterfaceRegKey; HKEY TcpipInterfaceRegKey;
WCHAR TcpipInterfaceRegPath[MAX_PATH]; WCHAR TcpipInterfaceRegPath[MAX_REG_PATH];
Result = GetTcpipInterfaceRegPath(*Adapter, TcpipInterfaceRegPath); Result = GetTcpipInterfaceRegPath(*Adapter, TcpipInterfaceRegPath);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
goto cleanupTcpipAdapterRegKey; goto cleanupTcpipAdapterRegKey;

View File

@ -66,18 +66,18 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGL
WINTUN_STATUS WINTUN_STATUS
RegistryOpenKeyWait( RegistryOpenKeyWait(
_In_ HKEY Key, _In_ HKEY Key,
_In_z_count_c_(MAX_PATH) const WCHAR *Path, _In_z_count_c_(MAX_REG_PATH) const WCHAR *Path,
_In_ DWORD Access, _In_ DWORD Access,
_In_ DWORD Timeout, _In_ DWORD Timeout,
_Out_ HKEY *KeyOut) _Out_ HKEY *KeyOut)
{ {
WCHAR Buf[MAX_PATH]; WCHAR Buf[MAX_REG_PATH];
wcscpy_s(Buf, _countof(Buf), Path); wcscpy_s(Buf, _countof(Buf), Path);
return OpenKeyWait(Key, Buf, Access, GetTickCount64() + Timeout, KeyOut); return OpenKeyWait(Key, Buf, Access, GetTickCount64() + Timeout, KeyOut);
} }
WINTUN_STATUS WINTUN_STATUS
RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) const WCHAR *Path, _In_ DWORD Timeout) RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_REG_PATH) const WCHAR *Path, _In_ DWORD Timeout)
{ {
HKEY k; HKEY k;
DWORD Result = RegistryOpenKeyWait(Key, Path, KEY_NOTIFY, Timeout, &k); DWORD Result = RegistryOpenKeyWait(Key, Path, KEY_NOTIFY, Timeout, &k);