aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-10-06 05:04:58 +0000
committerJason A. Donenfeld <Jason@zx2c4.com>2021-10-06 05:16:14 +0000
commit4d5d323d7f86d137dff83e1b16fd54d8835950dc (patch)
treec41e18341ee5f112e4b85e852490d900dee24b68
parentdriver: ioctl: remove old pid check (diff)
downloadwireguard-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.h1
-rw-r--r--driver/ioctl.c89
-rw-r--r--driver/undocumented.h33
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);