none
Cannot ping localhost (127.0.0.1) or its own IP address after calling FwpsAcquireWritableLayerDataPointer RRS feed

  • Question

  • I have a callout driver that redirects certain destination to localhost. I am seeing a strange problem. This is Windows Server 2012 R2. Once my driver is installed, I can no longer ping 127.0.0.1 or ping its own IP address. Pinging any IP address outside works fine. Un-install my driver, ping itself works again. I have narrowed down to the call of FwpsAcquireWritableLayerDataPointer. If I just call below test code, ping 127.0.0.1 won't work. Since I only run this code for FWPS_LAYER_ALE_CONNECT_REDIRECT_V4, I can still ping localhost using IPv6. I cannot find any clue from either MSDN document or WFPSampler code. Has anyone seen the similar issue?

        status = FwpsAcquireWritableLayerDataPointer(pRedirectData->classifyHandle,
                    pFilter->filterId,
                    0,
                    &pRedirectData->pData,
                    pClassifyOut);
        if (!NT_SUCCESS(status)) {
            MyLogging("%s fail to acquire writable data 0x%X\n", __FUNCTION__, status);
        }
        else {
            if (NULL != pRedirectData->pData) {
                FwpsApplyModifiedLayerData(pRedirectData->classifyHandle, pRedirectData->pData,
                    FWPS_CLASSIFY_FLAG_REAUTHORIZE_IF_MODIFIED_BY_OTHERS);
            }
            if (0 != pRedirectData->classifyHandle) {
                FwpsReleaseClassifyHandle(pRedirectData->classifyHandle);
                pRedirectData->classifyHandle = 0;
            }
        }

    Friday, June 3, 2016 7:13 PM

