api: switch to private heap

We must not use the process heap, as it is changeable. Client may change
it causing our HeapFree() to use wrong heap.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2020-10-24 22:12:47 +02:00 committed by Jason A. Donenfeld
parent 4b8f879fd6
commit bf4eabb4ca
9 changed files with 68 additions and 84 deletions

View File

@ -31,18 +31,17 @@ AdapterGetDrvInfoDetail(
_In_ SP_DRVINFO_DATA_W *DrvInfoData, _In_ SP_DRVINFO_DATA_W *DrvInfoData,
_Out_ SP_DRVINFO_DETAIL_DATA_W **DrvInfoDetailData) _Out_ SP_DRVINFO_DETAIL_DATA_W **DrvInfoDetailData)
{ {
HANDLE Heap = GetProcessHeap();
DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100; DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100;
for (;;) for (;;)
{ {
*DrvInfoDetailData = HeapAlloc(Heap, 0, Size); *DrvInfoDetailData = HeapAlloc(ModuleHeap, 0, Size);
if (!*DrvInfoDetailData) if (!*DrvInfoDetailData)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
(*DrvInfoDetailData)->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); (*DrvInfoDetailData)->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, *DrvInfoDetailData, Size, &Size)) if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, *DrvInfoDetailData, Size, &Size))
return ERROR_SUCCESS; return ERROR_SUCCESS;
DWORD Result = GetLastError(); DWORD Result = GetLastError();
HeapFree(Heap, 0, *DrvInfoDetailData); HeapFree(ModuleHeap, 0, *DrvInfoDetailData);
if (Result != ERROR_INSUFFICIENT_BUFFER) if (Result != ERROR_INSUFFICIENT_BUFFER)
return LOG_ERROR(L"Failed", Result); return LOG_ERROR(L"Failed", Result);
} }
@ -57,16 +56,15 @@ GetDeviceRegistryProperty(
_Out_ void **Buf, _Out_ void **Buf,
_Inout_ DWORD *BufLen) _Inout_ DWORD *BufLen)
{ {
HANDLE Heap = GetProcessHeap();
for (;;) for (;;)
{ {
*Buf = HeapAlloc(Heap, 0, *BufLen); *Buf = HeapAlloc(ModuleHeap, 0, *BufLen);
if (!*Buf) if (!*Buf)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
if (SetupDiGetDeviceRegistryPropertyW(DevInfo, DevInfoData, Property, ValueType, *Buf, *BufLen, BufLen)) if (SetupDiGetDeviceRegistryPropertyW(DevInfo, DevInfoData, Property, ValueType, *Buf, *BufLen, BufLen))
return ERROR_SUCCESS; return ERROR_SUCCESS;
DWORD Result = GetLastError(); DWORD Result = GetLastError();
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
if (Result != ERROR_INSUFFICIENT_BUFFER) if (Result != ERROR_INSUFFICIENT_BUFFER)
return LOG_ERROR(L"Querying property failed", Result); return LOG_ERROR(L"Querying property failed", Result);
} }
@ -90,11 +88,11 @@ GetDeviceRegistryString(
case REG_MULTI_SZ: case REG_MULTI_SZ:
Result = RegistryGetString(Buf, Size / sizeof(WCHAR), ValueType); Result = RegistryGetString(Buf, Size / sizeof(WCHAR), ValueType);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
HeapFree(GetProcessHeap(), 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
return Result; return Result;
default: default:
LOG(WINTUN_LOG_ERR, L"Property is not a string"); LOG(WINTUN_LOG_ERR, L"Property is not a string");
HeapFree(GetProcessHeap(), 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
return ERROR_INVALID_DATATYPE; return ERROR_INVALID_DATATYPE;
} }
} }
@ -117,11 +115,11 @@ GetDeviceRegistryMultiString(
case REG_MULTI_SZ: case REG_MULTI_SZ:
Result = RegistryGetMultiString(Buf, Size / sizeof(WCHAR), ValueType); Result = RegistryGetMultiString(Buf, Size / sizeof(WCHAR), ValueType);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
HeapFree(GetProcessHeap(), 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
return Result; return Result;
default: default:
LOG(WINTUN_LOG_ERR, L"Property is not a string"); LOG(WINTUN_LOG_ERR, L"Property is not a string");
HeapFree(GetProcessHeap(), 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
return ERROR_INVALID_DATATYPE; return ERROR_INVALID_DATATYPE;
} }
} }
@ -140,7 +138,6 @@ IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOO
static WINTUN_STATUS static WINTUN_STATUS
GetDeviceObject(_In_opt_z_ const WCHAR *InstanceId, _Out_ HANDLE *Handle) GetDeviceObject(_In_opt_z_ const WCHAR *InstanceId, _Out_ HANDLE *Handle)
{ {
HANDLE Heap = GetProcessHeap();
ULONG InterfacesLen; ULONG InterfacesLen;
DWORD Result = CM_Get_Device_Interface_List_SizeW( DWORD Result = CM_Get_Device_Interface_List_SizeW(
&InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT); &InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
@ -149,7 +146,7 @@ GetDeviceObject(_In_opt_z_ const WCHAR *InstanceId, _Out_ HANDLE *Handle)
LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances size"); LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances size");
return ERROR_GEN_FAILURE; return ERROR_GEN_FAILURE;
} }
WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR)); WCHAR *Interfaces = HeapAlloc(ModuleHeap, 0, InterfacesLen * sizeof(WCHAR));
if (!Interfaces) if (!Interfaces)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
Result = CM_Get_Device_Interface_ListW( Result = CM_Get_Device_Interface_ListW(
@ -174,7 +171,7 @@ GetDeviceObject(_In_opt_z_ const WCHAR *InstanceId, _Out_ HANDLE *Handle)
NULL); NULL);
Result = *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : LOG_LAST_ERROR(L"Failed to connect to device"); Result = *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : LOG_LAST_ERROR(L"Failed to connect to device");
cleanupBuf: cleanupBuf:
HeapFree(Heap, 0, Interfaces); HeapFree(ModuleHeap, 0, Interfaces);
return Result; return Result;
} }
@ -188,8 +185,7 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevIn
if (SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, NULL, 0, &RequiredBytes) || if (SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, NULL, 0, &RequiredBytes) ||
(Result = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) (Result = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
return LOG_ERROR(L"Failed to query device instance ID size", Result); return LOG_ERROR(L"Failed to query device instance ID size", Result);
HANDLE Heap = GetProcessHeap(); WCHAR *InstanceId = HeapAlloc(ModuleHeap, HEAP_ZERO_MEMORY, sizeof(*InstanceId) * RequiredBytes);
WCHAR *InstanceId = HeapAlloc(Heap, HEAP_ZERO_MEMORY, sizeof(*InstanceId) * RequiredBytes);
if (!InstanceId) if (!InstanceId)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, RequiredBytes, &RequiredBytes)) if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, RequiredBytes, &RequiredBytes))
@ -209,7 +205,7 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevIn
: LOG_LAST_ERROR(L"Failed to perform ioctl"); : LOG_LAST_ERROR(L"Failed to perform ioctl");
CloseHandle(NdisHandle); CloseHandle(NdisHandle);
out: out:
HeapFree(Heap, 0, InstanceId); HeapFree(ModuleHeap, 0, InstanceId);
return Result; return Result;
} }
@ -221,10 +217,9 @@ AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **Disa
.StateChange = DICS_DISABLE, .StateChange = DICS_DISABLE,
.Scope = DICS_FLAG_GLOBAL }; .Scope = DICS_FLAG_GLOBAL };
DWORD Result = ERROR_SUCCESS; DWORD Result = ERROR_SUCCESS;
HANDLE Heap = GetProcessHeap();
for (DWORD EnumIndex = 0;; ++EnumIndex) for (DWORD EnumIndex = 0;; ++EnumIndex)
{ {
SP_DEVINFO_DATA_LIST *DeviceNode = HeapAlloc(Heap, 0, sizeof(SP_DEVINFO_DATA_LIST)); SP_DEVINFO_DATA_LIST *DeviceNode = HeapAlloc(ModuleHeap, 0, sizeof(SP_DEVINFO_DATA_LIST));
if (!DeviceNode) if (!DeviceNode)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA); DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA);
@ -232,7 +227,7 @@ AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **Disa
{ {
if (GetLastError() == ERROR_NO_MORE_ITEMS) if (GetLastError() == ERROR_NO_MORE_ITEMS)
{ {
HeapFree(Heap, 0, DeviceNode); HeapFree(ModuleHeap, 0, DeviceNode);
break; break;
} }
goto cleanupDeviceInfoData; goto cleanupDeviceInfoData;
@ -265,7 +260,7 @@ AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **Disa
continue; continue;
cleanupDeviceInfoData: cleanupDeviceInfoData:
HeapFree(Heap, 0, &DeviceNode->Data); HeapFree(ModuleHeap, 0, &DeviceNode->Data);
} }
return Result; return Result;
} }
@ -404,7 +399,7 @@ GetNetCfgInstanceId(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _O
} }
else else
Result = ERROR_SUCCESS; Result = ERROR_SUCCESS;
HeapFree(GetProcessHeap(), 0, ValueStr); HeapFree(ModuleHeap, 0, ValueStr);
cleanupKey: cleanupKey:
RegCloseKey(Key); RegCloseKey(Key);
return Result; return Result;
@ -471,7 +466,6 @@ IsPoolMember(
_In_ SP_DEVINFO_DATA *DevInfoData, _In_ SP_DEVINFO_DATA *DevInfoData,
_Out_ BOOL *IsMember) _Out_ BOOL *IsMember)
{ {
HANDLE Heap = GetProcessHeap();
WCHAR *DeviceDesc, *FriendlyName; WCHAR *DeviceDesc, *FriendlyName;
DWORD Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_DEVICEDESC, &DeviceDesc); DWORD Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_DEVICEDESC, &DeviceDesc);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
@ -501,9 +495,9 @@ IsPoolMember(
} }
*IsMember = FALSE; *IsMember = FALSE;
cleanupFriendlyName: cleanupFriendlyName:
HeapFree(Heap, 0, FriendlyName); HeapFree(ModuleHeap, 0, FriendlyName);
cleanupDeviceDesc: cleanupDeviceDesc:
HeapFree(Heap, 0, DeviceDesc); HeapFree(ModuleHeap, 0, DeviceDesc);
return Result; return Result;
} }
@ -521,8 +515,7 @@ CreateAdapterData(
if (Key == INVALID_HANDLE_VALUE) if (Key == INVALID_HANDLE_VALUE)
return LOG_LAST_ERROR(L"Opening device registry key failed"); return LOG_LAST_ERROR(L"Opening device registry key failed");
HANDLE Heap = GetProcessHeap(); *Adapter = HeapAlloc(ModuleHeap, 0, sizeof(WINTUN_ADAPTER));
*Adapter = HeapAlloc(Heap, 0, sizeof(WINTUN_ADAPTER));
if (!*Adapter) if (!*Adapter)
{ {
LOG(WINTUN_LOG_ERR, L"Out of memory"); LOG(WINTUN_LOG_ERR, L"Out of memory");
@ -541,11 +534,11 @@ CreateAdapterData(
if (FAILED(CLSIDFromString(ValueStr, &(*Adapter)->CfgInstanceID))) if (FAILED(CLSIDFromString(ValueStr, &(*Adapter)->CfgInstanceID)))
{ {
LOG(WINTUN_LOG_ERR, L"NetCfgInstanceId is not a GUID"); LOG(WINTUN_LOG_ERR, L"NetCfgInstanceId is not a GUID");
HeapFree(Heap, 0, ValueStr); HeapFree(ModuleHeap, 0, ValueStr);
Result = ERROR_INVALID_DATA; Result = ERROR_INVALID_DATA;
goto cleanupAdapter; goto cleanupAdapter;
} }
HeapFree(Heap, 0, ValueStr); HeapFree(ModuleHeap, 0, ValueStr);
/* Read the NetLuidIndex value. */ /* Read the NetLuidIndex value. */
Result = RegistryQueryDWORD(Key, L"NetLuidIndex", &(*Adapter)->LuidIndex); Result = RegistryQueryDWORD(Key, L"NetLuidIndex", &(*Adapter)->LuidIndex);
@ -576,7 +569,7 @@ CreateAdapterData(
cleanupAdapter: cleanupAdapter:
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
HeapFree(Heap, 0, *Adapter); HeapFree(ModuleHeap, 0, *Adapter);
cleanupKey: cleanupKey:
RegCloseKey(Key); RegCloseKey(Key);
return Result; return Result;
@ -597,7 +590,7 @@ GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_REG_PATH) W
void WINAPI void WINAPI
WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter) WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter)
{ {
HeapFree(GetProcessHeap(), 0, Adapter); HeapFree(ModuleHeap, 0, Adapter);
} }
WINTUN_STATUS WINAPI WINTUN_STATUS WINAPI
@ -942,7 +935,7 @@ GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_REG
} }
_snwprintf_s(Path, MAX_REG_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(ModuleHeap, 0, Paths);
cleanupTcpipAdapterRegKey: cleanupTcpipAdapterRegKey:
RegCloseKey(TcpipAdapterRegKey); RegCloseKey(TcpipAdapterRegKey);
return Result; return Result;
@ -976,7 +969,6 @@ CreateAdapter(
goto cleanupDevInfo; goto cleanupDevInfo;
} }
HANDLE Heap = GetProcessHeap();
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE]; WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName); GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) }; SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
@ -1043,10 +1035,10 @@ CreateAdapter(
} }
if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
{ {
HeapFree(Heap, 0, DrvInfoDetailData); HeapFree(ModuleHeap, 0, DrvInfoDetailData);
continue; continue;
} }
HeapFree(Heap, 0, DrvInfoDetailData); HeapFree(ModuleHeap, 0, DrvInfoDetailData);
if (!SetupDiSetSelectedDriverW(DevInfo, &DevInfoData, &DrvInfoData)) if (!SetupDiSetSelectedDriverW(DevInfo, &DevInfoData, &DrvInfoData))
continue; continue;
@ -1131,7 +1123,7 @@ CreateAdapter(
LOG(WINTUN_LOG_ERR, L"Failed to query NetCfgInstanceId value"); LOG(WINTUN_LOG_ERR, L"Failed to query NetCfgInstanceId value");
goto cleanupNetDevRegKey; goto cleanupNetDevRegKey;
} }
HeapFree(Heap, 0, DummyStr); HeapFree(ModuleHeap, 0, DummyStr);
DWORD DummyDWORD; DWORD DummyDWORD;
Result = RegistryQueryDWORDWait(NetDevRegKey, L"NetLuidIndex", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD); Result = RegistryQueryDWORDWait(NetDevRegKey, L"NetLuidIndex", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
@ -1173,7 +1165,7 @@ CreateAdapter(
LOG(WINTUN_LOG_ERR, L"Failed to query IpConfig value"); LOG(WINTUN_LOG_ERR, L"Failed to query IpConfig value");
goto cleanupTcpipAdapterRegKey; goto cleanupTcpipAdapterRegKey;
} }
HeapFree(Heap, 0, DummyStr); HeapFree(ModuleHeap, 0, DummyStr);
HKEY TcpipInterfaceRegKey; HKEY TcpipInterfaceRegKey;
WCHAR TcpipInterfaceRegPath[MAX_REG_PATH]; WCHAR TcpipInterfaceRegPath[MAX_REG_PATH];
@ -1209,7 +1201,7 @@ cleanupTcpipAdapterRegKey:
RegCloseKey(TcpipAdapterRegKey); RegCloseKey(TcpipAdapterRegKey);
cleanupAdapter: cleanupAdapter:
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
HeapFree(Heap, 0, *Adapter); HeapFree(ModuleHeap, 0, *Adapter);
cleanupNetDevRegKey: cleanupNetDevRegKey:
RegCloseKey(NetDevRegKey); RegCloseKey(NetDevRegKey);
cleanupDevice: cleanupDevice:
@ -1365,9 +1357,8 @@ ExecuteRunDll32(
LOG(WINTUN_LOG_ERR, L"Failed to copy resource"); LOG(WINTUN_LOG_ERR, L"Failed to copy resource");
goto cleanupDelete; goto cleanupDelete;
} }
HANDLE Heap = GetProcessHeap();
size_t CommandLineLen = 10 + MAX_PATH + 2 + wcslen(Arguments) + 1; size_t CommandLineLen = 10 + MAX_PATH + 2 + wcslen(Arguments) + 1;
WCHAR *CommandLine = HeapAlloc(Heap, 0, CommandLineLen * sizeof(WCHAR)); WCHAR *CommandLine = HeapAlloc(ModuleHeap, 0, CommandLineLen * sizeof(WCHAR));
if (!CommandLine) if (!CommandLine)
{ {
LOG(WINTUN_LOG_ERR, L"Out of memory"); LOG(WINTUN_LOG_ERR, L"Out of memory");
@ -1438,7 +1429,7 @@ cleanupPipes:
CloseHandle(StreamW[Stderr]); CloseHandle(StreamW[Stderr]);
CloseHandle(StreamR[Stdout]); CloseHandle(StreamR[Stdout]);
CloseHandle(StreamW[Stdout]); CloseHandle(StreamW[Stdout]);
HeapFree(Heap, 0, CommandLine); HeapFree(ModuleHeap, 0, CommandLine);
cleanupDelete: cleanupDelete:
DeleteFileW(DllPath); DeleteFileW(DllPath);
cleanupDirectory: cleanupDirectory:
@ -1651,7 +1642,6 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_
Result = LOG_LAST_ERROR(L"Failed to get present class devices"); Result = LOG_LAST_ERROR(L"Failed to get present class devices");
goto cleanupMutex; goto cleanupMutex;
} }
HANDLE Heap = GetProcessHeap();
BOOL Continue = TRUE; BOOL Continue = TRUE;
for (DWORD EnumIndex = 0; Continue; ++EnumIndex) for (DWORD EnumIndex = 0; Continue; ++EnumIndex)
{ {
@ -1685,7 +1675,7 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_
break; break;
} }
Continue = Func(Adapter, Param); Continue = Func(Adapter, Param);
HeapFree(Heap, 0, Adapter); HeapFree(ModuleHeap, 0, Adapter);
} }
SetupDiDestroyDeviceInfoList(DevInfo); SetupDiDestroyDeviceInfoList(DevInfo);
cleanupMutex: cleanupMutex:

