Require the usual SDDL_DEVOBJ_SYS_ALL permissions

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2019-07-18 17:43:40 +00:00
parent 14e5532dc8
commit 6ebdbf77d2

132
wintun.c
View File

@ -135,8 +135,7 @@ typedef struct _TUN_CTX
ULONG Capacity; ULONG Capacity;
KEVENT *TailMoved; KEVENT *TailMoved;
KSPIN_LOCK Lock; KSPIN_LOCK Lock;
ULONG RingTail; /* We need a private tail offset to keep track of ring allocation without disturbing the ULONG RingTail;
* client. */
struct struct
{ {
NET_BUFFER_LIST *Head, *Tail; NET_BUFFER_LIST *Head, *Tail;
@ -165,7 +164,8 @@ typedef struct _TUN_CTX
static UINT NdisVersion; static UINT NdisVersion;
static NDIS_HANDLE NdisMiniportDriverHandle; static NDIS_HANDLE NdisMiniportDriverHandle;
static DRIVER_DISPATCH *NdisDispatchDeviceControl, *NdisDispatchClose; static DRIVER_DISPATCH *NdisDispatchDeviceControl, *NdisDispatchClose;
static ERESOURCE TunCtxDispatchGuard; static ERESOURCE TunDispatchCtxGuard;
static SECURITY_DESCRIPTOR *TunDispatchSecurityDescriptor;
static __forceinline ULONG static __forceinline ULONG
InterlockedExchangeU(_Inout_ _Interlocked_operand_ ULONG volatile *Target, _In_ ULONG Value) InterlockedExchangeU(_Inout_ _Interlocked_operand_ ULONG volatile *Target, _In_ ULONG Value)
@ -209,7 +209,7 @@ InterlockedGet64(_In_ _Interlocked_operand_ LONG64 volatile *Value)
} }
_IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL)
static void static VOID
TunIndicateStatus(_In_ NDIS_HANDLE MiniportAdapterHandle, _In_ NDIS_MEDIA_CONNECT_STATE MediaConnectState) TunIndicateStatus(_In_ NDIS_HANDLE MiniportAdapterHandle, _In_ NDIS_MEDIA_CONNECT_STATE MediaConnectState)
{ {
NDIS_LINK_STATE State = { .Header = { .Type = NDIS_OBJECT_TYPE_DEFAULT, NDIS_LINK_STATE State = { .Header = { .Type = NDIS_OBJECT_TYPE_DEFAULT,
@ -232,7 +232,7 @@ TunIndicateStatus(_In_ NDIS_HANDLE MiniportAdapterHandle, _In_ NDIS_MEDIA_CONNEC
NdisMIndicateStatusEx(MiniportAdapterHandle, &Indication); NdisMIndicateStatusEx(MiniportAdapterHandle, &Indication);
} }
static void static VOID
TunNblSetOffsetAndMarkActive(_Inout_ NET_BUFFER_LIST *Nbl, _In_ ULONG Offset) TunNblSetOffsetAndMarkActive(_Inout_ NET_BUFFER_LIST *Nbl, _In_ ULONG Offset)
{ {
ASSERT(TUN_IS_ALIGNED(Offset)); /* Alignment ensures bit 0 will be 0 (0=active, 1=completed). */ ASSERT(TUN_IS_ALIGNED(Offset)); /* Alignment ensures bit 0 will be 0 (0=active, 1=completed). */
@ -245,7 +245,7 @@ TunNblGetOffset(_In_ NET_BUFFER_LIST *Nbl)
return (ULONG)((ULONG_PTR)(NET_BUFFER_LIST_MINIPORT_RESERVED(Nbl)[0]) & ~((ULONG_PTR)TUN_ALIGNMENT - 1)); return (ULONG)((ULONG_PTR)(NET_BUFFER_LIST_MINIPORT_RESERVED(Nbl)[0]) & ~((ULONG_PTR)TUN_ALIGNMENT - 1));
} }
static void static VOID
TunNblMarkCompleted(_Inout_ NET_BUFFER_LIST *Nbl) TunNblMarkCompleted(_Inout_ NET_BUFFER_LIST *Nbl)
{ {
*(ULONG_PTR *)&NET_BUFFER_LIST_MINIPORT_RESERVED(Nbl)[0] |= 1; *(ULONG_PTR *)&NET_BUFFER_LIST_MINIPORT_RESERVED(Nbl)[0] |= 1;
@ -259,7 +259,7 @@ TunNblIsCompleted(_In_ NET_BUFFER_LIST *Nbl)
static MINIPORT_SEND_NET_BUFFER_LISTS TunSendNetBufferLists; static MINIPORT_SEND_NET_BUFFER_LISTS TunSendNetBufferLists;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunSendNetBufferLists( TunSendNetBufferLists(
NDIS_HANDLE MiniportAdapterContext, NDIS_HANDLE MiniportAdapterContext,
NET_BUFFER_LIST *NetBufferLists, NET_BUFFER_LIST *NetBufferLists,
@ -387,7 +387,7 @@ TunSendNetBufferLists(
static MINIPORT_CANCEL_SEND TunCancelSend; static MINIPORT_CANCEL_SEND TunCancelSend;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunCancelSend(NDIS_HANDLE MiniportAdapterContext, PVOID CancelId) TunCancelSend(NDIS_HANDLE MiniportAdapterContext, PVOID CancelId)
{ {
} }
@ -403,7 +403,7 @@ TunCancelSend(NDIS_HANDLE MiniportAdapterContext, PVOID CancelId)
static MINIPORT_RETURN_NET_BUFFER_LISTS TunReturnNetBufferLists; static MINIPORT_RETURN_NET_BUFFER_LISTS TunReturnNetBufferLists;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferLists, ULONG ReturnFlags) TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferLists, ULONG ReturnFlags)
{ {
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext; TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
@ -458,7 +458,7 @@ TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST Net
_IRQL_requires_max_(PASSIVE_LEVEL) _IRQL_requires_max_(PASSIVE_LEVEL)
_Function_class_(KSTART_ROUTINE) _Function_class_(KSTART_ROUTINE)
static void static VOID
TunProcessReceiveData(_Inout_ TUN_CTX *Ctx) TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
{ {
TUN_RING *Ring = Ctx->Device.Receive.Ring; TUN_RING *Ring = Ctx->Device.Receive.Ring;
@ -543,7 +543,6 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity); RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity);
/* Inform NDIS of the packet. */
NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList( NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(
Ctx->NblPool, 0, 0, Ctx->Device.Receive.Mdl, (ULONG)(Packet->Data - (UCHAR *)Ring), PacketSize); Ctx->NblPool, 0, 0, Ctx->Device.Receive.Mdl, (ULONG)(Packet->Data - (UCHAR *)Ring), PacketSize);
if (!Nbl) if (!Nbl)
@ -604,8 +603,6 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
NTSTATUS Status; NTSTATUS Status;
IO_STACK_LOCATION *Stack = IoGetCurrentIrpStackLocation(Irp); IO_STACK_LOCATION *Stack = IoGetCurrentIrpStackLocation(Irp);
/* TODO TODO TODO: SeCaptureSubjectContext, SeAccessCheck */
if (InterlockedCompareExchangePointer(&Ctx->Device.Owner, Stack->FileObject, NULL) != NULL) if (InterlockedCompareExchangePointer(&Ctx->Device.Owner, Stack->FileObject, NULL) != NULL)
return STATUS_ALREADY_INITIALIZED; return STATUS_ALREADY_INITIALIZED;
@ -613,7 +610,6 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
if (Status = STATUS_INVALID_PARAMETER, Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(*Rrb)) if (Status = STATUS_INVALID_PARAMETER, Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(*Rrb))
goto cleanupResetOwner; goto cleanupResetOwner;
/* Analyze and lock send ring. */
Ctx->Device.Send.Capacity = TUN_RING_CAPACITY(Rrb->Send.RingSize); Ctx->Device.Send.Capacity = TUN_RING_CAPACITY(Rrb->Send.RingSize);
if (Status = STATUS_INVALID_PARAMETER, if (Status = STATUS_INVALID_PARAMETER,
(Ctx->Device.Send.Capacity < TUN_MIN_RING_CAPACITY || Ctx->Device.Send.Capacity > TUN_MAX_RING_CAPACITY || (Ctx->Device.Send.Capacity < TUN_MIN_RING_CAPACITY || Ctx->Device.Send.Capacity > TUN_MAX_RING_CAPACITY ||
@ -623,7 +619,8 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
if (!NT_SUCCESS( if (!NT_SUCCESS(
Status = ObReferenceObjectByHandle( Status = ObReferenceObjectByHandle(
Rrb->Send.TailMoved, Rrb->Send.TailMoved,
EVENT_MODIFY_STATE, /* We will not wait on send ring tail moved event. */ /* We will not wait on send ring tail moved event. */
EVENT_MODIFY_STATE,
*ExEventObjectType, *ExEventObjectType,
UserMode, UserMode,
&Ctx->Device.Send.TailMoved, &Ctx->Device.Send.TailMoved,
@ -649,7 +646,6 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
if (Status = STATUS_INVALID_PARAMETER, Ctx->Device.Send.RingTail >= Ctx->Device.Send.Capacity) if (Status = STATUS_INVALID_PARAMETER, Ctx->Device.Send.RingTail >= Ctx->Device.Send.Capacity)
goto cleanupSendUnlockPages; goto cleanupSendUnlockPages;
/* Analyze and lock receive ring. */
Ctx->Device.Receive.Capacity = TUN_RING_CAPACITY(Rrb->Receive.RingSize); Ctx->Device.Receive.Capacity = TUN_RING_CAPACITY(Rrb->Receive.RingSize);
if (Status = STATUS_INVALID_PARAMETER, if (Status = STATUS_INVALID_PARAMETER,
(Ctx->Device.Receive.Capacity < TUN_MIN_RING_CAPACITY || Ctx->Device.Receive.Capacity > TUN_MAX_RING_CAPACITY || (Ctx->Device.Receive.Capacity < TUN_MIN_RING_CAPACITY || Ctx->Device.Receive.Capacity > TUN_MAX_RING_CAPACITY ||
@ -659,8 +655,8 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
if (!NT_SUCCESS( if (!NT_SUCCESS(
Status = ObReferenceObjectByHandle( Status = ObReferenceObjectByHandle(
Rrb->Receive.TailMoved, Rrb->Receive.TailMoved,
SYNCHRONIZE | EVENT_MODIFY_STATE, /* We need to clear recv ring TailMoved event on transition to /* We need to clear receive ring TailMoved event on transition to non-alertable state. */
non-alertable state. */ SYNCHRONIZE | EVENT_MODIFY_STATE,
*ExEventObjectType, *ExEventObjectType,
UserMode, UserMode,
&Ctx->Device.Receive.TailMoved, &Ctx->Device.Receive.TailMoved,
@ -684,7 +680,6 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
KeClearEvent(&Ctx->Device.Disconnected); KeClearEvent(&Ctx->Device.Disconnected);
/* Spawn receiver thread. */
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
if (Status = NDIS_STATUS_FAILURE, if (Status = NDIS_STATUS_FAILURE,
@ -718,7 +713,7 @@ cleanupResetOwner:
} }
_IRQL_requires_max_(PASSIVE_LEVEL) _IRQL_requires_max_(PASSIVE_LEVEL)
static void static VOID
TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner) TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner)
{ {
if (InterlockedCompareExchangePointer(&Ctx->Device.Owner, NULL, Owner) != Owner) if (InterlockedCompareExchangePointer(&Ctx->Device.Owner, NULL, Owner) != Owner)
@ -751,6 +746,45 @@ TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner)
ObDereferenceObject(Ctx->Device.Send.TailMoved); ObDereferenceObject(Ctx->Device.Send.TailMoved);
} }
static NTSTATUS TunInitializeDispatchSecurityDescriptor(VOID)
{
NTSTATUS Status;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
SID LocalSystem = { 0 };
if (!NT_SUCCESS(Status = RtlInitializeSid(&LocalSystem, &NtAuthority, 1)))
return Status;
LocalSystem.SubAuthority[0] = 18;
struct
{
ACL Dacl;
ACCESS_ALLOWED_ACE AceFiller;
SID SidFiller;
} DaclStorage = { 0 };
if (!NT_SUCCESS(Status = RtlCreateAcl(&DaclStorage.Dacl, sizeof(DaclStorage), ACL_REVISION)))
return Status;
ACCESS_MASK AccessMask = GENERIC_ALL;
RtlMapGenericMask(&AccessMask, IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(Status = RtlAddAccessAllowedAce(&DaclStorage.Dacl, ACL_REVISION, AccessMask, &LocalSystem)))
return Status;
SECURITY_DESCRIPTOR SecurityDescriptor = { 0 };
if (!NT_SUCCESS(Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)))
return Status;
if (!NT_SUCCESS(Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, &DaclStorage.Dacl, FALSE)))
return Status;
SecurityDescriptor.Control |= SE_DACL_PROTECTED;
ULONG RequiredBytes = 0;
Status = RtlAbsoluteToSelfRelativeSD(&SecurityDescriptor, NULL, &RequiredBytes);
if (Status != STATUS_BUFFER_TOO_SMALL)
return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
TunDispatchSecurityDescriptor = ExAllocatePoolWithTag(NonPagedPoolNx, RequiredBytes, TUN_MEMORY_TAG);
if (!TunDispatchSecurityDescriptor)
return STATUS_INSUFFICIENT_RESOURCES;
Status = RtlAbsoluteToSelfRelativeSD(&SecurityDescriptor, TunDispatchSecurityDescriptor, &RequiredBytes);
if (!NT_SUCCESS(Status))
return Status;
return STATUS_SUCCESS;
}
_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) _Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
static DRIVER_DISPATCH_PAGED TunDispatchDeviceControl; static DRIVER_DISPATCH_PAGED TunDispatchDeviceControl;
_Use_decl_annotations_ _Use_decl_annotations_
@ -760,13 +794,33 @@ TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
IO_STACK_LOCATION *Stack = IoGetCurrentIrpStackLocation(Irp); IO_STACK_LOCATION *Stack = IoGetCurrentIrpStackLocation(Irp);
if (Stack->Parameters.DeviceIoControl.IoControlCode != TUN_IOCTL_REGISTER_RINGS) if (Stack->Parameters.DeviceIoControl.IoControlCode != TUN_IOCTL_REGISTER_RINGS)
return NdisDispatchDeviceControl(DeviceObject, Irp); return NdisDispatchDeviceControl(DeviceObject, Irp);
ExAcquireResourceSharedLite(&TunCtxDispatchGuard, TRUE);
SECURITY_SUBJECT_CONTEXT SubjectContext;
SeCaptureSubjectContext(&SubjectContext);
NTSTATUS Status;
ACCESS_MASK GrantedAccess;
BOOLEAN HasAccess = SeAccessCheck(
TunDispatchSecurityDescriptor,
&SubjectContext,
FALSE,
FILE_WRITE_DATA,
0,
NULL,
IoGetFileObjectGenericMapping(),
Irp->RequestorMode,
&GrantedAccess,
&Status);
SeReleaseSubjectContext(&SubjectContext);
if (!HasAccess)
goto cleanup;
ExAcquireResourceSharedLite(&TunDispatchCtxGuard, TRUE);
#pragma warning(suppress : 28175) #pragma warning(suppress : 28175)
TUN_CTX *Ctx = DeviceObject->Reserved; TUN_CTX *Ctx = DeviceObject->Reserved;
NTSTATUS Status = NDIS_STATUS_ADAPTER_NOT_READY; Status = NDIS_STATUS_ADAPTER_NOT_READY;
if (Ctx) if (Ctx)
Status = TunRegisterBuffers(Ctx, Irp); Status = TunRegisterBuffers(Ctx, Irp);
ExReleaseResourceLite(&TunCtxDispatchGuard); ExReleaseResourceLite(&TunDispatchCtxGuard);
cleanup:
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -779,12 +833,12 @@ _Use_decl_annotations_
static NTSTATUS static NTSTATUS
TunDispatchClose(DEVICE_OBJECT *DeviceObject, IRP *Irp) TunDispatchClose(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{ {
ExAcquireResourceSharedLite(&TunCtxDispatchGuard, TRUE); ExAcquireResourceSharedLite(&TunDispatchCtxGuard, TRUE);
#pragma warning(suppress : 28175) #pragma warning(suppress : 28175)
TUN_CTX *Ctx = DeviceObject->Reserved; TUN_CTX *Ctx = DeviceObject->Reserved;
if (Ctx) if (Ctx)
TunUnregisterBuffers(Ctx, IoGetCurrentIrpStackLocation(Irp)->FileObject); TunUnregisterBuffers(Ctx, IoGetCurrentIrpStackLocation(Irp)->FileObject);
ExReleaseResourceLite(&TunCtxDispatchGuard); ExReleaseResourceLite(&TunDispatchCtxGuard);
return NdisDispatchClose(DeviceObject, Irp); return NdisDispatchClose(DeviceObject, Irp);
} }
@ -794,9 +848,7 @@ static NDIS_STATUS
TunRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters) TunRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)
{ {
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext; TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
InterlockedOr(&Ctx->Flags, TUN_FLAGS_RUNNING); InterlockedOr(&Ctx->Flags, TUN_FLAGS_RUNNING);
return NDIS_STATUS_SUCCESS; return NDIS_STATUS_SUCCESS;
} }
@ -820,7 +872,7 @@ TunPause(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS Min
static MINIPORT_DEVICE_PNP_EVENT_NOTIFY TunDevicePnPEventNotify; static MINIPORT_DEVICE_PNP_EVENT_NOTIFY TunDevicePnPEventNotify;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunDevicePnPEventNotify(NDIS_HANDLE MiniportAdapterContext, PNET_DEVICE_PNP_EVENT NetDevicePnPEvent) TunDevicePnPEventNotify(NDIS_HANDLE MiniportAdapterContext, PNET_DEVICE_PNP_EVENT NetDevicePnPEvent)
{ {
} }
@ -988,7 +1040,7 @@ cleanupFreeCtx:
static MINIPORT_HALT TunHaltEx; static MINIPORT_HALT TunHaltEx;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunHaltEx(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction) TunHaltEx(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction)
{ {
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext; TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
@ -1002,14 +1054,14 @@ TunHaltEx(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction)
InterlockedExchangePointer(&Ctx->MiniportAdapterHandle, NULL); InterlockedExchangePointer(&Ctx->MiniportAdapterHandle, NULL);
#pragma warning(suppress : 28175) #pragma warning(suppress : 28175)
InterlockedExchangePointer(&Ctx->FunctionalDeviceObject->Reserved, NULL); InterlockedExchangePointer(&Ctx->FunctionalDeviceObject->Reserved, NULL);
ExAcquireResourceExclusiveLite(&TunCtxDispatchGuard, TRUE); /* Ensure above change is visible to all readers. */ ExAcquireResourceExclusiveLite(&TunDispatchCtxGuard, TRUE); /* Ensure above change is visible to all readers. */
ExReleaseResourceLite(&TunCtxDispatchGuard); ExReleaseResourceLite(&TunDispatchCtxGuard);
ExFreePoolWithTag(Ctx, TUN_MEMORY_TAG); ExFreePoolWithTag(Ctx, TUN_MEMORY_TAG);
} }
static MINIPORT_SHUTDOWN TunShutdownEx; static MINIPORT_SHUTDOWN TunShutdownEx;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunShutdownEx(NDIS_HANDLE MiniportAdapterContext, NDIS_SHUTDOWN_ACTION ShutdownAction) TunShutdownEx(NDIS_HANDLE MiniportAdapterContext, NDIS_SHUTDOWN_ACTION ShutdownAction)
{ {
} }
@ -1201,7 +1253,7 @@ TunOidRequest(NDIS_HANDLE MiniportAdapterContext, PNDIS_OID_REQUEST OidRequest)
static MINIPORT_CANCEL_OID_REQUEST TunCancelOidRequest; static MINIPORT_CANCEL_OID_REQUEST TunCancelOidRequest;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunCancelOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId) TunCancelOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId)
{ {
} }
@ -1225,7 +1277,7 @@ TunDirectOidRequest(NDIS_HANDLE MiniportAdapterContext, PNDIS_OID_REQUEST OidReq
static MINIPORT_CANCEL_DIRECT_OID_REQUEST TunCancelDirectOidRequest; static MINIPORT_CANCEL_DIRECT_OID_REQUEST TunCancelDirectOidRequest;
_Use_decl_annotations_ _Use_decl_annotations_
static void static VOID
TunCancelDirectOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId) TunCancelDirectOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId)
{ {
} }
@ -1253,7 +1305,8 @@ static VOID
TunUnload(PDRIVER_OBJECT DriverObject) TunUnload(PDRIVER_OBJECT DriverObject)
{ {
NdisMDeregisterMiniportDriver(NdisMiniportDriverHandle); NdisMDeregisterMiniportDriver(NdisMiniportDriverHandle);
ExDeleteResourceLite(&TunCtxDispatchGuard); ExDeleteResourceLite(&TunDispatchCtxGuard);
ExFreePoolWithTag(TunDispatchSecurityDescriptor, TUN_MEMORY_TAG);
} }
DRIVER_INITIALIZE DriverEntry; DRIVER_INITIALIZE DriverEntry;
@ -1263,13 +1316,16 @@ DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
{ {
NTSTATUS Status; NTSTATUS Status;
if (!NT_SUCCESS(Status = TunInitializeDispatchSecurityDescriptor()))
return Status;
NdisVersion = NdisGetVersion(); NdisVersion = NdisGetVersion();
if (NdisVersion < NDIS_MINIPORT_VERSION_MIN) if (NdisVersion < NDIS_MINIPORT_VERSION_MIN)
return NDIS_STATUS_UNSUPPORTED_REVISION; return NDIS_STATUS_UNSUPPORTED_REVISION;
if (NdisVersion > NDIS_MINIPORT_VERSION_MAX) if (NdisVersion > NDIS_MINIPORT_VERSION_MAX)
NdisVersion = NDIS_MINIPORT_VERSION_MAX; NdisVersion = NDIS_MINIPORT_VERSION_MAX;
ExInitializeResourceLite(&TunCtxDispatchGuard); ExInitializeResourceLite(&TunDispatchCtxGuard);
NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniport = { NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniport = {
.Header = { .Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS, .Header = { .Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,
@ -1304,7 +1360,11 @@ DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
}; };
Status = NdisMRegisterMiniportDriver(DriverObject, RegistryPath, NULL, &miniport, &NdisMiniportDriverHandle); Status = NdisMRegisterMiniportDriver(DriverObject, RegistryPath, NULL, &miniport, &NdisMiniportDriverHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
ExDeleteResourceLite(&TunDispatchCtxGuard);
ExFreePoolWithTag(TunDispatchSecurityDescriptor, TUN_MEMORY_TAG);
return Status; return Status;
}
NdisDispatchDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]; NdisDispatchDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
NdisDispatchClose = DriverObject->MajorFunction[IRP_MJ_CLOSE]; NdisDispatchClose = DriverObject->MajorFunction[IRP_MJ_CLOSE];