api: only sleep after force closing handles if required

Also force close handles when deleting the adapter, in case the function
is called from another process, for example an uninstaller.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2020-10-30 14:21:13 +01:00 committed by Simon Rozman
parent 1b3af95be3
commit a332f54a1b
2 changed files with 19 additions and 9 deletions

View File

@ -214,9 +214,15 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevIn
LOG(WINTUN_LOG_ERR, L"Failed to get adapter device object");
goto out;
}
Result = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL)
? ERROR_SUCCESS
: LOG_LAST_ERROR(L"Failed to perform ioctl");
if (DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL))
{
Result = ERROR_SUCCESS;
Sleep(200);
}
else if (GetLastError() == ERROR_NOTHING_TO_TERMINATE)
Result = ERROR_SUCCESS;
else
Result = LOG_LAST_ERROR(L"Failed to perform ioctl");
CloseHandle(NdisHandle);
out:
HeapFree(ModuleHeap, 0, InstanceId);
@ -258,7 +264,6 @@ AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **Disa
LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter");
if (ForceCloseWintunAdapterHandle(DevInfo, &DeviceNode->Data) != ERROR_SUCCESS)
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
Sleep(200);
LOG(WINTUN_LOG_INFO, L"Disabling existing adapter");
if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) ||
@ -327,7 +332,6 @@ AdapterDeleteAllOurs(void)
LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter");
if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS)
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
Sleep(200);
LOG(WINTUN_LOG_INFO, L"Removing existing adapter");
if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) ||
@ -1717,6 +1721,10 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
LOG(WINTUN_LOG_ERR, L"Failed to get device info data");
goto cleanupToken;
}
if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS)
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
SetQuietInstall(DevInfo, &DevInfoData);
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
.InstallFunction = DIF_REMOVE },

View File

@ -759,7 +759,7 @@ TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner)
}
_IRQL_requires_max_(PASSIVE_LEVEL)
static VOID
static BOOLEAN
TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
{
NTSTATUS Status;
@ -769,6 +769,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
ULONG VerifierFlags = 0;
OBJECT_HANDLE_INFORMATION HandleInfo;
SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL;
BOOLEAN DidClose = FALSE;
MmIsVerifierEnabled(&VerifierFlags);
@ -781,7 +782,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
HandleTable = ExAllocatePoolWithTag(PagedPool, RequestedSize, TUN_MEMORY_TAG);
if (!HandleTable)
return;
return FALSE;
}
if (!NT_SUCCESS(Status) || !HandleTable)
goto cleanup;
@ -808,6 +809,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode);
if (!VerifierFlags)
ObfDereferenceObject(Object);
DidClose = TRUE;
}
KeUnstackDetachProcess(&ApcState);
ObfDereferenceObject(Process);
@ -815,6 +817,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
cleanup:
if (HandleTable)
ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
return DidClose;
}
static NTSTATUS TunInitializeDispatchSecurityDescriptor(VOID)
@ -927,8 +930,7 @@ TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
break;
}
case TUN_IOCTL_FORCE_CLOSE_HANDLES:
TunForceHandlesClosed(Stack->FileObject->DeviceObject);
Status = STATUS_SUCCESS;
Status = TunForceHandlesClosed(Stack->FileObject->DeviceObject) ? STATUS_SUCCESS : STATUS_NOTHING_TO_TERMINATE;
break;
}
cleanup: