@@ -61,7 +61,7 @@ static NTSTATUS TriggerFatal(_In_ PDRIVER_CONTEXT Ctx, _In_ NTSTATUS Status, _In
6161 return previous ;
6262}
6363
64- static void FailClosedClassify (
64+ static void TriggerFatalAndPermitClassify (
6565 _In_ PDRIVER_CONTEXT Ctx ,
6666 _Inout_ FWPS_CLASSIFY_OUT0 * classifyOut ,
6767 _In_ NTSTATUS Status ,
@@ -70,7 +70,7 @@ static void FailClosedClassify(
7070 if (Ctx ) {
7171 TriggerFatal (Ctx , Status , Message );
7272 }
73- BlockClassify (classifyOut );
73+ PermitClassify (classifyOut );
7474}
7575
7676static BOOLEAN IsLoopbackAddress (_In_ UINT8 AddressFamily , _In_reads_ (16 ) const UINT8 * Address )
@@ -129,7 +129,7 @@ static CONFIG_SNAPSHOT ReadConfigSnapshot(_In_ PDRIVER_CONTEXT Ctx)
129129 return snapshot ;
130130}
131131
132- static NTSTATUS BestRouteForEntry (
132+ static BOOLEAN TryBestRouteForEntry (
133133 _In_ const CONFIG_SNAPSHOT * Snapshot ,
134134 _In_ const PENDING_ENTRY * Entry ,
135135 _Out_ BEST_ROUTE_RESULT * Result )
@@ -142,13 +142,13 @@ static NTSTATUS BestRouteForEntry(
142142 NETIO_STATUS status ;
143143
144144 if (!Snapshot -> HasTunLuid ) {
145- return STATUS_INVALID_DEVICE_STATE ;
145+ return FALSE ;
146146 }
147147 // GetBestRoute2 requires IRQL < DISPATCH_LEVEL. We do not currently
148148 // characterize every runtime context where route lookup can be unavailable,
149149 // so report a normal lookup failure and let the caller decide the fallback.
150150 if (KeGetCurrentIrql () >= DISPATCH_LEVEL ) {
151- return STATUS_NOT_SUPPORTED ;
151+ return FALSE ;
152152 }
153153
154154 RtlZeroMemory (& sourceAddress , sizeof (sourceAddress ));
@@ -173,19 +173,19 @@ static NTSTATUS BestRouteForEntry(
173173 sourceAddressPtr = & sourceAddress ;
174174 }
175175 } else {
176- return STATUS_INVALID_PARAMETER ;
176+ return FALSE ;
177177 }
178178
179179 status = GetBestRoute2 (NULL , 0 , sourceAddressPtr , & destinationAddress , 0 , & bestRoute , & bestSourceAddress );
180- if (status != STATUS_SUCCESS ) {
181- return status ;
180+ if (status != 0 ) {
181+ return FALSE ;
182182 }
183183 if (bestRoute .InterfaceLuid .Value == Snapshot -> TunLuid .Value ) {
184184 * Result = BestRouteTun ;
185- return STATUS_SUCCESS ;
185+ return TRUE ;
186186 }
187187 * Result = BestRouteOther ;
188- return STATUS_SUCCESS ;
188+ return TRUE ;
189189}
190190
191191static void CancelPendingIoctlRequests (_In_ PDRIVER_CONTEXT Ctx , _In_ NTSTATUS Status )
@@ -321,6 +321,7 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Regi
321321 if (!NT_SUCCESS (status )) { WdfDeviceInitFree (deviceInit ); return status ; }
322322
323323 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE (& deviceAttrs , DRIVER_CONTEXT );
324+ deviceAttrs .ExecutionLevel = WdfExecutionLevelPassive ;
324325 status = WdfDeviceCreate (& deviceInit , & deviceAttrs , & device );
325326 if (!NT_SUCCESS (status )) return status ;
326327
@@ -397,7 +398,7 @@ void EvtDriverUnload(_In_ WDFDRIVER Driver)
397398 fatalStatus = ReadFatalStatus (g_Ctx );
398399 ShutdownRedirect (
399400 g_Ctx ,
400- fatalStatus != STATUS_SUCCESS ? VERDICT_DROP : VERDICT_BYPASS ,
401+ VERDICT_PERMIT ,
401402 fatalStatus != STATUS_SUCCESS ? fatalStatus : STATUS_CANCELLED );
402403 }
403404}
@@ -485,9 +486,9 @@ void EvtIoDeviceControl(
485486
486487 case IOCTL_WINREDIRECT_STOP :
487488 if (fatalStatus != STATUS_SUCCESS ) {
488- ShutdownRedirect (ctx , VERDICT_DROP , fatalStatus );
489+ ShutdownRedirect (ctx , VERDICT_PERMIT , fatalStatus );
489490 } else {
490- ShutdownRedirect (ctx , VERDICT_BYPASS , STATUS_CANCELLED );
491+ ShutdownRedirect (ctx , VERDICT_PERMIT , STATUS_CANCELLED );
491492 }
492493 WdfRequestComplete (Request , STATUS_SUCCESS );
493494 break ;
@@ -525,6 +526,10 @@ void EvtIoDeviceControl(
525526 break ;
526527 }
527528 WINREDIRECT_VERDICT * v = (WINREDIRECT_VERDICT * )inBuf ;
529+ if (v -> Verdict != VERDICT_REDIRECT && v -> Verdict != VERDICT_PERMIT ) {
530+ WdfRequestComplete (Request , STATUS_INVALID_PARAMETER );
531+ break ;
532+ }
528533 PPENDING_ENTRY entry = PendingFindByID (ctx , v -> ConnID );
529534 if (entry ) {
530535 ExecuteVerdict (ctx , entry , v -> Verdict );
@@ -609,7 +614,7 @@ void EvtTimeoutWorkItem(_In_ WDFWORKITEM WorkItem)
609614 break ;
610615 }
611616
612- ExecuteVerdict (g_Ctx , expired , VERDICT_BYPASS );
617+ ExecuteVerdict (g_Ctx , expired , VERDICT_PERMIT );
613618 ExFreePoolWithTag (expired , 'rniW' );
614619 }
615620}
@@ -633,7 +638,7 @@ void EvtFatalWorkItem(_In_ WDFWORKITEM WorkItem)
633638 return ;
634639 }
635640
636- ShutdownRedirect (g_Ctx , VERDICT_DROP , fatalStatus );
641+ ShutdownRedirect (g_Ctx , VERDICT_PERMIT , fatalStatus );
637642}
638643
639644// --- WFP Setup ---
@@ -732,10 +737,6 @@ NTSTATUS WfpSetup(_In_ PDRIVER_CONTEXT Ctx)
732737
733738void WfpCleanup (_In_ PDRIVER_CONTEXT Ctx )
734739{
735- if (Ctx -> RedirectHandle ) {
736- FwpsRedirectHandleDestroy0 (Ctx -> RedirectHandle );
737- Ctx -> RedirectHandle = NULL ;
738- }
739740 if (Ctx -> CalloutIdV4 ) {
740741 FwpsCalloutUnregisterById0 (Ctx -> CalloutIdV4 );
741742 Ctx -> CalloutIdV4 = 0 ;
@@ -744,6 +745,10 @@ void WfpCleanup(_In_ PDRIVER_CONTEXT Ctx)
744745 FwpsCalloutUnregisterById0 (Ctx -> CalloutIdV6 );
745746 Ctx -> CalloutIdV6 = 0 ;
746747 }
748+ if (Ctx -> RedirectHandle ) {
749+ FwpsRedirectHandleDestroy0 (Ctx -> RedirectHandle );
750+ Ctx -> RedirectHandle = NULL ;
751+ }
747752 if (Ctx -> EngineHandle ) {
748753 FwpmEngineClose0 (Ctx -> EngineHandle );
749754 Ctx -> EngineHandle = NULL ;
@@ -795,7 +800,7 @@ static void ClassifyFnCommon(
795800
796801 fatalStatus = ReadFatalStatus (ctx );
797802 if (fatalStatus != STATUS_SUCCESS ) {
798- BlockClassify (classifyOut );
803+ PermitClassify (classifyOut );
799804 return ;
800805 }
801806
@@ -832,9 +837,9 @@ static void ClassifyFnCommon(
832837 }
833838
834839 // Allocate pending entry
835- entry = (PPENDING_ENTRY )ExAllocatePoolZero (PagedPool , sizeof (PENDING_ENTRY ), 'rniW' );
840+ entry = (PPENDING_ENTRY )ExAllocatePoolZero (NonPagedPoolNx , sizeof (PENDING_ENTRY ), 'rniW' );
836841 if (!entry ) {
837- FailClosedClassify (ctx , classifyOut , STATUS_INSUFFICIENT_RESOURCES , "allocate pending entry" );
842+ TriggerFatalAndPermitClassify (ctx , classifyOut , STATUS_INSUFFICIENT_RESOURCES , "allocate pending entry" );
838843 return ;
839844 }
840845 entry -> ConnID = InterlockedIncrement64 (& ctx -> NextConnID );
@@ -858,7 +863,7 @@ static void ClassifyFnCommon(
858863 RtlCopyMemory (entry -> DstAddr , dstArr -> byteArray16 , 16 );
859864 } else {
860865 ExFreePoolWithTag (entry , 'rniW' );
861- FailClosedClassify (ctx , classifyOut , STATUS_INVALID_ADDRESS_COMPONENT , "ipv6 null destination" );
866+ TriggerFatalAndPermitClassify (ctx , classifyOut , STATUS_INVALID_ADDRESS_COMPONENT , "ipv6 null destination" );
862867 return ;
863868 }
864869 }
@@ -871,16 +876,15 @@ static void ClassifyFnCommon(
871876 return ;
872877 }
873878
874- status = BestRouteForEntry (& snapshot , entry , & bestRoute );
875- // Windows auto-redirect is best-effort: only redirect connections that are
876- // positively identified as already routed to the TUN. If route lookup says
877- // "not TUN" or fails for a context we do not currently characterize, leave
878- // the original connect alone instead of redirecting or blocking unknown traffic.
879- if (!NT_SUCCESS (status ) || bestRoute == BestRouteOther ) {
879+ if (!TryBestRouteForEntry (& snapshot , entry , & bestRoute ) || bestRoute == BestRouteOther ) {
880880 ExFreePoolWithTag (entry , 'rniW' );
881881 PermitClassify (classifyOut );
882882 return ;
883883 }
884+ // Windows auto-redirect is best-effort: only redirect connections that are
885+ // positively identified as already routed to the TUN. If route lookup says
886+ // "not TUN" or fails for a context we do not currently characterize, leave
887+ // the original connect alone instead of redirecting unknown traffic.
884888
885889 // Extract PID from metadata
886890 if (FWPS_IS_METADATA_FIELD_PRESENT (inMetaValues , FWPS_METADATA_FIELD_PROCESS_ID )) {
@@ -889,15 +893,15 @@ static void ClassifyFnCommon(
889893
890894 if (!classifyContext ) {
891895 ExFreePoolWithTag (entry , 'rniW' );
892- FailClosedClassify (ctx , classifyOut , STATUS_INVALID_DEVICE_STATE , "no classify context" );
896+ TriggerFatalAndPermitClassify (ctx , classifyOut , STATUS_INVALID_DEVICE_STATE , "no classify context" );
893897 return ;
894898 }
895899
896900 // Pend the classify
897901 status = FwpsAcquireClassifyHandle0 ((void * )classifyContext , 0 , & classifyHandle );
898902 if (!NT_SUCCESS (status )) {
899903 ExFreePoolWithTag (entry , 'rniW' );
900- FailClosedClassify (ctx , classifyOut , status , "acquire classify handle" );
904+ TriggerFatalAndPermitClassify (ctx , classifyOut , status , "acquire classify handle" );
901905 return ;
902906 }
903907
@@ -910,7 +914,7 @@ static void ClassifyFnCommon(
910914 if (!NT_SUCCESS (status ) || !entry -> WritableLayerData ) {
911915 FwpsReleaseClassifyHandle0 (classifyHandle );
912916 ExFreePoolWithTag (entry , 'rniW' );
913- FailClosedClassify (ctx , classifyOut , !NT_SUCCESS (status ) ? status : STATUS_INVALID_DEVICE_STATE , "acquire writable layer data" );
917+ TriggerFatalAndPermitClassify (ctx , classifyOut , !NT_SUCCESS (status ) ? status : STATUS_INVALID_DEVICE_STATE , "acquire writable layer data" );
914918 return ;
915919 }
916920
@@ -922,7 +926,7 @@ static void ClassifyFnCommon(
922926 FWPS_CLASSIFY_FLAG_REAUTHORIZE_IF_MODIFIED_BY_OTHERS );
923927 FwpsReleaseClassifyHandle0 (classifyHandle );
924928 ExFreePoolWithTag (entry , 'rniW' );
925- FailClosedClassify (ctx , classifyOut , status , "pend classify" );
929+ TriggerFatalAndPermitClassify (ctx , classifyOut , status , "pend classify" );
926930 return ;
927931 }
928932
@@ -1038,7 +1042,7 @@ void ExecuteVerdict(_In_ PDRIVER_CONTEXT Ctx, _In_ PPENDING_ENTRY Entry, _In_ UI
10381042 redirectStatus = STATUS_INVALID_DEVICE_STATE ;
10391043 } else {
10401044 SOCKADDR_STORAGE * redirectContext =
1041- (SOCKADDR_STORAGE * )ExAllocatePoolZero (PagedPool , sizeof (SOCKADDR_STORAGE ) * 2 , 'rniW' );
1045+ (SOCKADDR_STORAGE * )ExAllocatePoolZero (NonPagedPoolNx , sizeof (SOCKADDR_STORAGE ) * 2 , 'rniW' );
10421046 if (!redirectContext ) {
10431047 redirectStatus = STATUS_INSUFFICIENT_RESOURCES ;
10441048 } else {
@@ -1084,7 +1088,7 @@ void ExecuteVerdict(_In_ PDRIVER_CONTEXT Ctx, _In_ PPENDING_ENTRY Entry, _In_ UI
10841088
10851089 if (!NT_SUCCESS (redirectStatus )) {
10861090 TriggerFatal (Ctx , redirectStatus , "execute redirect" );
1087- Verdict = VERDICT_DROP ;
1091+ Verdict = VERDICT_PERMIT ;
10881092 }
10891093 }
10901094
@@ -1096,13 +1100,8 @@ void ExecuteVerdict(_In_ PDRIVER_CONTEXT Ctx, _In_ PPENDING_ENTRY Entry, _In_ UI
10961100 Entry -> WritableLayerData = NULL ;
10971101 }
10981102
1099- if (Verdict == VERDICT_REDIRECT || Verdict == VERDICT_BYPASS ) {
1100- classifyOut .actionType = FWP_ACTION_PERMIT ;
1101- classifyOut .rights &= ~FWPS_RIGHT_ACTION_WRITE ;
1102- } else { // VERDICT_DROP
1103- classifyOut .actionType = FWP_ACTION_BLOCK ;
1104- classifyOut .rights &= ~FWPS_RIGHT_ACTION_WRITE ;
1105- }
1103+ classifyOut .actionType = FWP_ACTION_PERMIT ;
1104+ classifyOut .rights &= ~FWPS_RIGHT_ACTION_WRITE ;
11061105
11071106 FwpsCompleteClassify0 (Entry -> ClassifyHandle , 0 , & classifyOut );
11081107 FwpsReleaseClassifyHandle0 (Entry -> ClassifyHandle );
0 commit comments