diff options
author | 2021-10-06 05:04:58 +0000 | |
---|---|---|
committer | 2021-10-06 05:16:14 +0000 | |
commit | 4d5d323d7f86d137dff83e1b16fd54d8835950dc (patch) | |
tree | c41e18341ee5f112e4b85e852490d900dee24b68 | |
parent | driver: ioctl: remove old pid check (diff) | |
download | wireguard-nt-4d5d323d7f86d137dff83e1b16fd54d8835950dc.tar.xz wireguard-nt-4d5d323d7f86d137dff83e1b16fd54d8835950dc.zip |
driver: ioctl: remove force closing of handles
This driver has never actually made successful use of it, because we've
been wrongly matching against the FunctionalDeviceObject instead of
Stack->FileObject->DeviceObject. Yet, things seem to have worked fine
enough because of smart notification to the logger thread.
Furthermore, SwDevice calls halt immediately, because it constitutes a
surprise removal, which means we don't really even have time for the
fuse to go off.
And finally, dereferencing Table[i]->Object can race with the
destruction of that object, which is a UaF.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | driver/device.h | 1 | ||||
-rw-r--r-- | driver/ioctl.c | 89 | ||||
-rw-r--r-- | driver/undocumented.h | 33 |
3 files changed, 0 insertions, 123 deletions
diff --git a/driver/device.h b/driver/device.h index 45a72de..39038d3 100644 --- a/driver/device.h +++ b/driver/device.h @@ -94,7 +94,6 @@ typedef struct _WG_DEVICE LOG_RING Log; LIST_ENTRY DeviceList; KEVENT DeviceRemoved; - PKTHREAD HandleForceCloseThread; } WG_DEVICE; _Requires_lock_held_(Wg->DeviceUpdateLock) diff --git a/driver/ioctl.c b/driver/ioctl.c index 7ecc039..061be2a 100644 --- a/driver/ioctl.c +++ b/driver/ioctl.c @@ -585,78 +585,6 @@ ReadLogLine(_In_ DEVICE_OBJECT *DeviceObject, _Inout_ IRP *Irp) Irp->IoStatus.Information = sizeof(WG_IOCTL_LOG_ENTRY); } -static KSTART_ROUTINE ForceCloseHandlesAfterDelay; -_Use_decl_annotations_ -static VOID -ForceCloseHandlesAfterDelay(PVOID StartContext) -{ - WG_DEVICE *Wg = StartContext; - DEVICE_OBJECT *DeviceObject; - NTSTATUS Status; - PEPROCESS Process; - KAPC_STATE ApcState; - PVOID Object = NULL; - ULONG VerifierFlags = 0; - OBJECT_HANDLE_INFORMATION HandleInfo; - SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL; - - if (KeWaitForSingleObject( - &Wg->DeviceRemoved, - Executive, - KernelMode, - FALSE, - &(LARGE_INTEGER){ .QuadPart = -SEC_TO_SYS_TIME_UNITS(5) }) != STATUS_TIMEOUT) - return; - - DeviceObject = Wg->FunctionalDeviceObject; - if (!DeviceObject) - return; - - LogWarn(Wg, "Force closing all adapter handles after having waited 5 seconds"); - - MmIsVerifierEnabled(&VerifierFlags); - - for (ULONG Size = 0, RequestedSize; - (Status = ZwQuerySystemInformation(SystemExtendedHandleInformation, HandleTable, Size, &RequestedSize)) == - STATUS_INFO_LENGTH_MISMATCH; - Size = RequestedSize) - { - if (HandleTable) - MemFree(HandleTable); - HandleTable = MemAllocate(RequestedSize); - if (!HandleTable) - return; - } - if (!NT_SUCCESS(Status) || !HandleTable) - goto cleanup; - - for (ULONG_PTR Index = 0; Index < HandleTable->NumberOfHandles; ++Index) - { - FILE_OBJECT *FileObject = HandleTable->Handles[Index].Object; - if (!FileObject || FileObject->Type != 5 || FileObject->DeviceObject != DeviceObject) - continue; - Status = PsLookupProcessByProcessId(HandleTable->Handles[Index].UniqueProcessId, &Process); - if (!NT_SUCCESS(Status)) - continue; - KeStackAttachProcess(Process, &ApcState); - if (!VerifierFlags) - Status = ObReferenceObjectByHandle( - HandleTable->Handles[Index].HandleValue, 0, NULL, UserMode, &Object, &HandleInfo); - if (NT_SUCCESS(Status)) - { - if (VerifierFlags || Object == FileObject) - ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode); - if (!VerifierFlags) - ObfDereferenceObject(Object); - } - KeUnstackDetachProcess(&ApcState); - ObfDereferenceObject(Process); - } -cleanup: - if (HandleTable) - MemFree(HandleTable); -} - _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) static DRIVER_DISPATCH_PAGED DispatchDeviceControl; _Use_decl_annotations_ @@ -718,17 +646,6 @@ DispatchPnp(DEVICE_OBJECT *DeviceObject, IRP *Irp) WriteBooleanNoFence(&Wg->IsDeviceRemoving, TRUE); KeSetEvent(&Wg->Log.NewEntry, IO_NO_INCREMENT, FALSE); - OBJECT_ATTRIBUTES ObjectAttributes; - InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); - HANDLE Handle; - if (NT_SUCCESS(PsCreateSystemThread( - &Handle, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, ForceCloseHandlesAfterDelay, Wg))) - { -#pragma warning(suppress : 28126) /* Handle is a kernel handle. */ - ObReferenceObjectByHandle(Handle, SYNCHRONIZE, NULL, KernelMode, &Wg->HandleForceCloseThread, NULL); - ZwClose(Handle); - } - ndisDispatch: return NdisDispatchPnp(DeviceObject, Irp); } @@ -739,12 +656,6 @@ IoctlHalt(WG_DEVICE *Wg) { WritePointerNoFence(&Wg->FunctionalDeviceObject->Reserved, NULL); KeSetEvent(&Wg->DeviceRemoved, IO_NETWORK_INCREMENT, FALSE); - if (Wg->HandleForceCloseThread) - { - KeWaitForSingleObject(Wg->HandleForceCloseThread, Executive, KernelMode, FALSE, NULL); - ObDereferenceObject(Wg->HandleForceCloseThread); - Wg->HandleForceCloseThread = NULL; - } } #ifdef ALLOC_PRAGMA diff --git a/driver/undocumented.h b/driver/undocumented.h index 7a4e534..0e6f05d 100644 --- a/driver/undocumented.h +++ b/driver/undocumented.h @@ -8,39 +8,6 @@ #include <ntifs.h> /* Must be included before <wdm.h> */ #include <wdm.h> -typedef enum _SYSTEM_INFORMATION_CLASS -{ - SystemBasicInformation = 0x0, - SystemExtendedHandleInformation = 0x40 -} SYSTEM_INFORMATION_CLASS; - -typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX -{ - PVOID Object; - HANDLE UniqueProcessId; - HANDLE HandleValue; - ACCESS_MASK GrantedAccess; - USHORT CreatorBackTraceIndex; - USHORT ObjectTypeIndex; - ULONG HandleAttributes; - ULONG Reserved; -} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX; - -typedef struct _SYSTEM_HANDLE_INFORMATION_EX -{ - ULONG_PTR NumberOfHandles; - ULONG_PTR Reserved; - SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[ANYSIZE_ARRAY]; -} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; - -NTSYSAPI -NTSTATUS NTAPI -ZwQuerySystemInformation( - _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, - _Out_bytecap_post_bytecount_(SystemInformationLength, *ReturnLength) PVOID SystemInformation, - _In_ ULONG SystemInformationLength, - _Out_opt_ PULONG ReturnLength); - NTSYSAPI NTSTATUS NTAPI ZwYieldExecution(VOID); |