View File

@ -29,7 +29,7 @@ typedef struct _SP_DEVINFO_DATA_LIST
* driver for which to retrieve details. * driver for which to retrieve details.
* *
* @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver. * @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver.
* Must be released with HeapFree(GetProcessHeap(), 0, *DrvInfoDetailData) after use. * Must be released with HeapFree(ModuleHeap, 0, *DrvInfoDetailData) after use.
* *
* @return ERROR_SUCCESS on success; Win32 error code otherwise. * @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/ */

View File

@ -6,8 +6,9 @@
#include "pch.h" #include "pch.h"
HINSTANCE ResourceModule; HINSTANCE ResourceModule;
HANDLE ModuleHeap;
static SECURITY_ATTRIBUTES SecurityAttributesSystem = { .nLength = sizeof(SECURITY_ATTRIBUTES) }; static SECURITY_ATTRIBUTES SecurityAttributesSystem = { .nLength = sizeof(SECURITY_ATTRIBUTES) };
SECURITY_ATTRIBUTES *SecurityAttributes = NULL; SECURITY_ATTRIBUTES *SecurityAttributes;
WINTUN_STATUS WINAPI WINTUN_STATUS WINAPI
WintunGetVersion( WintunGetVersion(
@ -56,6 +57,7 @@ DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
ResourceModule = hinstDLL; ResourceModule = hinstDLL;
ModuleHeap = HeapCreate(0, 0, 0);
#ifndef _DEBUG #ifndef _DEBUG
ConvertStringSecurityDescriptorToSecurityDescriptorW( ConvertStringSecurityDescriptorToSecurityDescriptorW(
L"O:SYD:P(A;;GA;;;SY)", SDDL_REVISION_1, &SecurityAttributesSystem.lpSecurityDescriptor, NULL); L"O:SYD:P(A;;GA;;;SY)", SDDL_REVISION_1, &SecurityAttributesSystem.lpSecurityDescriptor, NULL);
@ -73,6 +75,7 @@ DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved)
#ifndef _DEBUG #ifndef _DEBUG
LocalFree(SecurityAttributesSystem.lpSecurityDescriptor); LocalFree(SecurityAttributesSystem.lpSecurityDescriptor);
#endif #endif
HeapDestroy(ModuleHeap);
break; break;
} }
return TRUE; return TRUE;

View File

@ -15,4 +15,5 @@
#endif #endif
extern HINSTANCE ResourceModule; extern HINSTANCE ResourceModule;
extern HANDLE ModuleHeap;
extern SECURITY_ATTRIBUTES *SecurityAttributes; extern SECURITY_ATTRIBUTES *SecurityAttributes;

View File

@ -38,7 +38,6 @@ DriverRemoveAllOurs(void)
Result = LOG_LAST_ERROR(L"Failed to build list of drivers"); Result = LOG_LAST_ERROR(L"Failed to build list of drivers");
goto cleanupDeviceInfoSet; goto cleanupDeviceInfoSet;
} }
HANDLE Heap = GetProcessHeap();
for (DWORD EnumIndex = 0;; ++EnumIndex) for (DWORD EnumIndex = 0;; ++EnumIndex)
{ {
SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(DrvInfoData) }; SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(DrvInfoData) };
@ -56,7 +55,7 @@ DriverRemoveAllOurs(void)
} }
if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
{ {
HeapFree(Heap, 0, DrvInfoDetailData); HeapFree(ModuleHeap, 0, DrvInfoDetailData);
continue; continue;
} }
PathStripPathW(DrvInfoDetailData->InfFileName); PathStripPathW(DrvInfoDetailData->InfFileName);
@ -66,7 +65,7 @@ DriverRemoveAllOurs(void)
LOG_LAST_ERROR(L"Unable to remove existing driver"); LOG_LAST_ERROR(L"Unable to remove existing driver");
Result = Result != ERROR_SUCCESS ? Result : GetLastError(); Result = Result != ERROR_SUCCESS ? Result : GetLastError();
} }
HeapFree(Heap, 0, DrvInfoDetailData); HeapFree(ModuleHeap, 0, DrvInfoDetailData);
} }
SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER); SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER);
cleanupDeviceInfoSet: cleanupDeviceInfoSet:

