none
Get rid of Bugcheck DRIVER_VERIFIER_DETECTED_VIOLATION (IrqlPsPassive) on ? RRS feed

  • Question

  • Hello,

    I'm currently working on our PC card driver (that worked fine for years). Initially I fixed a problem where the system crashed in Windows 10 due to unexpected sequence of IRP_MJ_DEVICE_CONTROL packets. Now (again Windows 10) the system crashes with DRIVER_VERIFIER_DETECTED_VIOLATION (bug check 0xC4) with arg1=0x002001c ('IrqlPsPassive'). Debugging has shown that this happens when PsCreateSystemThread() is called.

    "Easily" said: Driver verifiier expects that PsCreateSystemThread() is call when running at PASSIVE_LEVEL....

    Unfortunately, I'm not very familiar with programming drivers, and the code I have is very old. I'm able to understand what the code does in general, but at several places I need to trust in the author 's (which isn't available any more, of course) work.

    General workflow of the driver

    In general, IRP_MJ_READ and IRP_MJ_WRITE IRPs are queued to a thread since PC card is avery time consuming task. If this thread does not exit, it will created. If there are no more IRPs occour for some time, the thread will terminate automatically. This process is create using PsCreateSystemThread() function.

    Now the question

    What can/need I to do that this procedure will run at the PASSIVE_LEVEL as expected by the DriverVerifier?

    I hope you can help me. Have much thanks in before.
    Willi K.

    P.S.: Here is some relevant code that may help to understand what happens:

    // Code (simplified view)
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, ...)
    {
        ...
    
        pDrvObj->MajorFunction[IRP_MJ_READ] = MyDrv_ReadWrite;
        pDrvObj->MajorFunction[IRP_MJ_WRITE] = MyDrv_ReadWrite;
    
        ...
    }
    
    NTSTATUS MyDrv_ReadWrite(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    {
        PIO_STACK_LOCATION  pIrpStack;
        pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    
        ...
    
        switch (pIrpStack->MajorFunction) 
        {
            case IRP_MJ_READ:
            case IRP_MJ_WRITE:
                Status = MyDrv_QueueIrpToThread(pIrp, ...);
                break;
        }
        
        ...
    }
    
    NTSTATUS MyDrv_QueueIrpToThread(PIRP pIrp, PVOID pData)
    {
        ...
        OBJECT_ATTRIBUTES ObjAttributes;
        InitializeObjectAttributes(&ObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
    
        // DRIVER_VERIFIER_DETECTED_VIOLATION happens here
        Status = PsCreateSystemThread(&hThread, (ACCESS_MASK) 0L, &ObjAttributes, (HANDLE) 0L, NULL, MyDrv_Thread, pData);
        ...
    }
    
    VOID MyDrv_Thread(PVOID pData)
    {
        ...
    }


    • Edited by Willi K Tuesday, May 29, 2018 3:25 PM Improve code cample
    Tuesday, May 29, 2018 3:25 PM

Answers

  • First, just because it worked up until now, does not mean that it is bug-free.

    In your case, your MyDrv_ReadWrite dispatch routine may be called at IRQL 2 (DISPATCH_LEVEL), and calling PsCreateSystemThread from that IRQL is not allowed. It appears that the overall design of your driver needs work. Usually, DriverEntry routine would create the thread and the dispatch routine will add requests to a queue that is then worked off by the system thread, thereby avoiding the problem that you're now seeing. In a nutshell, your driver's architecture will need to be reworked.

     -Brian


    Azius Developer Training www.azius.com Windows device driver, internals, security, & forensics training and consulting. Blog at www.azius.com/blog

    Tuesday, May 29, 2018 6:24 PM
    Moderator