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>
This commit is contained in:
Jason A. Donenfeld 2019-06-08 08:54:56 +00:00
parent c848006144
commit 12e9f53fe2

View File

@ -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);