Shared memory between kernel and user mode

I am trying to use shared memory between user process and kernel.

Option one - to let kernel to create section and let user mode app to open memory by name “Global\my_mem”. It’s working only in read-only mode. When I am trying to open section with FILE_MAP_WRITE it gives access denied(5). Not sure how to grant access or modify DACL.

Option two - pass handle back via IOCTL. This one is questionable since handle to section opened in KERNEL is 0xFFFFFFFF80001234. My understanding that handles that have any of upper bits set can not be used in user mode. Especially if app will be 32-bit :slight_smile: Initially I expected that section handle will be somewhat similar to kernel file handle and I will be able to use it.

What would be the correct approach to establish shared memory channel between kernel and user mode?

What problem are you trying to solve by sharing memory?

d

Bent from my phone


From: xxxxx@gmail.commailto:xxxxx
Sent: ?3/?30/?2015 6:43 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] Shared memory between kernel and user mode

I am trying to use shared memory between user process and kernel.

Option one - to let kernel to create section and let user mode app to open memory by name “Global\my_mem”. It’s working only in read-only mode. When I am trying to open section with FILE_MAP_WRITE it gives access denied(5). Not sure how to grant access or modify DACL.

Option two - pass handle back via IOCTL. This one is questionable since handle to section opened in KERNEL is 0xFFFFFFFF80001234. My understanding that handles that have any of upper bits set can not be used in user mode. Especially if app will be 32-bit :slight_smile: Initially I expected that section handle will be somewhat similar to kernel file handle and I will be able to use it.

What would be the correct approach to establish shared memory channel between kernel and user mode?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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</mailto:xxxxx></mailto:xxxxx>

I just need 2-way communication channel to Kernel driver. I have framework that uses same way between user processes and would like to utilize same approach here. Memory access will be synched thru named events and Interlocked variable lock. SEH handlers installed on both sides (kernel, user) so deadlocks are not my concern here. Also driver has dedicated thread for shared memory.

I was unable to create section on user side since users do not have SeCreateGlobalPriviledge. Now trying do this from Kernel.

If the memory is mapped properly you don’t need SEH. One of the many issues is escalation of privilege, the app can make the driver do things it was not supposed to do. For simple two way communication normal Io patterns (read, write, ioctl) are by far the better and safer choice

d

Bent from my phone


From: xxxxx@gmail.commailto:xxxxx
Sent: ?3/?30/?2015 7:16 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Shared memory between kernel and user mode

I just need 2-way communication channel to Kernel driver. I have framework that uses same way between user processes and would like to utilize same approach here. Memory access will be synched thru named events and Interlocked variable lock. SEH handlers installed on both sides (kernel, user) so deadlocks are not my concern here. Also driver has dedicated thread for shared memory.

I was unable to create section on user side since users do not have SeCreateGlobalPriviledge. Now trying do this from Kernel.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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</mailto:xxxxx></mailto:xxxxx>

Do you want to say there is now easy way for win driver to have shared memory established with user mode app running under user account?

SEH handlers I have just to make sure there will be no blow ups that will freeze worker thread on the other side of shared memory because of lock use.

I understand the IOCTL is preferred way, but I need 2way channel and forcing user app constantly call deviceio in order to return something via IOCTL does not look good to me.

In my test case I was able to open section under Admin account in read only mode. I am surprised that I got that access denied message when requested RW. I am still thinking that I just missed some simple flag when created named section inside of the driver.

> What would be the correct approach to establish shared memory channel between kernel and user

mode?

Do not go the undocumented way of ZwCreateSection.

Also, I would suggest to avoid touching the global namespace. It’s layout is undocumented and depends on things like are you on Remote Desktop or not so.

So, allocate in user mode by VirtualAlloc, then send the IOCTL to the driver with this buffer. The driver will pend the IOCTL forever - well, till the file is closed - and call MmGetSystemAddressForMdlSafe to map the memory.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> I understand the IOCTL is preferred way, but I need 2way channel and forcing user app constantly

call deviceio in order to return something via IOCTL does not look good to me.

This is how lots of stuff is done in Windows, including WMI Events (and thus ETW) and FltMgr’s communication ports.

This is how lots of stuff is done in Linux, including “tun” and “tap” virtual network adapters which underlay VPNs and PPP.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

Windows has a shared-memory scheme that applications and drivers use BY DEFAULT exchange data. It’s called Direct I/O. There is no need for you to invent a new scheme.

You can leverage Max’ suggestion:

Which is a very strong, safe, model.

The other model to consider is using asynchronous I/O, for IOCTL with METHOD_DIRECT. Now, before you dismiss this: Consider that you need SOME sort of communication/serialization mechanism between the driver and the app. You’re going to use shared events? This involves making a system service call. Why not use that SAME OVERHEAD and do an IOCTL (with an event, if you want). Note that the I/O path in Windows is pretty nicely optimized.

We’re not saying don’t do it. We’re saying don’t think of Windows like it’s Linux, and don’t re-invent the wheel, where there’s already a really terrific shared memory scheme already available for your use.

Peter
OSR
@OSRDrivers

Thanks for help.
But before I give up with my approach I just need to understand what was wrong? Why under admin account I was unable to open (by name) RW handle to shared memory section? It’s quite documented way of doing so. Did I have to grant explicit RW access for Admins/Users group to let them have access to shared memory object?

HANDLE FileHandle = NULL;
pHBAExt->SharedMem.SharedMemSectionHandle = NULL;
DesiredAccess = SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_QUERY;

InitializeObjectAttributes(&ObjectAttributes, &pHBAExt->SharedMem.SharedMemName->data, OBJ_KERNEL_HANDLE, NULL, NULL);

status = ZwCreateSection(&pHBAExt->SharedMem.SharedMemSectionHandle, DesiredAccess, &ObjectAttributes, &MaximumSize,
PAGE_READWRITE, SEC_COMMIT, FileHandle);

status = ZwMapViewOfSection(pHBAExt->SharedMem.SharedMemSectionHandle, ZwCurrentProcess(), (PVOID*)&pHBAExt->SharedMem.BaseAddress,
0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); // PAGE_NOCACHE

User mode:
handle = ::OpenFileMapping(FILE_MAP_WRITE, FALSE, name);
sharedAddress = ::MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, 0);

[quote]
But before I give up with my approach I just need to understand what was wrong?

I dunno, dude. It’ll take us all longer to discuss this here, look at various code snippets you provide, ask you for different code snippets, look at those, argue among ourselves, and eventually figure out what you did wrong than for you to change your code to use a different approach.

Peter
OSR
@OSRDrivers

xxxxx@gmail.com wrote:

I understand the IOCTL is preferred way, but I need 2way channel and forcing user app constantly call deviceio in order to return something via IOCTL does not look good to me.

I understand that this feels unnatural and inefficient, but it’s not.
All video capture drivers in Windows work this way, and they are among
the most bandwidth-intensive communication streams you’re likely to
encounter.

Remember, even if you use a shared memory segment, you will still have
to use events and/or semaphores to signal between the two players.
Those are all going to involve kernel/user transitions anyway, PLUS
you’ll have to create policy and protocol to keep them all aligned. You
might as well use an ioctl, where the mapping and the event management
is all done for you by the highly optimized I/O subsystem.


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

>But seriously, the better design is for you app to use overlapped IO and pend several buffers.

If memory access is only sequential - then yes.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> Remember, even if you use a shared memory segment, you will still have

to use events and/or semaphores to signal between the two players.

…or pend the IOCTL which will be completed when the thresholds specified in the IOCTL will be hit…


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

Max,
Do you offer to issue a single overlapped DeviceIO from user mode, pass buffer with this io request, pend this IRP in driver until driver is down or app is closed and let driver use the associated buffer as shared memory buffer? How to make sure that it is same memory page, not it’s copy?

Am I getting this idea correct?

xxxxx@gmail.com wrote:

Do you offer to issue a single overlapped DeviceIO from user mode, pass buffer with this io request, pend this IRP in driver until driver is down or app is closed and let driver use the associated buffer as shared memory buffer?

I have done exactly that in one telemetry application.

How to make sure that it is same memory page, not it’s copy?

That’s what direct I/O is for. In METHOD_BUFFERED, both buffers are
copies. In METHOD_IN_DIRECT and METHOD_OUT_DIRECT, the first buffer is
copied but the second buffer is mapped directly.


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

I have checked IOCTL_MINIPORT_PROCESS_SERVICE_IRP that I am using now and it uses METHOD_BUFFERED. I remember trying to send request with my own control code and use one of DIRECT methods and had no success.
Does any one can give share an example how to declare and send io packet to virtual storport miniport?

xxxxx@gmail.com wrote:

I have checked IOCTL_MINIPORT_PROCESS_SERVICE_IRP that I am using now and it uses METHOD_BUFFERED. I remember trying to send request with my own control code and use one of DIRECT methods and had no success.

You didn’t mention before that you were doing a storage miniport. In
that case, you have to live under the rules of the port driver. It
validates ioctls before they get to your miniport, so it blocks custom
codes. All of the storage ioctls are METHOD_BUFFERED. You can’t use
arbitrary ioctl codes without using a filter driver.

Does any one can give share an example how to declare and send io packet to virtual storport miniport?

IOCTL_SCSI_MINIPORT can do that, but it’s buffered. You may need a
filter driver.


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

It is time to get the answer to the basic question that Doron asked, i.e.
what problem are you trying to solve? I haven’t seen anything about
performance from the OP, mainly just about wanting to have the same
interface as the application uses to do interprocess communication.

So is there a performance problem? If not then abstract your application
interface to use an IOCTL for the driver, and whatever you want for IPC.
Trying to force the driver for the convenience of the application is just
ass backwards.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, March 31, 2015 3:03 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Shared memory between kernel and user mode

xxxxx@gmail.com wrote:

I have checked IOCTL_MINIPORT_PROCESS_SERVICE_IRP that I am using now and
it uses METHOD_BUFFERED. I remember trying to send request with my own
control code and use one of DIRECT methods and had no success.

You didn’t mention before that you were doing a storage miniport. In that
case, you have to live under the rules of the port driver. It validates
ioctls before they get to your miniport, so it blocks custom codes. All of
the storage ioctls are METHOD_BUFFERED. You can’t use arbitrary ioctl codes
without using a filter driver.

Does any one can give share an example how to declare and send io packet
to virtual storport miniport?

IOCTL_SCSI_MINIPORT can do that, but it’s buffered. You may need a filter
driver.


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


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

>shared memory buffer? How to make sure that it is same memory page, not it’s copy?

For direct IO, ->MdlAddress is a set of locked pages of the user buffer.

No copy.

Am I getting this idea correct?

Yes.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> Does any one can give share an example how to declare and send io packet to virtual storport

miniport?

Enumerate (INQUIRY and REPORT LUNS) the additional fake LUN of Processor class.

Then invent your own custom CDBs (not the most general ones which are mandated by the spec to be supported on Processor too) and send them to this LUN via SPTI.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com