-
Notifications
You must be signed in to change notification settings - Fork 490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible Confict with others WFP Solutions. #41
Comments
Thanks for the report. I was not aware of any problem so I will need to investigate. |
I could not build WFPSampler, but I tried with a combination of WinDivert driver variants and got a similar result. It seems that combining WinDivert/passthru with another WFP callout driver (that injects cloned packets) will cause packets to go into an infinite loop. I will need to look more into this. |
Assuming the above hypothesis is correct, it is not so clear that the problem can even be fixed. To elaborate: the problem can be demonstrated with two network layer WFP callout drivers that do other than drop-and-clone the original packet (such as the WFPSampler and WinDivert's passthru). Each driver inserts itself in a different WFP sublayer. What happens is this:
If true, the same problem will arise with any WFP callout driver that clones and injects packets, not just WinDivert specifically. I have not verified this so I could be wrong. This problem is not fixable since there is no practical way to tell if a packet is a clone of a previously seen packet. It would be nice if injected packets are only sent to callout drivers with a lower priority/weight rather than all drivers. This immediately prevents the possibility of loops forming. This is also the traditional "divert sockets" semantics (of which WinDivert emulates). |
Hi. |
The relevant documentation is here. It's been a while since I've looked at it. I am not sure if "PERMIT" is correct. WinDivert never "permits" traffic per se, rather the state of non-matching traffic should be as if WinDivert were never there. Also maybe PERMIT may cause the traffic to skip other WinDivert filters, I am not sure. |
Hi. Thanks for your answer. |
I am running into what I a believe is the same issue as above when we have another WinDivert based solution on the system. CPU usage is pegged split between our service and their service and all network traffic fails (although we will still block sites appropriated). I am in the process of trying the suggested fix above, but was hoping since over a year has passed someone might have more information. |
Unfortunately I do not know of a fix. Recently another user has opened a paid ticket with Microsoft regarding the issue, so hopefully a solution will be found, but I have not heard any news yet. Unless I am misunderstanding something (which is quite possible), this seems to be a design flaw in WFP itself. Basically, WFP has a mechanism for preventing a driver (such as WinDivert) from (re)considering packets injected by itself, causing an infinite loop. This is fine, but it appears that the design of WFP did not consider that the mutual infinite loops are possible between two or more drivers using the "clone / block / inject method", as explained in detail above. The reason why I think it is a design flaw is that Windows own sample driver (WFPSampler) exhibits the same problem when combined with other WFP drivers such as WinDivert. Another problem is even if a solution is found I currently cannot make any new release of WinDivert until #53 is fixed. |
I finally found an authoritative acknowledgement and response to this problem. Post is old (2013) but was somehow missed. It seems that our analysis above is basically correct, i.e. two or more drivers can enter an infinite loop using the clone-block-reinject method. Two suggested solutions from Dusty Harper:
I am not sure how this can be implemented, since each time we see the indication it looks like a brand new packet. But perhaps he means the packet's TTL counter? This is a crude way of preventing infinite loops, but may be better than nothing. It is also not the semantics we want: we want to allow the looping packet, not drop it.
This idea does not really work with WinDivert since the driver has no idea if the injected packet is copy or not. It might be possible to thread this information via the user space application (e.g. via the WinDivert address structure), however we then rely on the application to behave correctly in order to avoid infinite loops. Another idea may be to just ignore any packet |
- A partial fix for #41 - Decrements the TTL for reinjected packets. - If (TTL==0), WinDivertRecv() will fail with: ERROR_HOST_UNREACHABLE = 1232 which is better than looping.
As mentioned, the repository version of WinDivert will decrement the TTL counter for "suspicious" packets that were injected by other callout drivers. This hardens WinDivert against infinite loops caused by mutual recursion, since the looping packet will eventually be dropped. When this occurs, the |
WinDivert will now mark any packet injected by another driver as an "impostor", meaning that it did not originate from the network. Changes are: - User programs may filter impostor packets. - WinDivertSend() automatically decrements the TTL for imposter packets, see #41.
Test Environment: Windows 7 X86
1 - Install thunderbird from https://www.mozilla.org/pt-BR/thunderbird/?icn=tabz
2 - Configure email account using port 587 for smtp
3 - Compile and install WFPSampler as described at https://code.msdn.microsoft.com/windowshardware/Windows-Filtering-Platform-27553baa#content
4 - Configure WFPSampler using the command line: "WFPSampler.Exe -s BASIC_PACKET_INJECTION -l FWPM_LAYER_OUTBOUND_IPPACKET_V4 -v"
5 - Compile, install Windivert and use this command line: "passthru.exe "outbound and (ip || ipv6) and tcp and tcp.PayloadLength > 0" 1"
Result:
Note:
The text was updated successfully, but these errors were encountered: