problems setting user-mode event in kernel mode, wdm/xp

problems setting user-mode event in kernel mode, wdm/xp

Post by Stephen Cowel » Thu, 27 Jun 2002 06:31:40



This is in reference to a touchscreen driver that declares itself type MOUSE
and opens the serial port via IoGetDeviceObjectPointer.  A separate device
is opened for IOCTL communication with usermode, since Mouclass reserves
reads for itself.

I'm trying to set an event passed via IOCTL from user to kernel... I'm
looking
at EVENT.EXE and can't find my problem.  I see the IOCTL come down
to kernel mode, I have a user-mode handle from the
Irp->AssociatedIrp.SystemBuffer...
I set the allocation up as a HANDLE in my device extension, but when I run
ObReferenceObjectByHandle I get '0' for the kernel mode handle... the handle
arriving in the buffer appears invalid, or something is set wrong.

I have the ioctl scheme already working for several other control codes...
I'm calling
them with METHOD_NEITHER and they work fine.

Here's a little code:

 case TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT:
  DbgOut(TS_DBG_IOCTL, ("TsIoctl():
TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT\n"));

  if (devExt->RightClickEvent == NULL)//just allow one registration
  {
   if (inBufLen < sizeof(HANDLE))
   {
    status = STATUS_INVALID_PARAMETER;
    break;
   }

   hEvent = (HANDLE) Irp->AssociatedIrp.SystemBuffer;

   status = ObReferenceObjectByHandle( hEvent,
            SYNCHRONIZE,
            *ExEventObjectType,
            KernelMode,
            &devExt->RightClickEvent,
            NULL);

   DbgOut(TS_DBG_IOCTL, ("TsIoctl(): RightClick kernel event handle = %X,
user event handle = %X\n",
    devExt->RightClickEvent, hEvent));
  }
  else
   status = STATUS_SUCCESS;
  // Don't forget to set this
  Len = sizeof(TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT);
 break;

Debug outputs:

TsIoctl(): enter -1065369576
TsIoctl(): TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT
TsIoctl(): RightClick kernel event handle = 0, user event handle = 8133EBE8
TsIoctl(): exit, status c0000008
TsDispatch(): exit, status c0000008

So obviously the handle I'm getting through the IOCTL is invalid... here's
the header entry for
the IOCTL:

//  register rightclick event with kernel
#define TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT  CTL_CODE(FILE_DEVICE_UNKNOWN,
6, METHOD_BUFFERED, FILE_ALL_ACCESS)

Here's the user-mode call to CreateFile:

void OpenKernelModeHandle()
{

 // Open touchscreen control device
 ghKernelModeHandle = CreateFile(TS_DEVICE_NAME, GENERIC_READ |
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL, OPEN_EXISTING, 0, NULL);
 // Fail if no success
 if (ghKernelModeHandle == INVALID_HANDLE_VALUE) {
  MessageBox(NULL, "cant open filter device!!!", "NOTICE", MB_OK);
  CheckDlgButton(ghWndToolbarDlg, IDC_KERNEL_MODE, TRUE);

 }

 return;

Quote:}

Here's where I send the register event IOCTL:

void RegisterKernelModeRightClickEvent()
{
 BOOL retVal;
 DWORD bytesReturned;
 DWORD sizeOfRightClickEvent;

 sizeOfRightClickEvent = sizeof(ghRightClickEvent);

 // Call Ioctl
 retVal = DeviceIoControl(ghKernelModeHandle,
TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT, &ghRightClickEvent,
sizeOfRightClickEvent, NULL, 0, &bytesReturned, NULL);
 return;

Quote:}

I create the RightClickEvent in a separate thread, set the global event
handle with the result, then call
the RegisterKernelModeRightClickEvent() routine.

I've been through Oney's example and the MS Event example... I'm not finding
my problem, any help or
hints would be most appreciated.  Thanks for reading this far.
__
Steve
.

 
 
 

problems setting user-mode event in kernel mode, wdm/xp

Post by Doron Holan [MS » Thu, 27 Jun 2002 07:38:26


you are incorrectly casting the buffer.  instead of

hEvent = (HANDLE) Irp->AssociatedIrp.SystemBuffer

it should be

hEvent = * (HANDLE*) Irp->AssociatedIrp.SystemBuffer

--
This posting is provided "AS IS" with no warranties, and confers no rights.


Quote:> This is in reference to a touchscreen driver that declares itself type
MOUSE
> and opens the serial port via IoGetDeviceObjectPointer.  A separate device
> is opened for IOCTL communication with usermode, since Mouclass reserves
> reads for itself.

> I'm trying to set an event passed via IOCTL from user to kernel... I'm
> looking
> at EVENT.EXE and can't find my problem.  I see the IOCTL come down
> to kernel mode, I have a user-mode handle from the
> Irp->AssociatedIrp.SystemBuffer...
> I set the allocation up as a HANDLE in my device extension, but when I run
> ObReferenceObjectByHandle I get '0' for the kernel mode handle... the
handle
> arriving in the buffer appears invalid, or something is set wrong.

> I have the ioctl scheme already working for several other control codes...
> I'm calling
> them with METHOD_NEITHER and they work fine.

> Here's a little code:

>  case TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT:
>   DbgOut(TS_DBG_IOCTL, ("TsIoctl():
> TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT\n"));

>   if (devExt->RightClickEvent == NULL)//just allow one registration
>   {
>    if (inBufLen < sizeof(HANDLE))
>    {
>     status = STATUS_INVALID_PARAMETER;
>     break;
>    }

>    hEvent = (HANDLE) Irp->AssociatedIrp.SystemBuffer;

>    status = ObReferenceObjectByHandle( hEvent,
>             SYNCHRONIZE,
>             *ExEventObjectType,
>             KernelMode,
>             &devExt->RightClickEvent,
>             NULL);

>    DbgOut(TS_DBG_IOCTL, ("TsIoctl(): RightClick kernel event handle = %X,
> user event handle = %X\n",
>     devExt->RightClickEvent, hEvent));
>   }
>   else
>    status = STATUS_SUCCESS;
>   // Don't forget to set this
>   Len = sizeof(TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT);
>  break;

> Debug outputs:

> TsIoctl(): enter -1065369576
> TsIoctl(): TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT
> TsIoctl(): RightClick kernel event handle = 0, user event handle =
8133EBE8
> TsIoctl(): exit, status c0000008
> TsDispatch(): exit, status c0000008

> So obviously the handle I'm getting through the IOCTL is invalid... here's
> the header entry for
> the IOCTL:

> //  register rightclick event with kernel
> #define TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT  CTL_CODE(FILE_DEVICE_UNKNOWN,
> 6, METHOD_BUFFERED, FILE_ALL_ACCESS)

> Here's the user-mode call to CreateFile:

> void OpenKernelModeHandle()
> {

>  // Open touchscreen control device
>  ghKernelModeHandle = CreateFile(TS_DEVICE_NAME, GENERIC_READ |
> GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
>           NULL, OPEN_EXISTING, 0, NULL);
>  // Fail if no success
>  if (ghKernelModeHandle == INVALID_HANDLE_VALUE) {
>   MessageBox(NULL, "cant open filter device!!!", "NOTICE", MB_OK);
>   CheckDlgButton(ghWndToolbarDlg, IDC_KERNEL_MODE, TRUE);

>  }

>  return;

> }

> Here's where I send the register event IOCTL:

> void RegisterKernelModeRightClickEvent()
> {
>  BOOL retVal;
>  DWORD bytesReturned;
>  DWORD sizeOfRightClickEvent;

>  sizeOfRightClickEvent = sizeof(ghRightClickEvent);

>  // Call Ioctl
>  retVal = DeviceIoControl(ghKernelModeHandle,
> TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT, &ghRightClickEvent,
> sizeOfRightClickEvent, NULL, 0, &bytesReturned, NULL);
>  return;
> }

> I create the RightClickEvent in a separate thread, set the global event
> handle with the result, then call
> the RegisterKernelModeRightClickEvent() routine.

> I've been through Oney's example and the MS Event example... I'm not
finding
> my problem, any help or
> hints would be most appreciated.  Thanks for reading this far.
> __
> Steve
> .


 
 
 

problems setting user-mode event in kernel mode, wdm/xp

Post by Neill Clift [MS » Thu, 27 Jun 2002 09:14:44


Somebody else has already pointed out your casting mistake so I'll mention a
few more things you might want to concider. Obviously since I can't see the
whole driver I might be completely off base here.

Your using kernel mode for the mode passed to ObReferenceObjectByHandle. By
doing this your telling the object manager that this handle came from a very
trusted source (the kernel) and so it won't do things like access checks.
The verifier will bugcheck for example if the handle is bad with this mode.
You should probably use the mode that's inside the IRP but even this might
be complicated if your something like a filesystem that's accessible over
the net via srv.sys.

A caller could repeatedly call you driver with special handle values (we
call them kernel handles) that live in the kernel handle table. If your code
set one of these events (if there are any, I would guess yes) then anything
can happen.

To set an event a caller should have EVENT_MODIFY_STATE access to an event.
You seem to be specifying the wrong access (base on what you say below). You
don't want to allow an attacker to set an event they don't have access to
set themselves.

You seem to be checking devExt->RightClickEvent  while you hold no locks.
Obviously we can't see all of the code here but race conditions look to be
an issue.
Neill

--
This posting is provided "AS IS" with no warranties, and confers no rights.


Quote:> This is in reference to a touchscreen driver that declares itself type
MOUSE
> and opens the serial port via IoGetDeviceObjectPointer.  A separate device
> is opened for IOCTL communication with usermode, since Mouclass reserves
> reads for itself.

snip
 
 
 

problems setting user-mode event in kernel mode, wdm/xp

Post by Stephen Cowel » Fri, 28 Jun 2002 04:41:09


You are the lifesaver of lifesavers... my hair can grow again!
Thanks.
__
Steve
.



Quote:> you are incorrectly casting the buffer.  instead of

> hEvent = (HANDLE) Irp->AssociatedIrp.SystemBuffer

> it should be

> hEvent = * (HANDLE*) Irp->AssociatedIrp.SystemBuffer

 
 
 

problems setting user-mode event in kernel mode, wdm/xp

Post by Stephen Cowel » Fri, 28 Jun 2002 04:48:06




Quote:> Somebody else has already pointed out your casting mistake so I'll mention
a
> few more things you might want to concider. Obviously since I can't see
the
> whole driver I might be completely off base here.

> Your using kernel mode for the mode passed to ObReferenceObjectByHandle.
By
> doing this your telling the object manager that this handle came from a
very
> trusted source (the kernel) and so it won't do things like access checks.
> The verifier will bugcheck for example if the handle is bad with this
mode.
> You should probably use the mode that's inside the IRP but even this might
> be complicated if your something like a filesystem that's accessible over
> the net via srv.sys.

Pure desperation... it used to say Irp->RequestorMode, but in debugging,
I went for the one that was most likely to succeed.  I'll swap it back when
it works!

Quote:> A caller could repeatedly call you driver with special handle values (we
> call them kernel handles) that live in the kernel handle table. If your
code
> set one of these events (if there are any, I would guess yes) then
anything
> can happen.

> To set an event a caller should have EVENT_MODIFY_STATE access to an
event.
> You seem to be specifying the wrong access (base on what you say below).
You
> don't want to allow an attacker to set an event they don't have access to
> set themselves.

again, pure desperation... it will be more robust before it leaves.

Quote:> You seem to be checking devExt->RightClickEvent  while you hold no locks.
> Obviously we can't see all of the code here but race conditions look to be
> an issue.

I plan for only one device... I could make that check more robust, but
I just wanted to prevent multiple registrations of that event.

Thanks for your interest and critiques... I'll give serious thought to
implementing
them before release.
__
Steve
.

 
 
 

problems setting user-mode event in kernel mode, wdm/xp

Post by Stephen Cowel » Sat, 29 Jun 2002 01:33:28


Still not fixed... some progress, but strange.

New Debug outputs:

TsIoctl(): enter -1065369576
TsIoctl(): TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT
TsIoctl(): RightClick kernel event handle = 8133EBE8, user event handle = 7C
TsIoctl(): exit, status 0
TsDispatch(): exit, status 0

and the event still won't signal usermode (KeSetEvent returns zero, so it's
happy).

I don't like the look of the usermode handle that results from our fix...
shouldn't
that handle be a big ugly hex number, not something nice like 7C?  Here's my
new code for the IOCTL handler:
...
   hEvent = *(HANDLE*)Irp->AssociatedIrp.SystemBuffer;

   status = ObReferenceObjectByHandle( hEvent,
            SYNCHRONIZE,
            *ExEventObjectType,
            Irp->RequestorMode,
            &devExt->RightClickEvent,
            NULL);

   DbgOut(TS_DBG_IOCTL, ("TsIoctl(): RightClick kernel event handle = %X,
user event handle = %X\n",
    devExt->RightClickEvent, hEvent));
...
and the usermode DeviceIoControl call:
...
retVal = DeviceIoControl(ghKernelModeHandle,
TS_IOCTL_REGISTER_RIGHT_CLICK_EVENT, &ghRightClickEvent,
sizeOfRightClickEvent, NULL, 0, &bytesReturned, NULL);
...

This looks just like the EVENT and EVENTTEST stuff, with the exception that
I'm not passing a
SET_EVENT struct, but an event handle.  Here's my usermode thread and call:

DWORD WINAPI RightClickThreadProc(LPVOID lpV)
{
    DWORD dwRes;
    BOOL fDone;

 fDone = FALSE;
    //
    // create synchronization event for RightClick
    //
    ghRightClickEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//manual reset,
created 'off'

 //
 // send event handle to kernel mode
 //
 RegisterKernelModeRightClickEvent();

 // wait til event is signalled, then send message to right click dialog
 // signalled event means that 1.) rightclickdialog sent kernel a right
 // click request and 2.) kernel mode fulfilled it... we should now
 // change button to left click.

    while ( !fDone ) {
        dwRes = WaitForSingleObject(ghRightClickEvent, INFINITE);
        switch(dwRes)
        {

            case WAIT_ABANDONED:
                    ErrorReporter("WaitForSingleObject(rightclick
proc)WAIT_ABANDONED)");
                    fDone = TRUE;
            break;
            case WAIT_FAILED:
                    ErrorReporter("WaitForSingleObject(rightclick
proc)WAIT_FAILED, bad handle?)");
                    fDone = TRUE;
            break;

            case WAIT_OBJECT_0:
       ResetEvent(ghRightClickEvent);
    ErrorReporter("WaitForSingleObject(rightclick proc)WAIT_OBJECT_0, object
signaled");
    SendMessage(ghWndRightClickDlg, WM_COMMAND, WM_RBUTTONUP, 0);

            break;

            default:
                    ErrorReporter("WaitForSingleObject( rightclick proc
default)");
                    fDone = TRUE;
            break;

        }
    }

    CloseHandle(ghRightClickEvent);

    return 1;

Quote:}

I'm using globals, of course... that should not be the problem.  Help!
__
Steve
.
 
 
 

1. Porting kernel-mode printer driver to user-mode

LS,

I am currently porting a printer-driver that was originally written in
kernel-mode into a user-mode driver (under the Win2K/XP DDK).

What I did was the following:
- Linked UMPDDDI.LIB, GDI32.LIB and KERNEL32.LIB.
- Defined USERMODE_DRIVER.
- Included WINDDI.H.
- Added the DrvQueryDriverInfo function.
- Set the proper version (3.0) in resource file.
- Set TARGETTYPE=DYNLINK in sources file.

The original driver consisted of 2 DLL's: a kernel-mode DLL and a separate
user-mode DLL that implements functions like: DrvSplStartDoc,
DrvSplWritePrinter etc.
Those functions are now considered obsolete and apparently are no longer
called since the moment that I have the 'main' DLL running in user-mode.

My question: How/where do I put the code from the obsolete functions in the
old user-mode DLL into the new (main) user-mode DLL?

Any reactions are greatly appreciated.
Marcel.

2. FS: RiscPC £390

3. providing memory from kernel mode for access in user-mode

4. Need help posting messages to local bboard

5. Does VxWorks use User Mode & Kernel Mode?

6. need help

7. Kernel mode vs user mode

8. FS: Toshiba Libretto 50, Melbourne

9. Does VxWorks use User Mode & Kernel Mode?

10. How detect USER Mode Application is loaded in kernel mode driver

11. Sharing memory on Kernel mode with User mode app

12. How to convert the user mode address to the kernel mode address?

13. How to map the user mode address to the kernel mode address?