locked
Windows Server 2008 Beta3 Reinjecting at ALE_AUTH_RECV_ACCEPT RRS feed

  • Question

  • Hello again.  In the course of testing out my code on Windows Server 2008 Beta3 (as it is the closest thing to Vista SP1 currently available to me) I think I have come across a bug in it:

     

    On the ALE_AUTH_RECV_ACCEPT layer I am Pending a UDP packet, cloning the net buffer list (after retreating it to the ip header start), and later I Continue it and Reinject it into the transport layer receive.  While this works on Vista, on Server 2008 Beta3 I get back the error code 0xc000023e in the NBL's Status field on my InjectComplete function.  I have confirmed that my callout is called again, and that I get FWPS_PACKET_INJECTED_BY_SELF.

     

    I can only assume this is a bug in the beta, and it will be fixed for the actual release, but I wanted to make sure you know about it...

     

    Thanks,

    Jeremy

    Tuesday, June 12, 2007 7:46 PM

Answers

  • I think what was likely happening was that while you permitted the re-injected clone, the Windows firewall blocked it. From tcpip stack's point of view, the packet could not be delivered to the socket, hence it sets STATUS_PROTOCOL_UNREACHABLE (arguably not the most intuitive error code).

     

    It doesn't sound like to be your goal to inter-operate with Windows Firewall (or other WFP-based firewall). If it is, then you should add the filter into your own sub-layer and clear the FWPS_RIGHT_ACTION_WRITE flag before you PERMIT the clone. That way other firewall won't be able to veto your decision without also triggering an audit event.

     

    Hope this helps,

    Biao.W.

    Wednesday, June 13, 2007 6:54 PM

