locked
Injection @ FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET RRS feed

  • Question

  • I'm trying to re-inject NBL at FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET layer. Tried to do outbound and inbound injection but in either case after a few dozen bytes are received ALE layer does not see most of inbound traffic. Here's callout function I use:

    void NTAPI InboundEthernetCallout(const FWPS_INCOMING_VALUES0*          inFixedValues,
                                                       FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
                                                       PVOID                                                   layerData,
                                                       const void*                                           classifyContext,
                                                       const FWPS_FILTER1*                            filter,
                                                       UINT64                                                 flowContext,
                                                       FWPS_CLASSIFY_OUT0*                        classifyOut)
    {       
        UNREFERENCED_PARAMETER(classifyContext);   
        UNREFERENCED_PARAMETER(flowContext);

        if (classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
        {
            classifyOut->actionType = FWP_ACTION_PERMIT;
        }

        if (inMetaValues->l2Flags & FWPS_L2_INCOMING_FLAG_RECLASSIFY_MULTI_DESTINATION)
        {       
            return;
        }

        const PNET_BUFFER_LIST pNBL = static_cast<const PNET_BUFFER_LIST>(layerData);

        FWPS_PACKET_INJECTION_STATE iState = FwpsQueryPacketInjectionState(m_hInjectionHandle,
                                                                                                                     pNBL,
                                                                                                                     NULL);

        if ((iState == FWPS_PACKET_INJECTED_BY_SELF) || (iState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF))
        {       
            return;
        }

        ULONG ulBytesRetreated = 0;

        if (FWPS_IS_L2_METADATA_FIELD_PRESENT(inMetaValues, FWPS_L2_METADATA_FIELD_ETHERNET_MAC_HEADER_SIZE))
        {
            ulBytesRetreated = inMetaValues->ethernetMacHeaderSize;
        }

        NTSTATUS ulStatus = STATUS_SUCCESS;

        if (ulBytesRetreated)
        {       
            ulStatus = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB(pNBL),
                                                                         ulBytesRetreated,
                                                                         0,
                                                                         0);
            if (ulStatus != STATUS_SUCCESS)
            {
                return;
            }
        }


        PNET_BUFFER_LIST pNewNBL = NULL;

        ulStatus = FwpsAllocateCloneNetBufferList(pNBL, NULL, NULL, 0, &pNewNBL);

        if (ulBytesRetreated)
        {       
            NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB(pNBL),
                                                           ulBytesRetreated,
                                                           FALSE,
                                                          0);
        }

        if (!NT_SUCCESS(ulStatus))
        {
            return;
        }

        UINT32 ulItfIndex = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_MAC_FRAME_ETHERNET_INTERFACE_INDEX].value.uint32;
        UINT32 ulNdisPort = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_MAC_FRAME_ETHERNET_NDIS_PORT].value.uint32;

        ulStatus = FwpsInjectMacReceiveAsync(CDriver::m_hInjectionHandle,
                                             NULL,
                                             0,
                                             inFixedValues->layerId,
                                             ulItfIndex,
                                             ulNdisPort,
                                             pNewNBL,
                                             InjectCompletionFn,
                                             0);
        if (ulStatus == STATUS_SUCCESS)
        {
            classifyOut->actionType = FWP_ACTION_BLOCK;

            classifyOut->flags  |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
            classifyOut->rights ^= FWPS_RIGHT_ACTION_WRITE;
        }
    }

    void NTAPI InjectCompletionFn(VOID*                    context,
                                                  NET_BUFFER_LIST* netBufferList,
                                                  BOOLEAN               dispatchLevel)
    {
        UNREFERENCED_PARAMETER(context);
        UNREFERENCED_PARAMETER(dispatchLevel);       

        FwpsFreeCloneNetBufferList(netBufferList, 0);
    }

    Am I doing something wrong? Nothing in callout function fails. Similar approach works fine for FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET layer.

    Thanks!

    Nikos.

    Thursday, November 8, 2012 11:32 PM

