aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-06-08 08:54:56 +0000
committerJason A. Donenfeld <Jason@zx2c4.com>2019-06-08 09:04:32 +0000
commit12e9f53fe2fef372d5bf2196e22b98a2cf44a2ca (patch)
tree232bf2d4c06bb881724dd1657cc1f8cf12cbb5ed
parentClean TunWaitForReferencesToDropToZero() (diff)
downloadwintun-12e9f53fe2fef372d5bf2196e22b98a2cf44a2ca.tar.xz
wintun-12e9f53fe2fef372d5bf2196e22b98a2cf44a2ca.zip
Do not take handle reference with verifier enabled
This is actually very much wrong. In fact, it's bound to create all sorts of nasty issues. But without it, we can't use the reference function to check the validity of a potentially invalid handle while the verifier is enabled. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--wintun.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/wintun.c b/wintun.c
index 54ffe30..8a677d2 100644
--- a/wintun.c
+++ b/wintun.c
@@ -1246,10 +1246,13 @@ static void TunForceHandlesClosed(_Inout_ TUN_CTX *ctx)
NTSTATUS status;
PEPROCESS process;
KAPC_STATE apc_state;
- PVOID object;
+ PVOID object = NULL;
+ ULONG verifier_flags = 0;
OBJECT_HANDLE_INFORMATION handle_info;
SYSTEM_HANDLE_INFORMATION_EX *table = NULL;
+ MmIsVerifierEnabled(&verifier_flags);
+
for (ULONG size = 0, req; (status = ZwQuerySystemInformation(SystemExtendedHandleInformation, table, size, &req)) == STATUS_INFO_LENGTH_MISMATCH; size = req) {
if (table)
ExFreePoolWithTag(table, TUN_HTONL(TUN_MEMORY_TAG));
@@ -1268,11 +1271,13 @@ static void TunForceHandlesClosed(_Inout_ TUN_CTX *ctx)
if (!NT_SUCCESS(status))
continue;
KeStackAttachProcess(process, &apc_state);
- status = ObReferenceObjectByHandle(table->Handles[i].HandleValue, 0, NULL, UserMode, &object, &handle_info);
+ if (!verifier_flags)
+ status = ObReferenceObjectByHandle(table->Handles[i].HandleValue, 0, NULL, UserMode, &object, &handle_info);
if (NT_SUCCESS(status)) {
- if (object == file)
+ if (verifier_flags || object == file)
ObCloseHandle(table->Handles[i].HandleValue, UserMode);
- ObfDereferenceObject(object);
+ if (!verifier_flags)
+ ObfDereferenceObject(object);
}
KeUnstackDetachProcess(&apc_state);
ObfDereferenceObject(process);