问题
I have a parent process that allocates shared memory and writes to it. It also starts child processes that only read the shared memory. However I don't have any control over the insights of those child processes. They are written by other programmers. These child processes are not supposed to write on the shared memory. So I wondered if I can allow them read permissions, but not write access.
However with shmget
you can only specify general permission without being able to distinguish between read and write access.
I also thought about switching to shm_open
& mmap
as it seems that you can open the shared memory with O_RDONLY
which forces the use of PROT_READ
(read-only access) in the mmap
call. Is it somehow possible to create two file descriptors with shm_open
in the parent process: one with O_RDONLY
and one with O_RDWR
and then passing the O_RDONLY
one to the child processes which can then map it into their process space? Of course, the children shouldn't have the permission to open the shared memory on their own by using shm_open
because that would enable them to open it with O_RDWR
.
Or did I get the concept wrong? Is it what I want even possible?
回答1:
"[T]he children shouldn't have the permission to open the shared memory on their own" implies that this is a security boundary, so shared memory is probably not appropriate. There are all sorts of odd synchronisation issues involved with shared memory, and you really want all users to play nicely with each other.
shm_open()
is little more than a helper function to generate the name of a rendezvous file within "/dev/shm" and open()
it. You then get to ftruncate()
and mmap()
it yourself. The mmap()
call will fail if you ask for PROT_WRITE
on a read-only file descriptor, which gives you the finer control that you seek.
So one thing you can do is shm_open(..., O_RDWR)
in the parent and set up a writable mapping for the parent before closing the handle, then shm_open(..., O_RDONLY)
to get a read-only file handle which you will pass to the children, followed by a shm_unlink()
so that the children cannot then re-open the file. Children then use this read-only file handle for their own mappings.
If a child were to perform a read-write shm_open()
after the parent has done a shm_unlink()
, it would get a new rendezvous file and thus cannot affect the mapping in the parent or other children. However, a determined attacker could try and exploit a race condition when the parent creates a fresh mapping. How untrustworthy are these child processes?
You do not say if these child processes are separate executables. If they are, you will want to want to use fcntl()
to duplicate the fd to a well-known fd number that is not marked close-on-exec so that the child can find it when it is launched.
I do however recommend you reconsider your need for shared memory if you do not trust child processes, and look at sending messages over a pipe or socketpair instead.
来源:https://stackoverflow.com/questions/35002305/linux-shared-memory-only-allow-read-access