basil00 / Divert

WinDivert: Windows Packet Divert
https://reqrypt.org/windivert.html
Other
2.32k stars 491 forks source link

Confusion about "impostor" packet and infinite loop #332

Closed Lingxi-Li closed 1 year ago

Lingxi-Li commented 1 year ago

I'm uncertain about the impostor packet description (emphasis mine).

The Impostor flag is set for impostor packets. An impostor packet is any packet injected by another driver rather than originating from the network or Windows TCP/IP stack. Impostor packets are problematic since they can cause infinite loops, where a packet injected by WinDivertSend() is captured again by WinDivertRecv().

I suppose "by another driver" means by drivers other than WinDivert. So packet spawned and injected by WinDivert that neither originates from network nor OS TCP/IP stack won't be captured again by WinDivert. Yet, later on it's also said that "packet injected by WinDivertSend() is captured again by WinDivertRecv()", defeating my initial understanding.

I looked at the netfilter example, where I see no special handling about the WinDivert spawned and injected packet, say TCP RST. So I guess my initial understanding is correct, right? Otherwise, the spawned TCP RST will be captured again by WinDivert, causing infinite loop.

Could you help clarify? Thanks~

basil00 commented 1 year ago

You can read more about it in #41.

Basically, the underlying kernel WFP framework cannot prevent packets getting stuck in infinite capture+reinject loops between two or more drivers. This is an apparent design flaw, since the case for a single driver is accounted for. To mitigate this problem, WinDivert marks potential problematic packets as "impostor" and decrements the TTL.

It is only a problem if such a capture+reinject can exist in the first place. For example, if the filter used by WinDivertRecv() does not match any packet injected by WinDivertSend(), then no loop can exist and there will be no problem.