3
votes

I'm looking for a possibility to create a shared memory block on Windows platforms that is write-protected for all processes except for the process that created the shared memory block.

In detail I need the following:

Process (1) has to create a shared memory block and should be able to modify the buffer. Process (2) should be able to open and to read the created shared memory block but must not have permission to modify the content. This is important due to security/safty reasons.

Currently I have a solution creating a shared memory block using CreateFileMapping() together with MapViewOfFile() which then has read and write permission in process (1) and (2) like:

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, highSize, lowSize, L"uniquename");
void* sharedMemory = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
// now we can modify sharedMemory...

These two lines of code can be applied in both processes as the first process creates the shared memory block and the second process simply opens the shared memory. However, obviously the second process will have write permission due to the provided access values (PAGE_READWRITE and FILE_MAP_ALL_ACCESS) during creation of the memory block.

I would need to create the shared memory block in process (1) by using access values PAGE_READONLY and FILE_MAP_READ but obviously than I'm not allowed to initialize/set/modify the memory block in process (1) which than is a useless memory buffer.

To my best knowledge, the definition of security attributes can not solve the problem as my problem does not depend on users or groups.

I even would be happy with a solution which creates a shared memory block in process (1) relying on memory content that is known before the creation of the shared memory block (and which will not be modified in process (1) afterwards).

3

3 Answers

2
votes

Do you trust process #2 to use FILE_MAP_READ? That will prevent accidental overwrites from e.g. wild pointers corrupting the shared memory.

If you're trying to protect against malicious overwrites, then you need to use the OS-provided security principals and run process #2 in a different session with lesser credentials. If process #2 runs under the same security credentials as process #1, then it can perform any operation process #1 can perform (for example, by injecting code into process #1).

(On Windows, users are security principals and processes are not. Users are not the only level of restriction, for example User Access Control in Vista and later creates tokens corresponding to an administrative user both with and without the Administrators group membership)

Since you say process #1 doesn't need continuing write access, only one time, you could create the mapping, map it for write, then adjust the ACL using SetSecurityInfo so that future accesses cannot write.

Another possibility is to instead map a disk file, and open it with FILE_SHARE_READ (but not FILE_SHARE_WRITE) access from the first process.

But neither of these prevent process #2 from coercing process #1 to make changes on its behalf. Only using separate tokens can prevent coercion.

1
votes

You don't explain why you can't provide different arguments in each case, so I'm going to assume you don't know which process is the creator until you have the file open. In which case, you might want to try:

HANDLE h = OpenFileMapping(FILE_MAP_READ, /*args*/);
if (h) {
    v = MapViewOfFile(h, FILE_MAP_READ, 0, 0, 0);
} else {
    h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, highSize, lowSize, L"uniquename");
    if (!h)
        FirePhotonTorpedoes();
    v = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
}
1
votes

The CreateFileMapping function allows you to set an ACL for the file mapping object. If you create an ACL that only allows read-only access, other processes should be unable to open the file mapping object with read-write access.

Typically, when creating an object, the permissions you assign don't apply to the handle you obtain during creation. However, I haven't tested this with CreateFileMapping in particular.

This only provides weak protection. A malicious process could change the permissions on the file mapping object, or inject code into the process that created the object.