MULTIPLE_IRP_COMPLETE_REQUESTS

Тема в разделе "WASM.NT.KERNEL", создана пользователем Mika0x65, 20 авг 2011.

  1. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Мое почтение всем.

    Пишу WDM драйвер. Один из обработчиков IRP_MJ_DEVICE_CONTROL вызывает BSoD MULTIPLE_IRP_COMPLETE_REQUESTS. Детали: для IRP ставится completion routine, которая вызывается только один раз (что больше всего меня смущает). BSoD происходит при закрытии приложения в случае, если есть не обработанные IRP.

    Код (Text):
    1. 1: kd> !analyze -v
    2. *******************************************************************************
    3. *                                                                             *
    4. *                        Bugcheck Analysis                                    *
    5. *                                                                             *
    6. *******************************************************************************
    7.  
    8. MULTIPLE_IRP_COMPLETE_REQUESTS (44)
    9. A driver has requested that an IRP be completed (IoCompleteRequest()), but
    10. the packet has already been completed.  This is a tough bug to find because
    11. the easiest case, a driver actually attempted to complete its own packet
    12. twice, is generally not what happened.  Rather, two separate drivers each
    13. believe that they own the packet, and each attempts to complete it.  The
    14. first actually works, and the second fails.  Tracking down which drivers
    15. in the system actually did this is difficult, generally because the trails
    16. of the first driver have been covered by the second.  However, the driver
    17. stack for the current request can be found by examining the DeviceObject
    18. fields in each of the stack locations.
    19. Arguments:
    20. Arg1: 86414720, Address of the IRP
    21. Arg2: 00001bbe
    22. Arg3: 00000000
    23. Arg4: 00000000
    24.  
    25. Debugging Details:
    26. ------------------
    27.  
    28. *************************************************************************
    29. ***                                                                   ***
    30. ***                                                                   ***
    31. ***    Your debugger is not using the correct symbols                 ***
    32. ***                                                                   ***
    33. ***    In order for this command to work properly, your symbol path   ***
    34. ***    must point to .pdb files that have full type information.      ***
    35. ***                                                                   ***
    36. ***    Certain .pdb files (such as the public OS symbols) do not      ***
    37. ***    contain the required information.  Contact the group that      ***
    38. ***    provided you with these symbols if you need this command to    ***
    39. ***    work.                                                          ***
    40. ***                                                                   ***
    41. ***    Type referenced: kernel32!pNlsUserInfo                         ***
    42. ***                                                                   ***
    43. *************************************************************************
    44. *************************************************************************
    45. ***                                                                   ***
    46. ***                                                                   ***
    47. ***    Your debugger is not using the correct symbols                 ***
    48. ***                                                                   ***
    49. ***    In order for this command to work properly, your symbol path   ***
    50. ***    must point to .pdb files that have full type information.      ***
    51. ***                                                                   ***
    52. ***    Certain .pdb files (such as the public OS symbols) do not      ***
    53. ***    contain the required information.  Contact the group that      ***
    54. ***    provided you with these symbols if you need this command to    ***
    55. ***    work.                                                          ***
    56. ***                                                                   ***
    57. ***    Type referenced: kernel32!pNlsUserInfo                         ***
    58. ***                                                                   ***
    59. *************************************************************************
    60.  
    61. IRP_ADDRESS:  86414720
    62.  
    63. DEFAULT_BUCKET_ID:  DRIVER_FAULT
    64.  
    65. BUGCHECK_STR:  0x44
    66.  
    67. PROCESS_NAME:  ScannerClient.e
    68.  
    69. LAST_CONTROL_TRANSFER:  from 804f8afd to 8052a5d8
    70.  
    71. STACK_TEXT:  
    72. ee7436c8 804f8afd 00000003 ee743a24 00000000 nt!RtlpBreakWithStatusInstruction
    73. ee743714 804f96e8 00000003 864a53d0 86414720 nt!KiBugCheckDebugBreak+0x19
    74. ee743af4 804f9c37 00000044 86414720 00001bbe nt!KeBugCheck2+0x574
    75. ee743b14 804ef1e6 00000044 86414720 00001bbe nt!KeBugCheckEx+0x1b
    76. ee743b3c 804f4a03 86414720 86414760 8667ca50 nt!IopFreeIrp+0x22
    77. ee743b90 804febb5 86414760 ee743bdc ee743bd0 nt!IopCompleteRequest+0x1b7
    78. ee743be0 80502b35 00000000 00000000 00000000 nt!KiDeliverApc+0xb3
    79. ee743bf8 804fa737 00000103 864a542c 00000000 nt!KiSwapThread+0x89
    80. ee743c24 8057c97a 00000000 00000000 ee743c40 nt!KeDelayExecutionThread+0x1c9
    81. ee743c48 8057e709 014a542c 86414720 864147fc nt!IopCancelAlertedRequest+0x52
    82. ee743c64 8057f4eb 864a5478 00000103 864a53d0 nt!IopSynchronousServiceTail+0xe1
    83. ee743d00 8057804e 0000001c 00000000 00000000 nt!IopXxxControlFile+0x5c5
    84. ee743d34 8054060c 0000001c 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
    85. ee743d34 7c90eb94 0000001c 00000000 00000000 nt!KiFastCallEntry+0xfc
    86. 0012f9f0 7c90d8ef 7c801671 0000001c 00000000 ntdll!KiFastSystemCallRet
    87. 0012f9f4 7c801671 0000001c 00000000 00000000 ntdll!ZwDeviceIoControlFile+0xc
    88. 0012fa54 004305a6 0000001c 00222016 0012fb4c kernel32!DeviceIoControl+0xdd
    89. 0012ff6c 0042da47 00000001 00332fc0 00333030 ScannerClient!main+0x86
    90. [d:\src\c\scannerclient\scannerclient.c @ 36]
    91. 0012ffb8 0042d91f 0012fff0 7c816d4f 7c910738
    92. ScannerClient!__tmainCRTStartup+0x117
    93. [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 266]
    94. 0012ffc0 7c816d4f 7c910738 ffffffff 7ffd5000 ScannerClient!mainCRTStartup+0xf
    95. [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 182]
    96. 0012fff0 00000000 0042bb72 00000000 78746341 kernel32!BaseProcessStart+0x23
    97.  
    98.  
    99. STACK_COMMAND:  kb
    100.  
    101. FOLLOWUP_IP:
    102. nt!KiDeliverApc+b3
    103. 804febb5 8d55d8          lea     edx,[ebp-28h]
    104.  
    105. SYMBOL_STACK_INDEX:  6
    106.  
    107. SYMBOL_NAME:  nt!KiDeliverApc+b3
    108.  
    109. FOLLOWUP_NAME:  MachineOwner
    110.  
    111. MODULE_NAME: nt
    112.  
    113. IMAGE_NAME:  ntkrpamp.exe
    114.  
    115. DEBUG_FLR_IMAGE_TIMESTAMP:  41107b0d
    116.  
    117. FAILURE_BUCKET_ID:  0x44_nt!KiDeliverApc+b3
    118.  
    119. BUCKET_ID:  0x44_nt!KiDeliverApc+b3
    120.  
    121. Followup: MachineOwner
    122. ---------
    Кто-нибудь может объяснить отчего такое может происходить? Особенно меня удручает, что completion routine вызывается только один раз.

    Заранее благодарен.
     
  2. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    а можно код функции завершения?
     
  3. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Сокету посылаешь DevIoControl ? Винда XP. А вообще это на баг смахивает в винде. По идее уронить ядро обычным приложением - это DoS (если у тя там не стоят свои драйвера и тп).
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Да, конечно.

    ВОт так завершается:
    Код (Text):
    1. NTSTATUS InterruptEventCompletionRoutine(PDEVICE_OBJECT pDeviceObject, PIRP pIrp, PVOID pContext)
    2. {
    3.     KIRQL                Irql;
    4.     PUSB_COMPLETION_INFO pUsbCompletionInfo;
    5.     PURB                 pUrb;
    6.  
    7.     DbgPrint("InterruptEventCompletionRoutine\n");
    8.  
    9.     pUsbCompletionInfo = (PUSB_COMPLETION_INFO)pContext;
    10.  
    11.     if (pIrp ->PendingReturned)
    12.     {
    13.         IoMarkIrpPending(pIrp);
    14.     }
    15.  
    16.     if (InterlockedExchangePointer(pUsbCompletionInfo ->ListEntryIrp.pIrp, NULL) ||
    17.         InterlockedExchange(&pUsbCompletionInfo ->ListEntryIrp.CancelFlag, 1))
    18.     {
    19.         pIrp ->IoStatus.Information = pUsbCompletionInfo ->pUrb ->UrbBulkOrInterruptTransfer.TransferBufferLength;
    20.  
    21.         CleanupUsbCompletionInfo(pDeviceObject, pUsbCompletionInfo);
    22.  
    23.         return STATUS_SUCCESS;
    24.     }
    25.  
    26.     return STATUS_MORE_PROCESSING_REQUIRED;
    27. }
    Вот фрагмент вызова:

    Код (Text):
    1.         pStackLocation = IoGetNextIrpStackLocation(pIrp);
    2.  
    3.         pStackLocation ->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    4.  
    5.         pStackLocation ->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
    6.  
    7.         pStackLocation ->Parameters.Others.Argument1 = pUrb;
    8.  
    9.         pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject ->DeviceExtension;
    10.  
    11.         if (pCompletionRoutine)
    12.         {
    13.             IoSetCompletionRoutine(pIrp, pCompletionRoutine, pContext, TRUE, TRUE, TRUE);
    14.  
    15.             status = IoAcquireRemoveLock(&pDeviceExtension ->RemoveLock, pIrp);
    16.  
    17.             if (!NT_SUCCESS(status))
    18.             {
    19.                 break;
    20.             }
    21.  
    22.             status = IoCallDriver(pDeviceExtension ->pTopOfStack, pIrp);
    23.  
    24.             IoReleaseRemoveLock(&pDeviceExtension ->RemoveLock, pIrp);
    25.         }
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    TermoSINteZ
    Нет, не сокет. Это моему драйверу шлются DEVICE_CONTROL, а он передает их ниже (USB).
     
  6. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Вопросы:

    - Ты где-нибудь освобождаешь пришедший IRP самостоятельно?
    - Ты ставишь функцию отмены перед тем, как поставить IRP в очередь?
     
  7. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Mika0x65
    попробуй IoReleaseRemoveLock(&pDeviceExtension ->RemoveLock, pIrp); делать в Completion Routines твоей. перед return STATUS_SUCCESS.
     
  8. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    x64
    1. Нет, это не мой IRP, я не освобождаю его.
    2. Нет, не ставлю. Нет смысла, т.к. я получаю IRP, добавляю его в свою очередь (чтобы можно было отменить) и сразу отправляю IRP низлежащему устройству.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    TermoSINteZ
    Можно попробовать, но смысл не улавливаю.
     
  10. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Mika0x65
    Ну обычно если это не твой пакет и его надо передать ниже. то ты его передаешь перед этим подняв лок. Потом в комплетион рутине, ты лок снимаешь, обеспечив тем самым то, что приложение не будет выгружено, до того как с IRP выполнятся все действия.
     
  11. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Mika0x65

    - Какая система?
    - Имеются ли в USB-стеке не-системные драйвера (не считая твоего)?
     
  12. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Я, наверное, чего-то не догоняю, но каким образом лок удаления может предотвратить завершение процесса? Они как бы для другого предназначены. К слову, процесс будет уничтожен в любом случае, даже если у его потоков висят незавершённые запросы.
     
  13. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    А как же синхронизация с механизмом отмены?
    Каким образом ты собрался "отменять" запрос, если он уже ушёл ниже?
     
  14. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    x64
    Нет, драйверов нет. Для отмены я использую механизм, предложенный Они, он позволяет отменять полученные сверху IRP, отосланные низлежащему драйверу.
     
  15. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Черт, я полдня потратил на поиски ошибки. А произошло всего-лишь следующее:

    if (InterlockedExchangePointer(&pUsbCompletionInfo ->ListEntryIrp.pIrp, NULL) ||
    InterlockedExchange(&pUsbCompletionInfo ->ListEntryIrp.CancelFlag, 1))
    {
    pIrp ->IoStatus.Information = pUsbCompletionInfo ->pUrb ->UrbBulkOrInterruptTransfer.TransferBufferLength;

    CleanupUsbCompletionInfo(pDeviceObject, pUsbCompletionInfo);

    return STATUS_SUCCESS;
    }

    Не хватало амперсанда, а т.к. ф-ия принимает PVOID, то контроль типов не предупредил. Соответственно, повреждался _IRP::Type, а IopFreeIrp его проверяет, и если он 0, то вызывает KeBugCheck(44, ...). Короче, я сам повредил. Велик отладчик, дизассемблер и аппаратные точки останова!
     
  16. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Mika0x65
    /W4 Вам в помощь :)