All replies

  • Jeremy,

     

    Can you dump the content of the clone right before you call FwpsInjectTransportReceiveAsync0 and paste it here? (start with MDL->MappedSystemVa + NB->DataOffset).

     

    In addition, when your completion function is invoked with 0xc000023e, can you cut-and-paste the callstack here as well?

     

    What was the action you returned when the callout was invoked again with FWPS_PACKET_INJECTED_BY_SELF?.

     

    Biao.W.

    Tuesday, June 12, 2007 10:56 PM
  •  Biao Wang [MSFT] wrote:
      

    Can you dump the content of the clone right before you call FwpsInjectTransportReceiveAsync0 and paste it here? (start with MDL->MappedSystemVa + NB->DataOffset).

     

    Code Snippet
    83ab2dce 45 00 00 31 88 13 00 00 80 11 c2 d7 c0 a8 37 01  E..1..........7.
    83ab2dde c0 a8 37 7f 0a a2 04 d2 00 1d 50 b2 54 65 73 74  ..7.......P.Test
    83ab2dee 69 6e 67 20 69 6e 63 6f 6d 69 6e 67 20 55 44 50  ing incoming UDP
    83ab2dfe 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

     

     

     Biao Wang [MSFT] wrote:
      

    In addition, when your completion function is invoked with 0xc000023e, can you cut-and-paste the callstack here as well?

    Code Snippet
    kd> kb
    ChildEBP RetAddr  Args to Child             
    89add934 82393a16 8427a390 83d4d6f8 00000000 mymodule!MyCompletionFn+0x6
    89add954 820307f1 83d4d6f8 00000001 00000000 fwpkclnt!FwppInjectComplete+0x87
    89add974 820310e8 83d4d6f8 00000000 00000000 NETIO!NetioDereferenceNetBufferList+0x68
    89add9a4 82311b9c 00000000 00000000 00000000 NETIO!NetioDereferenceNetBufferListChain+0x3a
    89add9c4 82316485 8395e000 00000000 83961cd0 tcpip!IppCompleteAndFreePacketList+0xbf
    89adda04 82311a18 8236fbc0 00000011 83b202d8 tcpip!IppReceiveHeaderBatch+0x282
    89adda94 8234978d 83b202d8 00000000 00000001 tcpip!IpFlcReceivePackets+0xbe1
    89addab4 82394aea 02000000 8396b9c0 0000000b tcpip!IppInspectInjectReceive+0xbc
    89addaf0 860382f3 839cf070 00000000 00000000 fwpkclnt!FwpsInjectTransportReceiveAsync0+0x1aa
    89addb38 8602ee79 8427b7ec 84286894 00000001 mymodule!MyOnUserReply+0x103

     

     

     Biao Wang [MSFT] wrote:
      

    What was the action you returned when the callout was invoked again with FWPS_PACKET_INJECTED_BY_SELF?.

     

    FWP_ACTION_PERMIT

     

    And, just for kicks, here is the (shallow) netBufferList struct, including the status

    Code Snippet

    kd> dt netBufferList
    Local var @ 0x89add940 Type _NET_BUFFER_LIST*
    0x83d4d6f8
       +0x000 Next             : (null)
       +0x004 FirstNetBuffer   : 0x83d4d780 _NET_BUFFER
       +0x000 Link             : _SLIST_HEADER
       +0x008 Context          : (null)
       +0x00c ParentNetBufferList : 0x83d71720 _NET_BUFFER_LIST
       +0x010 NdisPoolHandle   : 0x838fb080
       +0x018 NdisReserved     : [2] (null)
       +0x020 ProtocolReserved : [4] (null)
       +0x030 MiniportReserved : [2] (null)
       +0x038 Scratch          : (null)
       +0x03c SourceHandle     : 0x83a260e8
       +0x040 NblFlags         : 0
       +0x044 ChildRefCount    : 0
       +0x048 Flags            : 0x3000100
       +0x04c Status           : -1073741250
       +0x050 NetBufferListInfo : [11] (null)

     

    Wednesday, June 13, 2007 1:01 AM
  • Thanks for the data. I have a few more questions --

     

    1) Was Windows Firewall enabled? Does the app receive the packet if your callout simply permits AUTH_RECV_ACCEPT? I want to see whether there are other filters at play here.

     

    2) What kind of socket is this packet destined to? Is it a raw socket? If it is a standard UDP socket, do you have other promiscuous-mode raw socket listening for traffic?

     

    3) Did the socket receive the UDP data?

     

    4) I want to see the precise instruction that sets this error. Before the injection call, can you set a "break-on-access" breakpoint on the Status field and send me the callstack when the breakpoint is hit *and* the Status is set to 0xc000023e?

     

    Using the clone above as an example, you would use "ba w4 0x83d4d6f8+0x048" to set the memory breakpoint.

     

    Biao.W.

    Wednesday, June 13, 2007 3:07 AM
  •  Biao Wang [MSFT] wrote:

    1) Was Windows Firewall enabled? Does the app receive the packet if your callout simply permits AUTH_RECV_ACCEPT? I want to see whether there are other filters at play here.

     

    Oops, Windows Firewall was enabled  I thought it was not, the installer for my program has code to disable the firewall on XP SP2, and this seems to work on Vista, but did not seem to work on this box.  The problem does not reproduce if I disable windows firewall from the control panel.

     

     

     Biao Wang [MSFT] wrote:

    2) What kind of socket is this packet destined to? Is it a raw socket? If it is a standard UDP socket, do you have other promiscuous-mode raw socket listening for traffic?

    I think it is a plain UDP socket.  I used netcat.  On the box being debugged, I ran nc -u -l -p 1234, and on another box I ran nc -u 192.168.55.127 1234 and typed in something.  I don't think there are any other promiscuous-mode raw sockets on the box, it is a clean windows server 2008 beta3 web edition install without any roles or anything.

     

     Biao Wang [MSFT] wrote:

    3) Did the socket receive the UDP data?

    No

     

     Biao Wang [MSFT] wrote:

    4) I want to see the precise instruction that sets this error. Before the injection call, can you set a "break-on-access" breakpoint on the Status field and send me the callstack when the breakpoint is hit *and* the Status is set to 0xc000023e?

     

    Using the clone above as an example, you would use "ba w4 0x83d4d6f8+0x048" to set the memory breakpoint.

     

    The status was set 4 times:

    Code Snippet
    kd> ba w4 83cb0564 "dd 83cb0564"
    kd> g
    83cb0564  00000105
    tcpip!IppReceiveHeadersHelper+0x251:
    82316ac9 8b4804          mov     ecx,dword ptr [eax+4]
    kd> g
    83cb0564  00000000
    tcpip!IppReceiveHeaderBatch+0x110:
    82316313 f6868400000004  test    byte ptr [esi+84h],4
    kd> g
    83cb0564  c0220104
    tcpip!InetInspectReceiveDatagram+0x112:
    8231bccf 5f              pop     edi
    kd> g
    83cb0564  c000023e
    tcpip!IppProcessDeliverList+0x1a9:
    82316639 8b4304          mov     eax,dword ptr [ebx+4]
    kd> kb
    ChildEBP RetAddr  Args to Child             
    826ef9b0 823163e1 8236fbc0 00000011 826ef9e4 tcpip!IppProcessDeliverList+0x1a9
    826efa04 82311a18 8236fbc0 00000011 83b89938 tcpip!IppReceiveHeaderBatch+0x1de
    826efa94 8234978d 83b89938 00000000 00000001 tcpip!IpFlcReceivePackets+0xbe1
    826efab4 82394aea 02000000 8396d008 0000000b tcpip!IppInspectInjectReceive+0xbc
    826efaf0 878f62f3 83ae72d0 00000000 00000000 fwpkclnt!FwpsInjectTransportReceiveAsync0+0x1aa

     

    It seems that it tells you the instruction AFTER the access, so here is the exact instruction that sets the status:

    Code Snippet
    82316632 c7404c3e0200c0  mov     dword ptr [eax+4Ch],0C000023Eh

     

    Wednesday, June 13, 2007 5:39 PM
  • I think what was likely happening was that while you permitted the re-injected clone, the Windows firewall blocked it. From tcpip stack's point of view, the packet could not be delivered to the socket, hence it sets STATUS_PROTOCOL_UNREACHABLE (arguably not the most intuitive error code).

     

    It doesn't sound like to be your goal to inter-operate with Windows Firewall (or other WFP-based firewall). If it is, then you should add the filter into your own sub-layer and clear the FWPS_RIGHT_ACTION_WRITE flag before you PERMIT the clone. That way other firewall won't be able to veto your decision without also triggering an audit event.

     

    Hope this helps,

    Biao.W.

    Wednesday, June 13, 2007 6:54 PM