All replies

  • Nothing stands out to me as to what could be wrong.  You mention that nothing in the callout function fails, but what about the completionFn?  What does the netBufferList->Status show? Have you walked the functions in the failure cases?

    Hope this helps,


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------

    Friday, November 9, 2012 6:37 PM
    Moderator
  • netBufferList->Status is always STATUS_SUCCESS. This happens on clean Win8 (i.e. without any 3rd party software installed) either in VMWare environment or on physical machine.

    Once the problem occurs stopping injection driver does not help to restore networking. Adapter must be re-enabled to fix this. This may indicate that there's something interesting going on in WFP NDIS LW fitler driver.

    One time OS bugchecked:

    DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
    An attempt was made to access a pageable (or completely invalid) address at an
    interrupt request level (IRQL) that is too high.  This is usually
    caused by drivers using improper addresses.
    If kernel debugger is available get stack backtrace.
    Arguments:
    Arg1: 00000014, memory referenced
    Arg2: 00000002, IRQL
    Arg3: 00000000, value 0 = read operation, 1 = write operation
    Arg4: 81d1ec7e, address which referenced memory

    Debugging Details:
    ------------------


    READ_ADDRESS: GetPointerFromAddress: unable to read from 8142d470
    Unable to read MiSystemVaType memory at 81403080
     00000014

    CURRENT_IRQL:  2

    FAULTING_IP:
    ndis!ndisSortNetBufferLists+a1
    81d1ec7e 8b4114          mov     eax,dword ptr [ecx+14h]

    CUSTOMER_CRASH_COUNT:  1

    DEFAULT_BUCKET_ID:  WIN8_DRIVER_FAULT

    BUGCHECK_STR:  AV

    PROCESS_NAME:  System

    TAG_NOT_DEFINED_c000000f:  FFFFFFFF81058000

    TRAP_FRAME:  810546dc -- (.trap 0xffffffff810546dc)
    ErrCode = 00000000
    eax=93602990 ebx=93600000 ecx=00000000 edx=936028e0 esi=85af600c edi=0000000a
    eip=81d1ec7e esp=81054750 ebp=8105479c iopl=0         nv up ei pl zr na pe nc
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246
    ndis!ndisSortNetBufferLists+0xa1:
    81d1ec7e 8b4114          mov     eax,dword ptr [ecx+14h] ds:0023:00000014=????????
    Resetting default scope

    LAST_CONTROL_TRANSFER:  from 81346a70 to 812cf234

    STACK_TEXT: 
    810546bc 81346a70 0000000a 00000014 00000002 nt!KiBugCheck2
    810546bc 81d1ec7e 0000000a 00000014 00000002 nt!KiTrap0E+0x2c8
    8105479c 81d24742 85af600c 00000001 00000005 ndis!ndisSortNetBufferLists+0xa1
    810547e4 81d7142a 885a30e8 887f6a20 00000000 ndis!ndisMTopReceiveNetBufferLists+0x111
    81054860 81d1fba7 887f6a20 00000000 00000009 ndis! ?? ::FNODOBFM::`string'+0x90a9
    810548ac 8f341c12 885a30e8 887f6a20 00000000 ndis!NdisMIndicateReceiveNetBufferLists+0x155
    WARNING: Stack unwind information not available. Following frames may be wrong.
    810548d4 8f33f9c4 88725000 00000000 00000009 e1i6332+0x1cc12
    81054918 8f3334c8 88725000 8872fcc0 00000000 e1i6332+0x1a9c4
    81054954 8f3332dc 00000000 00000000 827c0001 e1i6332+0xe4c8
    81054994 81d1e985 827c0001 01000000 00000000 e1i6332+0xe2dc
    81054a28 813bc788 887d7914 887d7818 00000000 ndis!ndisInterruptDpc+0x188
    81054ae0 813bc3d2 8142a0c0 81054b28 a41447c0 nt!KiExecuteAllDpcs+0x1f2
    81054c00 813480d4 00000000 0000000e 00000000 nt!KiRetireDpcList+0xed
    81054c04 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x38


    STACK_COMMAND:  kb

    FOLLOWUP_IP:
    e1i6332+1cc12
    8f341c12 ??              ???

    SYMBOL_STACK_INDEX:  6

    SYMBOL_NAME:  e1i6332+1cc12

    FOLLOWUP_NAME:  MachineOwner

    MODULE_NAME: e1i6332

    IMAGE_NAME:  e1i6332.sys

    DEBUG_FLR_IMAGE_TIMESTAMP:  4f4eeba8

    FAILURE_BUCKET_ID:  AV_e1i6332+1cc12

    BUCKET_ID:  AV_e1i6332+1cc12

    Followup: MachineOwner
    ---------

    0: kd> .trap 0xffffffff810546dc
    ErrCode = 00000000
    eax=93602990 ebx=93600000 ecx=00000000 edx=936028e0 esi=85af600c edi=0000000a
    eip=81d1ec7e esp=81054750 ebp=8105479c iopl=0         nv up ei pl zr na pe nc
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246
    ndis!ndisSortNetBufferLists+0xa1:
    81d1ec7e 8b4114          mov     eax,dword ptr [ecx+14h] ds:0023:00000014=????????


    • Edited by Nikos_K Saturday, November 10, 2012 12:10 AM
    Saturday, November 10, 2012 12:03 AM
  • After some debugging I came to conclusion that the problem is caused by the presence of second FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET filter registered in the system. If only single filter is registered injection works fine. However if second FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET filter is registered even at different sublayer with different CONDITIONs the problem starts showing itself. I believe this is WFP bug. No such problem occurs in case injection is performed for outbound traffic at FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET layer even if multiple filters are registered.

    My exact test scenario: 1 persistent FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET filter/callout with condition to see only ARP traffic and 1 non-persistent FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET filter/callout for all traffic that the driver registers at start time and unregisters at unload time. No driver using first filter is loaded. Second filter/callout is used for re-injection of inbound NBLs.

    The first filter is at UNIVERSAL_SUBLAYER, second at sublayer the driver adds. Such setup causes the problem described above. If first filter/callout is not registered no problem occurs. Both filters have ActionType set to FWP_ACTION_CALLOUT_UNKNOWN.



    • Edited by Nikos_K Saturday, November 10, 2012 6:21 AM
    Saturday, November 10, 2012 6:10 AM
  • More investigation shows that if more than one FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET filter is registered inbound NBLs get messed up. CurrentMdlOffset in NB's MDL is bad in most NBLs. As a result FwpsAllocateCloneNetBufferList() does not copy the entire NB data buffer:

     FwpsAllocateCloneNetBufferList(pNBL, NULL, NULL, 0, &pNewNBL);

     ULONG ulOriginalNBSize = NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pNBL));
     ULONG ulNewNBSize = NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pNewNBL));

    For most inbound NBLs ulOriginalNBSize > ulNewNBSize.

    Once again, this problem does not occur if only one FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET filter is registered in the system.

    This is clearly a bug in WFP that is very easy to duplicate. Please investigate, as it's very serious issue.

    Monday, November 19, 2012 6:45 PM
  • Our Sustained Engineering team has been notified of the issue you are seeing,  and should be investigating further.

    Thanks,


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------

    Monday, November 19, 2012 11:03 PM
    Moderator
  • Any news on the fix? Do you want me to write and provide you with a sample showing the problem?
    Thursday, January 10, 2013 8:27 PM
  • I also encountered some similar problems... So is there any news? Thanks!
    Thursday, May 24, 2018 10:02 AM