View File

@ -12,18 +12,17 @@ static BCRYPT_ALG_HANDLE AlgProvider;
static WCHAR * static WCHAR *
NormalizeStringAlloc(_In_ NORM_FORM NormForm, _In_z_ const WCHAR *Source) NormalizeStringAlloc(_In_ NORM_FORM NormForm, _In_z_ const WCHAR *Source)
{ {
HANDLE Heap = GetProcessHeap();
int Len = NormalizeString(NormForm, Source, -1, NULL, 0); int Len = NormalizeString(NormForm, Source, -1, NULL, 0);
for (;;) for (;;)
{ {
WCHAR *Str = HeapAlloc(Heap, 0, sizeof(WCHAR) * Len); WCHAR *Str = HeapAlloc(ModuleHeap, 0, sizeof(WCHAR) * Len);
if (!Str) if (!Str)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), NULL; return LOG(WINTUN_LOG_ERR, L"Out of memory"), NULL;
Len = NormalizeString(NormForm, Source, -1, Str, Len); Len = NormalizeString(NormForm, Source, -1, Str, Len);
if (Len > 0) if (Len > 0)
return Str; return Str;
DWORD Result = GetLastError(); DWORD Result = GetLastError();
HeapFree(Heap, 0, Str); HeapFree(ModuleHeap, 0, Str);
if (Result != ERROR_INSUFFICIENT_BUFFER) if (Result != ERROR_INSUFFICIENT_BUFFER)
return LOG_ERROR(L"Failed", Result), NULL; return LOG_ERROR(L"Failed", Result), NULL;
Len = -Len; Len = -Len;
@ -152,7 +151,7 @@ NamespaceTakeMutex(_In_z_ const WCHAR *Pool)
CloseHandle(Mutex); CloseHandle(Mutex);
Mutex = NULL; Mutex = NULL;
cleanupPoolNorm: cleanupPoolNorm:
HeapFree(GetProcessHeap(), 0, PoolNorm); HeapFree(ModuleHeap, 0, PoolNorm);
cleanupSha256: cleanupSha256:
BCryptDestroyHash(Sha256); BCryptDestroyHash(Sha256);
return Mutex; return Mutex;

View File

@ -73,17 +73,15 @@ RegistryOpenKeyWait(
WINTUN_STATUS WINTUN_STATUS
RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType) RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
{ {
HANDLE Heap = GetProcessHeap();
if (wcsnlen(*Buf, Len) >= Len) if (wcsnlen(*Buf, Len) >= Len)
{ {
/* String is missing zero-terminator. */ /* String is missing zero-terminator. */
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR)); WCHAR *BufZ = HeapAlloc(ModuleHeap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
if (!BufZ) if (!BufZ)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
wmemcpy(BufZ, *Buf, Len); wmemcpy(BufZ, *Buf, Len);
BufZ[Len] = 0; BufZ[Len] = 0;
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
*Buf = BufZ; *Buf = BufZ;
} }
@ -98,23 +96,23 @@ RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
Len = Len * 2 + 64; Len = Len * 2 + 64;
for (;;) for (;;)
{ {
WCHAR *Expanded = HeapAlloc(Heap, 0, Len * sizeof(WCHAR)); WCHAR *Expanded = HeapAlloc(ModuleHeap, 0, Len * sizeof(WCHAR));
if (!Expanded) if (!Expanded)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
DWORD Result = ExpandEnvironmentStringsW(*Buf, Expanded, Len); DWORD Result = ExpandEnvironmentStringsW(*Buf, Expanded, Len);
if (!Result) if (!Result)
{ {
Result = LOG_LAST_ERROR(L"Failed to expand environment variables"); Result = LOG_LAST_ERROR(L"Failed to expand environment variables");
HeapFree(Heap, 0, Expanded); HeapFree(ModuleHeap, 0, Expanded);
return Result; return Result;
} }
if (Result > Len) if (Result > Len)
{ {
HeapFree(Heap, 0, Expanded); HeapFree(ModuleHeap, 0, Expanded);
Len = Result; Len = Result;
continue; continue;
} }
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
*Buf = Expanded; *Buf = Expanded;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -123,8 +121,6 @@ RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
WINTUN_STATUS WINTUN_STATUS
RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType) RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
{ {
HANDLE Heap = GetProcessHeap();
if (ValueType == REG_MULTI_SZ) if (ValueType == REG_MULTI_SZ)
{ {
for (size_t i = 0;; i += wcsnlen(*Buf + i, Len - i) + 1) for (size_t i = 0;; i += wcsnlen(*Buf + i, Len - i) + 1)
@ -132,25 +128,25 @@ RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType
if (i > Len) if (i > Len)
{ {
/* Missing string and list terminators. */ /* Missing string and list terminators. */
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 2) * sizeof(WCHAR)); WCHAR *BufZ = HeapAlloc(ModuleHeap, 0, ((size_t)Len + 2) * sizeof(WCHAR));
if (!BufZ) if (!BufZ)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
wmemcpy(BufZ, *Buf, Len); wmemcpy(BufZ, *Buf, Len);
BufZ[Len] = 0; BufZ[Len] = 0;
BufZ[Len + 1] = 0; BufZ[Len + 1] = 0;
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
*Buf = BufZ; *Buf = BufZ;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
if (i == Len) if (i == Len)
{ {
/* Missing list terminator. */ /* Missing list terminator. */
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR)); WCHAR *BufZ = HeapAlloc(ModuleHeap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
if (!BufZ) if (!BufZ)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
wmemcpy(BufZ, *Buf, Len); wmemcpy(BufZ, *Buf, Len);
BufZ[Len] = 0; BufZ[Len] = 0;
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
*Buf = BufZ; *Buf = BufZ;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -164,12 +160,12 @@ RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
return Result; return Result;
Len = (DWORD)wcslen(*Buf) + 1; Len = (DWORD)wcslen(*Buf) + 1;
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR)); WCHAR *BufZ = HeapAlloc(ModuleHeap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
if (!BufZ) if (!BufZ)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
wmemcpy(BufZ, *Buf, Len); wmemcpy(BufZ, *Buf, Len);
BufZ[Len] = 0; BufZ[Len] = 0;
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
*Buf = BufZ; *Buf = BufZ;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -183,16 +179,15 @@ RegistryQuery(
_Inout_ DWORD *BufLen, _Inout_ DWORD *BufLen,
_In_ BOOL Log) _In_ BOOL Log)
{ {
HANDLE Heap = GetProcessHeap();
for (;;) for (;;)
{ {
*Buf = HeapAlloc(Heap, 0, *BufLen); *Buf = HeapAlloc(ModuleHeap, 0, *BufLen);
if (!*Buf) if (!*Buf)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
LSTATUS Result = RegQueryValueExW(Key, Name, NULL, ValueType, (BYTE *)*Buf, BufLen); LSTATUS Result = RegQueryValueExW(Key, Name, NULL, ValueType, (BYTE *)*Buf, BufLen);
if (Result == ERROR_SUCCESS) if (Result == ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
HeapFree(Heap, 0, *Buf); HeapFree(ModuleHeap, 0, *Buf);
if (Result != ERROR_MORE_DATA) if (Result != ERROR_MORE_DATA)
return Log ? LOG_ERROR(L"Querying value failed", Result) : Result; return Log ? LOG_ERROR(L"Querying value failed", Result) : Result;
} }
@ -212,11 +207,11 @@ RegistryQueryString(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ WCHAR **V
case REG_MULTI_SZ: case REG_MULTI_SZ:
Result = RegistryGetString(Value, Size / sizeof(WCHAR), ValueType); Result = RegistryGetString(Value, Size / sizeof(WCHAR), ValueType);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
HeapFree(GetProcessHeap(), 0, *Value); HeapFree(ModuleHeap, 0, *Value);
return Result; return Result;
default: default:
LOG(WINTUN_LOG_ERR, L"Value is not a string"); LOG(WINTUN_LOG_ERR, L"Value is not a string");
HeapFree(GetProcessHeap(), 0, *Value); HeapFree(ModuleHeap, 0, *Value);
return ERROR_INVALID_DATATYPE; return ERROR_INVALID_DATATYPE;
} }
} }

View File

@ -38,9 +38,8 @@ RegistryOpenKeyWait(
* Validates and/or sanitizes string value read from registry. * Validates and/or sanitizes string value read from registry.
* *
* @param Buf On input, it contains a pointer to pointer where the data is stored. The data must be allocated * @param Buf On input, it contains a pointer to pointer where the data is stored. The data must be allocated
* using HeapAlloc(GetProcessHeap(), 0). On output, it contains a pointer to pointer where the * using HeapAlloc(ModuleHeap, 0). On output, it contains a pointer to pointer where the sanitized
* sanitized data is stored. It must be released with HeapFree(GetProcessHeap(), 0, *Buf) after * data is stored. It must be released with HeapFree(ModuleHeap, 0, *Buf) after use.
* use.
* *
* @param Len Length of data string in wide characters. * @param Len Length of data string in wide characters.
* *
@ -56,9 +55,8 @@ RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType);
* Validates and/or sanitizes multi-string value read from registry. * Validates and/or sanitizes multi-string value read from registry.
* *
* @param Buf On input, it contains a pointer to pointer where the data is stored. The data must be allocated * @param Buf On input, it contains a pointer to pointer where the data is stored. The data must be allocated
* using HeapAlloc(GetProcessHeap(), 0). On output, it contains a pointer to pointer where the * using HeapAlloc(ModuleHeap, 0). On output, it contains a pointer to pointer where the sanitized
* sanitized data is stored. It must be released with HeapFree(GetProcessHeap(), 0, *Buf) after * data is stored. It must be released with HeapFree(ModuleHeap, 0, *Buf) after use.
* use.
* *
* @param Len Length of data string in wide characters. * @param Len Length of data string in wide characters.
* *
@ -79,7 +77,7 @@ RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType
* @param Value Pointer to string to retrieve registry value. If the value type is REG_EXPAND_SZ the value is * @param Value Pointer to string to retrieve registry value. If the value type is REG_EXPAND_SZ the value is
* expanded using ExpandEnvironmentStrings(). If the value type is REG_MULTI_SZ, only the first * expanded using ExpandEnvironmentStrings(). If the value type is REG_MULTI_SZ, only the first
* string from the multi-string is returned. The string must be released with * string from the multi-string is returned. The string must be released with
* HeapFree(GetProcessHeap(), 0, Value) after use. * HeapFree(ModuleHeap, 0, Value) after use.
* *
* @Log Set to TRUE to log all failures; FALSE to skip logging the innermost errors. Skipping innermost * @Log Set to TRUE to log all failures; FALSE to skip logging the innermost errors. Skipping innermost
* errors reduces log clutter when we are using RegistryQueryString() from * errors reduces log clutter when we are using RegistryQueryString() from
@ -103,7 +101,7 @@ RegistryQueryString(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ WCHAR **V
* @param Value Pointer to string to retrieve registry value. If the value type is REG_EXPAND_SZ the value is * @param Value Pointer to string to retrieve registry value. If the value type is REG_EXPAND_SZ the value is
* expanded using ExpandEnvironmentStrings(). If the value type is REG_MULTI_SZ, only the first * expanded using ExpandEnvironmentStrings(). If the value type is REG_MULTI_SZ, only the first
* string from the multi-string is returned. The string must be released with * string from the multi-string is returned. The string must be released with
* HeapFree(GetProcessHeap(), 0, Value) after use. * HeapFree(ModuleHeap, 0, Value) after use.
* *
* @return ERROR_SUCCESS on success; WAIT_TIMEOUT on timeout; ERROR_INVALID_DATATYPE when the registry value is not a * @return ERROR_SUCCESS on success; WAIT_TIMEOUT on timeout; ERROR_INVALID_DATATYPE when the registry value is not a
* string; Win32 error code otherwise. * string; Win32 error code otherwise.

View File

@ -52,8 +52,7 @@ typedef struct _TUN_SESSION
WINTUN_STATUS WINAPI WINTUN_STATUS WINAPI
WintunStartSession(_In_ const WINTUN_ADAPTER *Adapter, _In_ DWORD Capacity, _Out_ TUN_SESSION **Session) WintunStartSession(_In_ const WINTUN_ADAPTER *Adapter, _In_ DWORD Capacity, _Out_ TUN_SESSION **Session)
{ {
HANDLE Heap = GetProcessHeap(); *Session = HeapAlloc(ModuleHeap, 0, sizeof(TUN_SESSION));
*Session = HeapAlloc(Heap, 0, sizeof(TUN_SESSION));
if (!*Session) if (!*Session)
return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY; return LOG(WINTUN_LOG_ERR, L"Out of memory"), ERROR_OUTOFMEMORY;
const ULONG RingSize = TUN_RING_SIZE(Capacity); const ULONG RingSize = TUN_RING_SIZE(Capacity);
@ -113,7 +112,7 @@ cleanupSendTailMoved:
cleanupAllocatedRegion: cleanupAllocatedRegion:
VirtualFree(AllocatedRegion, 0, MEM_RELEASE); VirtualFree(AllocatedRegion, 0, MEM_RELEASE);
cleanupRings: cleanupRings:
HeapFree(Heap, 0, *Session); HeapFree(ModuleHeap, 0, *Session);
*Session = NULL; *Session = NULL;
return Result; return Result;
} }
@ -126,7 +125,7 @@ WintunEndSession(_In_ TUN_SESSION *Session)
CloseHandle(Session->Descriptor.Send.TailMoved); CloseHandle(Session->Descriptor.Send.TailMoved);
CloseHandle(Session->Descriptor.Receive.TailMoved); CloseHandle(Session->Descriptor.Receive.TailMoved);
VirtualFree(Session->Descriptor.Send.Ring, 0, MEM_RELEASE); VirtualFree(Session->Descriptor.Send.Ring, 0, MEM_RELEASE);
HeapFree(GetProcessHeap(), 0, Session); HeapFree(ModuleHeap, 0, Session);
} }
BOOL WINAPI BOOL WINAPI