diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-06-08 08:54:56 +0000 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-06-08 09:04:32 +0000 |
commit | 12e9f53fe2fef372d5bf2196e22b98a2cf44a2ca (patch) | |
tree | 232bf2d4c06bb881724dd1657cc1f8cf12cbb5ed | |
parent | Clean TunWaitForReferencesToDropToZero() (diff) | |
download | wintun-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.c | 13 |
1 files changed, 9 insertions, 4 deletions
@@ -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); |