I have some important data structures stored in shared memory by my
service. My service creates the shared memory region and it allows
read/write access to this region by SOME processes. I was wondering
if there was a way to regulate access to my region from a driver. I
would like my driver to own the region, and based on the process ID,
allow or disallow access to this region. If my service crashes, I
would like to still allow those selected few processes to still be
able to access the shared memory region. Are there any articles or
other references that people can point me to in order to achieve this?
Drivers can access ALL of physical memory, so no there is no way to have
memory private to your process that’s not visible to a driver.
Jan
I have some important data structures stored in shared memory by my
service. My service creates the shared memory region and it allows
read/write access to this region by SOME processes. I was wondering
if there was a way to regulate access to my region from a driver. I
would like my driver to own the region, and based on the process ID,
allow or disallow access to this region. If my service crashes, I
would like to still allow those selected few processes to still be
able to access the shared memory region. Are there any articles or
other references that people can point me to in order to achieve this?
Thanks for the reply Jan. If I am only trying to prevent access from
user processes, is this possible? One idea I had was to encrypt the
shared memory region and pass the keys to the processes that need
access to this memory, but managing keys seems like a complicated
task.
On Fri, May 28, 2010 at 10:13 AM, Jan Bottorff wrote: > Drivers can access ALL of physical memory, so no there is no way to have > memory private to your process that’s not visible to a driver. > > Jan > >> I have some important data structures stored in shared memory by my >> service. ?My service creates the shared memory region and it allows >> read/write access to this region by SOME processes. ?I was wondering >> if there was a way to regulate access to my region from a driver. ?I >> would like my driver to own the region, and based on the process ID, >> allow or disallow access to this region. ?If my service crashes, I >> would like to still allow those selected few processes to still be >> able to access the shared memory region. ?Are there any articles or >> other references that people can point me to in order to achieve this? > > > — > 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 >
If you’re going to share memory between user & the kernel, given your other goals, encryption would seem like the best you could do, though it wouldn’t prevent anything else in the kernel from overwriting you, either intentionally or not.
Why do you need to share the memory in the first place? If you just went with the usual IOCTL approach, you wouldn’t have to worry about user mode access, and it’s certainly no more complicated than dealing with encryption and so forth.
Also, you’re going to have to synchronize access to all of this, which means that you’re likely to have send IOCTL’s anyway.
> Why not have the driver allocate the pages, and have the applications that want to share those
pages call into the driver to get a mapping?
I refuse to believe my own eyes - basically what you are offering here is implementing mmap()…
Is that not sufficiently secure,
Well, I would say under Windows this approach is not as secure as it would be under those OSes that support mmap() due to the specifics of Windows process model, i.e billions of DLLs loaded in the same address space plus the ability to modify the address space of any process that you can open handle to (with the specifc permissions,of course). Although access permissions can protect you against malicious code they cannot do anything about the buggy one. With this approach a bug in, say, some DLLmay have system-wide implications if this DLL is loaded into the address space of a process that driver maps its pages to…
I didn’t follow any of that. It has nothing to do with DLLs. App calls into driver. Driver maps shared area into address space that’s available in application. Driver returns UVA to application.
> App calls into driver. Driver maps shared area into address space that’s available in application.
Driver returns UVA to application.
…and some buggy third-party DLL that is mapped into app’s address space by yet another buggy third-party app that has created a couple of threads in your app by accident subsequently corrupts data in this shared area. As an app writer you cannot protect yourself against this scenario, can you. This is what I am talking about - no matter how well Windows app itself is written it cannot be totally trustworthy for the reasons that are out of app’s writer’s control…
Oh, I see. You’re saying: “Bugs might cause problems and could corrupt shared data.” Wow. Yeah…
You DID read the thread, right? He’s not talking about mapping memory DEVICE MEMORY into user space. He’s merely talking about regulating access to some shared data structures among processes.
If an app was only a consumer and not a producer, you COULD of course map the memory into the apps address space read-only. It’d be more work, but if that’s what was needed…
> …and some buggy third-party DLL that is mapped into app’s address space by yet another buggy
third-party app that has created a couple of threads in your app by accident subsequently corrupts
data in this shared area. As an app writer you cannot protect yourself against this scenario
> I have some important data structures stored in shared
memory by my service. My service creates the shared
memory region and it allows read/write access to this
region by SOME processes. I was wondering if there
was a way to regulate access to my region from a
driver. I would like my driver to own the region, and
based on the process ID, allow or disallow access to
this region.
The security model in Windows is that you allow or deny
access based on the token the process is running with,
not its process ID. When you create the section object
(using CreateFileMapping in user mode or
ZwCreateSection from a driver), specify a security
descriptor that grants access only to the users/groups
you want. Trying to further restrict access based on
other factors like process ID is hard (probably impossible)
to do right. Processes running as the same user will
likely be able to bypass these restrictions by reading
each other’s memory, injecting code through various
mechanisms, etc.
Thanks guys for all the replies. So, I like the idea of mapping the
region into only my process. Without enforcing access using security
tokens, is there a way to say “only my module within this process can
access this memory?” I saw another thread on the list mentioning
something similar where the user wanted to determine if a specific
module was calling into some function. I am wondering if I could
leverage this to do what I want?
Thanks,
J
On Sat, May 29, 2010 at 1:41 PM, Pavel Lebedinsky wrote: >> I have some important data structures stored in shared >> memory by my service. ?My service creates the shared >> memory region and it allows read/write access to this >> region by SOME processes. ?I was wondering if there >> was a way to regulate access to my region from a >> driver. ?I would like my driver to own the region, and >> based on the process ID, allow or disallow access to >> this region. > > The security model in Windows is that you allow or deny > access based on the token the process is running with, > not its process ID. When you create the section object > (using CreateFileMapping in user mode or > ZwCreateSection from a driver), specify a security > descriptor that grants access only to the users/groups > you want. Trying to further restrict access based on > other factors like process ID is hard (probably impossible) > to do right. Processes running as the same user will > likely be able to bypass these restrictions by reading > each other’s memory, injecting code through various > mechanisms, etc. > — > 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 >
Well, Pavel is entirely right about this when he wrote:
If this is a service, you could use a Service SID to control access. Really, Pavel’s point is well taken here. It would be best for you to think (and try to work) within the Windows architectural framework and not try to re-invent the wheel.
>tokens, is there a way to say "only my module within this process can
access this memory?"
If you really need securing access to these data to your code only, then you can abandon the idea of mapping, keep the data in kernel mode only, and only allow administrators (or some proper users) to open this device object.
Or, you can run a service EXE with this area mapped, and do all work by making RPC/DCOM calls from the apps to this service EXE.
Note that unmanaged Windows code has no per-module security, it only has per-thread-identity security. So, all code running under administrator will be able to access your data.