2

Is there any way to revoke write permissions to shared memory by the process who created that shared object, s.t. any other process who has mapped the shared memory to its virtual space with write permissions will fail when trying to actually write after the permissions were revoked?

At first I actually expected when revoking write permissions with fchmod() on a shared memory object created with shm_open(), that all subsequent writes by other processes who had the shared memory object already mapped with PROT_WRITE via mmap() will cause a segfault. But this is not the case.

Now I was wondering, if there is any other approach (syscall, shared memory API..) how to achieve my desired behavior?

I need the write permissions when registering the shared memory object for RDMA usage while bootstrapping my application. However, eventually I'd like to ensure that the local process is not able to write to the shared memory object.

4
  • shm_open() is usually implemented as nothing more than mmap() of a file in a prescribed directory, and the memory page permissions are set at mmap() time so changing the file permissions afterwards won't change the memory permissions. Sys V shared memory (shmget()/shmat()) might do what you need - a Sys V shared memory segment has permission modes similar to file modes, and those modes can be changed at runtime. That might do what you need - allow your "other" processes write access via group membership, then have your master process remove write access for the group. Commented Jun 8, 2020 at 0:44
  • @AndrewHenle I'd be surprised if that worked either. I'd expect permissions to only be checked at attach time. Commented Jun 8, 2020 at 0:47
  • @JosephSible-ReinstateMonica So would I. But it should be relatively easy to test, and it's a lot simpler than somehow getting into the other processes and remapping pages to remove write permissions. Commented Jun 8, 2020 at 0:50
  • @AndrewHenle Unfortunately with sys v it behaves the same as with the posix ipc api. Most likely because of the same same reason Joseph mentioned. Strange that such behavior is simply not provided by any of those APIs. Seems to me to be a basic functionality to support. Commented Jun 8, 2020 at 8:51

1 Answer 1

1
+100

This simply isn't possible with Linux permissions model. There's unlikely to be any direct mechanism in the form you are asking.

Why?

Once a process has mmap'd a file, it's access to the file is handled through virtual addressing. Individual read/writes are not checked and this is deliberate for performance. This is actually the point of memory mapping. When combined with DMA, memory mapping allows access to files with near zero CPU overhead. That is, after a file has been memory mapped, the kernel only needs get involved where pages have not yet been loaded from disk, or there is good reason to start flushing changes back to disk. Everything else is handled through virtual addressing.

In fact the problem is subtly worse than you may believe. A process is allowed to read and write to a file using read() and write() without ever having permissions to that file. All is needs is an open FD (file descriptor). File permissions normally prevent the process from getting that, but not entirely. FDs can be passed between processes using unix-domain-sockets. So one process with permissions can pass an open FD to another process with no permission at all.

Work around

Your question isn't entirely clear. I think what you are asking for your application to have read-only access and something else (via RDMA) to have read-write access.

If that's the case I would suggest simply memory-mapping the file twice, once with and once without write access. Changes made by one memory mapping are carried through to another as long as you set MAP_SHARED.

If you must keep the write access open in a process for RDMA to function, then you can always fork(), and keep write-access in one process while the other, your application, has read-only access. I'm unclear on whether you need this or not from your question.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.