Using Event Handle in driver passed from app or KeSetEvent Error?

Hi All,

I’m porting a PCI device Driver from WDM to KMDF.
The new KMDF driver can be worked well in Vista,but in XP it has problem.
It caused system crashed when run app for a period of time in XP.
[I doubt ISR rountine caused it a few days ago,later I found there are something wrong during my test,so there may be some other bug that caused it]

Our application created share event and use DeviceControl to pass the handle to driver.
[use METHOD_NEITHER method]
Then driver used ObReferenceObjectByHandle to validate the object handle.
In ISR routine,I first judge whether the interrupt is generated by our device.
If it is,set interrupt line to low,request DPC,then return TRUE.If not,return FALSE.
DPC callback for ISR called KeSetEvent to set the state of the share event object to Signaled.

If I didn’t called ObReferenceObjectByHandle in EvtIoDeviceControl,
[it caused KeSetEvent can not be implemented in EvtInterruptDpc]
App can run normally in XP.
[But this didn’t set the state of the share event,it didn’t meet our demand]

Someone encountered a similar problem with me?

Any help is appreciated.Thanks.

Best Regards
Zhou ChengJun

Related to the code below[Simplify]:

EvtIoDeviceControl:

WDF_REQUEST_PARAMETERS params;
WDF_REQUEST_PARAMETERS_INIT(&params);
WdfRequestGetParameters(Request, &params );
// Access the input buffer of METHOD_NEITHER Device control IRP
hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;

status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL, KernelMode, &m_EventObject, m_HandleInfo);

EvtInterruptDpc:

WdfInterruptAcquireLock(Interrupt);
if(m_EventObject)
{
KeSetEvent( (KEVENT *)m_EventObject, 0, FALSE);
}
WdfInterruptReleaseLock( Interrupt );

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Thursday, March 20, 2008 4:46 AM
Subject: [ntdev] Using Event Handle in driver passed from app or KeSetEvent
Error?

> Hi All,
>
> I’m porting a PCI device Driver from WDM to KMDF.
> The new KMDF driver can be worked well in Vista,but in XP it has problem.
> It caused system crashed when run app for a period of time in XP.
> [I doubt ISR rountine caused it a few days ago,later I found there are <br>&gt; something wrong during my test,so there may be some other bug that caused <br>&gt; it]
>

What’s the cause of the system crash? What’s the output of !analyze -v? Have
you attached windbg to the test machine and see what happens during the
crash?

> Our application created share event and use DeviceControl to pass the
> handle to driver.
> [use METHOD_NEITHER method]

Why METHOD_NEITHER? There is no reason to use METHOD_NEITHER to pass an
event handle to a driver. Use METHOD_DIRECT.

> Then driver used ObReferenceObjectByHandle to validate the object handle.

You do that to both validate the handle and to increment the reference
counter on the handle itself, so that if the user app closes the event
handle, the event doesn’t get released because the driver owns a reference
to it.
Remember to call ObDereferenceObject when the driver doesn’t need the event
any more.

> In ISR routine,I first judge whether the interrupt is generated by our
> device.
> If it is,set interrupt line to low,request DPC,then return TRUE.If
> not,return FALSE.
> DPC callback for ISR called KeSetEvent to set the state of the share event
> object to Signaled.
>
> If I didn’t called ObReferenceObjectByHandle in EvtIoDeviceControl,
> [it caused KeSetEvent can not be implemented in EvtInterruptDpc]
> App can run normally in XP.
> [But this didn’t set the state of the share event,it didn’t meet our
> demand]
>
> Someone encountered a similar problem with me?
>
> Any help is appreciated.Thanks.
>
> Best Regards
> Zhou ChengJun
>
> Related to the code below[Simplify]:
>
> EvtIoDeviceControl:
> …
> WDF_REQUEST_PARAMETERS params;
> WDF_REQUEST_PARAMETERS_INIT(&params);
> WdfRequestGetParameters(Request, &params );
> // Access the input buffer of METHOD_NEITHER Device control IRP
> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;
>
> status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL, KernelMode,
> &m_EventObject, m_HandleInfo);
> …
>

This is wrong. The handle passed from user mode is valid only in the context
of the calling process. EvtIoDeviceControl is executed in an arbitrary
context. You need to process that IOCTL from within the
EvtIoInCallerContext.

> EvtInterruptDpc:
> …
> WdfInterruptAcquireLock(Interrupt);
> if(m_EventObject)
> {
> KeSetEvent( (KEVENT *)m_EventObject, 0, FALSE);
> }
> WdfInterruptReleaseLock( Interrupt );
> …