All replies

  • Hello DanLi

    1)You are redirecting certain destination to localhost, Is that working? You may need to set redirectHandle & localPID for win8+

    2) FwpsAcquireWritableLayerDataPointer doesn't do anything unless u change its members, It seems its something else or the logic of your callout thats messing up the localhost ping.

    Posting a lil snapshot of your callout might shed some light on whats wrong



    ___________ Regards Umar Yaqoob ___________

    Wednesday, July 27, 2016 2:21 PM
  • Yes. Redirect certain destination to localhost works fine. I do set PID. (another interesting observation, PID doesn't need to be match the process requested, as long as it is non-0. I guess it is only used when multiple processes try to do redirect)

    I test it again, testRedirectV4 is the function that is called by pCallout->classifyFn. The code post here is the actual code I test. Doesn't even need to call FwpsApplyModifiedLayerData.

    NTSTATUS testRedirectV4(_Inout_ PCLASSIFY_DATA pClassifyData)
    {
        NTSTATUS status = STATUS_SUCCESS;
        PREDIRECT_DATA pRedirectData;

        UNREFERENCED_PARAMETER(pClassifyData);
        pRedirectData = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(REDIRECT_DATA),
                            MY_DRIVER_TAG);
        if (NULL == pRedirectData) {
            logit( "%s fails to allocate memory for redirect data\n", __FUNCTION__);
            status = STATUS_NO_MEMORY;
            goto exit_point;
        }
        memset(pRedirectData, 0, sizeof(REDIRECT_DATA));
        status = FwpsAcquireClassifyHandle((VOID *)(pClassifyData->pClassifyContext),
                            0, &pRedirectData->classifyHandle);
        if (!NT_SUCCESS(status)) {
            logit("%s fail to get classfy handle 0x%X\n", __FUNCTION__, status);
            goto exit_point;
        }
        status = FwpsAcquireWritableLayerDataPointer(pRedirectData->classifyHandle,
                    pClassifyData->pFilter->filterId,
                    0,
                    &pRedirectData->pData,
                    pClassifyData->pClassifyOut);
        if (!NT_SUCCESS(status)) {
            logit("%s fail to acquire writable data 0x%X\n", __FUNCTION__, status);
            goto exit_point;
        }

    exit_point:
        if (NULL != pRedirectData) {
            if (NULL != pRedirectData->pData) {
                FwpsApplyModifiedLayerData(pRedirectData->classifyHandle, pRedirectData->pData,
                    FWPS_CLASSIFY_FLAG_REAUTHORIZE_IF_MODIFIED_BY_OTHERS);
            }
            /**if (0 != pRedirectData->classifyHandle) {
                FwpsReleaseClassifyHandle(pRedirectData->classifyHandle);
                pRedirectData->classifyHandle = 0;
            }**/
            ExFreePoolWithTag(pRedirectData, MY_DRIVER_TAG);
        }
        return status;
    }

    Here is the code in my classifyFn callback.

    if (pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) {
          if (pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V4) {            

               if (FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                    FWPS_METADATA_FIELD_REDIRECT_RECORD_HANDLE)) {
                    VOID *pRedirectContext = 0;
                    redirectionState = FwpsQueryConnectionRedirectState(pMetadata->redirectRecords,
                        g_pDeviceContext->hRedirect,
                        &pRedirectContext);
                    logit("%s call redirect state %d\n", __FUNCTION__, redirectionState);
                }
                if (FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                    FWPS_METADATA_FIELD_PROCESS_ID)) {
                    pid = pMetadata->processId;
                }
                switch (redirectionState) {
                case FWPS_CONNECTION_NOT_REDIRECTED:
                case FWPS_CONNECTION_REDIRECTED_BY_OTHER:
                   
                    pClassifyData = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLASSIFY_DATA), MY_DRIVER_TAG);
                    if (NULL == pClassifyData) {
                        logit("%s fails to allocate memory for classify data", __FUNCTION__);
                        goto error_handling;
                    }
                    pClassifyData->pClassifyValues = pClassifyValues;
                    pClassifyData->pMetadataValues = pMetadata;
                    pClassifyData->pFilter = pFilter;
                    pClassifyData->pClassifyOut = pClassifyOut;
                    pClassifyData->pClassifyContext = pClassifyContext;
                    status = testRedirectV4(pClassifyData);
                    ExFreePoolWithTag(pClassifyData, MY_DRIVER_TAG);
                    pClassifyData = NULL;
                    break;

               case FWPS_CONNECTION_REDIRECTED_BY_SELF:
                    pClassifyOut->actionType = FWP_ACTION_PERMIT;
                    break;
                case FWPS_CONNECTION_PREVIOUSLY_REDIRECTED_BY_SELF:
                    pClassifyOut->actionType = FWP_ACTION_PERMIT;
                    break;
                default:
                    logit("%s redirect state %d is not handled", __FUNCTION__, redirectionState);
                    pClassifyOut->actionType = FWP_ACTION_PERMIT;
                    break;

    Friday, August 12, 2016 12:46 AM
  • where are you setting localRedirectTargetPID ?
    Wednesday, August 17, 2016 2:19 PM
  • I don't set it in my tst code. In real code, I set it after calling testRedirectV4 function. Does it matter? My test code won't work for redirect but I don't expect it to break anything.
    Wednesday, August 17, 2016 7:32 PM
  • I've spent quite a long time running through my driver and the conclusion I have came to (it's not documented anywhere) is that the localRedirectPid always needs set if you have called FwpsAcquireWritableLayerDataPointer for an invocation that is not a reauth - even if you don't change any of the layer data.
    Wednesday, August 17, 2016 10:55 PM
  • Hmm... still not working. I add code to assign localRedirectTargetPID after successfully calling FwpsAcquireWritableLayerDataPointer. Also call FwpsApplyModifiedLayerData afterwards.

    Thursday, August 25, 2016 10:06 PM
  • Ping is ICMP traffic, what filters are you using on your callout?
    Friday, August 26, 2016 8:21 AM
  • What do you mean of filters?

    In my test driver, for all IPv4 socket connect requests, my driver calls FwpsAcquireWritableLayerDataPointer but do nothing. I have tried both calling FwpsApplyModifiedLayerData or not calling it.

    Since in real code, one can check whether the request matches any filter, before calling FwpsAcquireWritableLayerDataPointer, I don't consider this an issue. I am just curious about it as I am not convinced that  FwpsAcquireWritableLayerDataPointer doesn't modify anything.

    Friday, August 26, 2016 4:23 PM