installer: improve resource freeing flow

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2019-10-04 08:49:23 +00:00
parent 736131960f
commit 53332cd078
2 changed files with 44 additions and 31 deletions

View File

@ -298,7 +298,7 @@ InstallWintun(BOOL UpdateExisting)
Logger(LOG_WARN, TEXT("A reboot might be required, which really should not be the case")); Logger(LOG_WARN, TEXT("A reboot might be required, which really should not be the case"));
cleanupDelete: cleanupDelete:
LastError = LastError ? LastError : GetLastError(); LastError = GetLastError();
DeleteFile(CatPath); DeleteFile(CatPath);
DeleteFile(SysPath); DeleteFile(SysPath);
DeleteFile(InfPath); DeleteFile(InfPath);
@ -410,8 +410,9 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DeviceInfoSet, _In_ SP_DEVINFO_DATA
TCHAR *InstanceId = calloc(sizeof(*InstanceId), RequiredBytes); TCHAR *InstanceId = calloc(sizeof(*InstanceId), RequiredBytes);
if (!InstanceId) if (!InstanceId)
return FALSE; return FALSE;
BOOL Ret = FALSE;
if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, DeviceInfo, InstanceId, RequiredBytes, &RequiredBytes)) if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, DeviceInfo, InstanceId, RequiredBytes, &RequiredBytes))
return FALSE; goto out;
TCHAR *InterfaceList = NULL; TCHAR *InterfaceList = NULL;
for (;;) for (;;)
{ {
@ -419,22 +420,22 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DeviceInfoSet, _In_ SP_DEVINFO_DATA
if (CM_Get_Device_Interface_List_Size( if (CM_Get_Device_Interface_List_Size(
&RequiredBytes, (LPGUID)&GUID_DEVINTERFACE_NET, InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != &RequiredBytes, (LPGUID)&GUID_DEVINTERFACE_NET, InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) !=
CR_SUCCESS) CR_SUCCESS)
return FALSE; goto out;
InterfaceList = calloc(sizeof(*InterfaceList), RequiredBytes); InterfaceList = calloc(sizeof(*InterfaceList), RequiredBytes);
if (!InterfaceList) if (!InterfaceList)
return FALSE; goto out;
CONFIGRET Ret = CM_Get_Device_Interface_List( CONFIGRET CRet = CM_Get_Device_Interface_List(
(LPGUID)&GUID_DEVINTERFACE_NET, (LPGUID)&GUID_DEVINTERFACE_NET,
InstanceId, InstanceId,
InterfaceList, InterfaceList,
RequiredBytes, RequiredBytes,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT); CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (Ret == CR_SUCCESS) if (CRet == CR_SUCCESS)
break; break;
if (Ret != CR_BUFFER_SMALL) if (CRet != CR_BUFFER_SMALL)
{ {
free(InterfaceList); free(InterfaceList);
return FALSE; goto out;
} }
} }
@ -448,11 +449,13 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DeviceInfoSet, _In_ SP_DEVINFO_DATA
NULL); NULL);
free(InterfaceList); free(InterfaceList);
if (NdisHandle == INVALID_HANDLE_VALUE) if (NdisHandle == INVALID_HANDLE_VALUE)
return FALSE; goto out;
BOOL Ret = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL); Ret = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL);
DWORD LastError = GetLastError(); DWORD LastError = GetLastError();
CloseHandle(NdisHandle); CloseHandle(NdisHandle);
SetLastError(LastError); SetLastError(LastError);
out:
free(InstanceId);
return Ret; return Ret;
} }

View File

@ -42,15 +42,19 @@ static BOOL ElevateToSystem(VOID)
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } }; TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
CHAR LocalSystemSid[0x400]; CHAR LocalSystemSid[0x400];
DWORD RequiredBytes = sizeof(LocalSystemSid); DWORD RequiredBytes = sizeof(LocalSystemSid);
if (!CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes))
goto cleanup;
struct struct
{ {
TOKEN_USER MaybeLocalSystem; TOKEN_USER MaybeLocalSystem;
CHAR LargeEnoughForLocalSystem[0x400]; CHAR LargeEnoughForLocalSystem[0x400];
} TokenUserBuffer; } TokenUserBuffer;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken))
Ret = CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes);
LastError = GetLastError();
if (!Ret)
goto cleanup;
Ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken);
LastError = GetLastError();
if (!Ret)
goto cleanup; goto cleanup;
Ret = Ret =
GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes); GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
@ -60,41 +64,47 @@ static BOOL ElevateToSystem(VOID)
goto cleanup; goto cleanup;
if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid)) if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
return TRUE; return TRUE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid)) Ret = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid);
LastError = GetLastError();
if (!Ret)
goto cleanup; goto cleanup;
ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
LastError = GetLastError();
if (ProcessSnapshot == INVALID_HANDLE_VALUE) if (ProcessSnapshot == INVALID_HANDLE_VALUE)
goto cleanup; goto cleanup;
for (Ret = Process32First(ProcessSnapshot, &ProcessEntry); Ret; for (Ret = Process32First(ProcessSnapshot, &ProcessEntry); Ret; Ret = Process32Next(ProcessSnapshot, &ProcessEntry))
LastError = GetLastError(), Ret = Process32Next(ProcessSnapshot, &ProcessEntry))
{ {
if (_tcsicmp(ProcessEntry.szExeFile, TEXT("winlogon.exe"))) if (_tcsicmp(ProcessEntry.szExeFile, TEXT("winlogon.exe")))
continue; continue;
RevertToSelf(); RevertToSelf();
if (!ImpersonateSelf(SecurityImpersonation)) Ret = ImpersonateSelf(SecurityImpersonation);
LastError = GetLastError();
if (!Ret)
continue; continue;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken)) Ret = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken);
LastError = GetLastError();
if (!Ret)
continue; continue;
if (!AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL)) Ret = AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
{ LastError = GetLastError();
LastError = GetLastError();
CloseHandle(ThreadToken);
continue;
}
CloseHandle(ThreadToken); CloseHandle(ThreadToken);
if (!Ret)
continue;
WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID); WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID);
LastError = GetLastError();
if (!WinlogonProcess) if (!WinlogonProcess)
continue; continue;
if (!OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken)) Ret = OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken);
continue; LastError = GetLastError();
CloseHandle(WinlogonProcess); CloseHandle(WinlogonProcess);
if (!DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken)) if (!Ret)
{
LastError = GetLastError();
continue; continue;
} Ret = DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken);
LastError = GetLastError();
CloseHandle(WinlogonToken); CloseHandle(WinlogonToken);
if (!Ret)
continue;
if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes)) if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes))
goto next; goto next;
if (SetLastError(ERROR_ACCESS_DENIED), !EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid)) if (SetLastError(ERROR_ACCESS_DENIED), !EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))