You cannot do this. WdfInterruptAcquireLock raises the IRQL to DIRQL,
KeSetEvent must be called at IRQL <= DISPATCH_LEVEL. Why are you raising the
IRQL to DIRQL in your DPC routine?

Have a nice day
GV


Gianluca Varenni, Windows DDK MVP

CACE Technologies
http://www.cacetech.com

>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Gianluca Varenni wrote:

> Our application created share event and use DeviceControl to pass the
> handle to driver.
> [use METHOD_NEITHER method]

Why METHOD_NEITHER? There is no reason to use METHOD_NEITHER to pass
an event handle to a driver. Use METHOD_DIRECT.

If all he is passing is a handle, he should just use METHOD_BUFFERED.

> Related to the code below[Simplify]:
>
> EvtIoDeviceControl:
> …
> WDF_REQUEST_PARAMETERS params;
> WDF_REQUEST_PARAMETERS_INIT(&params);
> WdfRequestGetParameters(Request, &params );
> // Access the input buffer of METHOD_NEITHER Device control IRP
> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;
>
> status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL,
> KernelMode, &m_EventObject, m_HandleInfo);
> …
>

This is wrong. The handle passed from user mode is valid only in the
context of the calling process. EvtIoDeviceControl is executed in an
arbitrary context. You need to process that IOCTL from within the
EvtIoInCallerContext.

Also, remember that the original poster is using KMDF. He should be
using WdfRequestRetrieveInputBuffer, not touching the fields of the IRP
directly. This is what happens from trying to slap together a WDM->KMDF
port without thinking about the problem being solved.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim and Gianluca:

I’ve refrained from answer the guy because I suspect he has to
reproduce a poorly designed driver to have the same user interface. The
real answer is if he can change the interface, then why is he using an event
at all, rather than an inverted call that will not have all the problems of
an event.,


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

“Tim Roberts” wrote in message news:xxxxx@ntdev…
> Gianluca Varenni wrote:
>>
>>
>>> Our application created share event and use DeviceControl to pass the
>>> handle to driver.
>>> [use METHOD_NEITHER method]
>>
>> Why METHOD_NEITHER? There is no reason to use METHOD_NEITHER to pass an
>> event handle to a driver. Use METHOD_DIRECT.
>
> If all he is passing is a handle, he should just use METHOD_BUFFERED.
>
>
>>> Related to the code below[Simplify]:
>>>
>>> EvtIoDeviceControl:
>>> …
>>> WDF_REQUEST_PARAMETERS params;
>>> WDF_REQUEST_PARAMETERS_INIT(&params);
>>> WdfRequestGetParameters(Request, &params );
>>> // Access the input buffer of METHOD_NEITHER Device control IRP
>>> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;
>>>
>>> status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL, KernelMode,
>>> &m_EventObject, m_HandleInfo);
>>> …
>>>
>>
>> This is wrong. The handle passed from user mode is valid only in the
>> context of the calling process. EvtIoDeviceControl is executed in an
>> arbitrary context. You need to process that IOCTL from within the
>> EvtIoInCallerContext.
>
> Also, remember that the original poster is using KMDF. He should be using
> WdfRequestRetrieveInputBuffer, not touching the fields of the IRP
> directly. This is what happens from trying to slap together a WDM->KMDF
> port without thinking about the problem being solved.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>

----- Original Message -----
From: “Tim Roberts”
To: “Windows System Software Devs Interest List”
Sent: Thursday, March 20, 2008 9:55 AM
Subject: Re: [ntdev] Using Event Handle in driver passed from app or
KeSetEvent Error?

> Gianluca Varenni wrote:
>>
>>
>>> Our application created share event and use DeviceControl to pass the
>>> handle to driver.
>>> [use METHOD_NEITHER method]
>>
>> Why METHOD_NEITHER? There is no reason to use METHOD_NEITHER to pass an
>> event handle to a driver. Use METHOD_DIRECT.
>
> If all he is passing is a handle, he should just use METHOD_BUFFERED.
>

Definitely true. My brain thought BUFFERED, my fingers types DIRECT…

>
>>> Related to the code below[Simplify]:
>>>
>>> EvtIoDeviceControl:
>>> …
>>> WDF_REQUEST_PARAMETERS params;
>>> WDF_REQUEST_PARAMETERS_INIT(&params);
>>> WdfRequestGetParameters(Request, &params );
>>> // Access the input buffer of METHOD_NEITHER Device control IRP
>>> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;
>>>
>>> status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL, KernelMode,
>>> &m_EventObject, m_HandleInfo);
>>> …
>>>
>>
>> This is wrong. The handle passed from user mode is valid only in the
>> context of the calling process. EvtIoDeviceControl is executed in an
>> arbitrary context. You need to process that IOCTL from within the
>> EvtIoInCallerContext.
>
> Also, remember that the original poster is using KMDF. He should be using
> WdfRequestRetrieveInputBuffer, not touching the fields of the IRP
> directly. This is what happens from trying to slap together a WDM->KMDF
> port without thinking about the problem being solved.

Again, true. My main concern was the calling context and METHOD_NEITHER.

GV

>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;

status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL, KernelMode,
&m_EventObject, m_HandleInfo);

Is this a safe way to reference the underlying object of a user-mode handle?
Isn’t the driver supposed to validate privileges, check object types, etc.?

You are right. I’m not usually against using events, as long as you use them
in the right way (i.e. to give a hint to the user level that something
happened, it’s not a way to propagate an interrupt to user level). I’m more
concerned about the fact that the guy is probably confused about process
contexts and events, IRQLs and debugging.

Just my two cents
GV


Gianluca Varenni, Windows DDK MVP

CACE Technologies
http://www.cacetech.com
----- Original Message -----
From: “Don Burn”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Thursday, March 20, 2008 10:03 AM
Subject: Re:[ntdev] Using Event Handle in driver passed from app or
KeSetEvent Error?

> Tim and Gianluca:
>
> I’ve refrained from answer the guy because I suspect he has to
> reproduce a poorly designed driver to have the same user interface. The
> real answer is if he can change the interface, then why is he using an
> event at all, rather than an inverted call that will not have all the
> problems of an event.,
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> Website: http://www.windrvr.com
> Blog: http://msmvps.com/blogs/WinDrvr
> Remove StopSpam to reply
>
>
>
> “Tim Roberts” wrote in message news:xxxxx@ntdev…
>> Gianluca Varenni wrote:
>>>
>>>
>>>> Our application created share event and use DeviceControl to pass the
>>>> handle to driver.
>>>> [use METHOD_NEITHER method]
>>>
>>> Why METHOD_NEITHER? There is no reason to use METHOD_NEITHER to pass an
>>> event handle to a driver. Use METHOD_DIRECT.
>>
>> If all he is passing is a handle, he should just use METHOD_BUFFERED.
>>
>>
>>>> Related to the code below[Simplify]:
>>>>
>>>> EvtIoDeviceControl:
>>>> …
>>>> WDF_REQUEST_PARAMETERS params;
>>>> WDF_REQUEST_PARAMETERS_INIT(&params);
>>>> WdfRequestGetParameters(Request, &params );
>>>> // Access the input buffer of METHOD_NEITHER Device control IRP
>>>> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;
>>>>
>>>> status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL,
>>>> KernelMode, &m_EventObject, m_HandleInfo);
>>>> …
>>>>
>>>
>>> This is wrong. The handle passed from user mode is valid only in the
>>> context of the calling process. EvtIoDeviceControl is executed in an
>>> arbitrary context. You need to process that IOCTL from within the
>>> EvtIoInCallerContext.
>>
>> Also, remember that the original poster is using KMDF. He should be
>> using WdfRequestRetrieveInputBuffer, not touching the fields of the IRP
>> directly. This is what happens from trying to slap together a WDM->KMDF
>> port without thinking about the problem being solved.
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Thursday, March 20, 2008 10:43 AM
Subject: RE:[ntdev] Using Event Handle in driver passed from app or
KeSetEvent Error?

>> hEvent = (HANDLE)params.Parameters.DeviceIoControl.Type3InputBuffer;
>>
>> status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL, KernelMode,
>> &m_EventObject, m_HandleInfo);
>
> Is this a safe way to reference the underlying object of a user-mode
> handle?
> Isn’t the driver supposed to validate privileges, check object types,
> etc.?

Yes, the OP’s driver should also validate the user input, among other
things. And using METHOD_NEITHER makes things much more complicated.

If you use KMDF and METHOD_BUFFERED, validating such input is trivial.

Have a nice day
GV

>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

> > status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL, NULL,

KernelMode,
> &m_EventObject, m_HandleInfo);

Is this a safe way to reference the underlying object of a user-mode handle?

No.

Isn’t the driver supposed to validate privileges, check object types, etc.?

Yes.

The correct call is:

status = ObReferenceObjectByHandle(hEvent,EVENT_MODIFY_STATE,
*ExEventObjectType, Irp->RequestorMode, &m_EventObject, m_HandleInfo);


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com