为什么?

为什么?

有没有什么方法可以撤销创建该共享对象的进程对共享内存的写入权限,而任何其他已将共享内存映射到具有写入权限的虚拟空间的进程在权限被撤销后尝试实际写入时都会失败?

起初,我实际上预计,当撤销fchmod()使用 创建的共享内存对象的写入权限时shm_open(),共享内存对象已映射到PROT_WRITEvia的其他进程的所有后续写入mmap()都会导致段错误。但这种情况并非如此。

现在我想知道,是否有其他方法(系统调用、共享内存 API..)如何实现我想要的行为?

在引导我的应用程序时注册共享内存对象以供 RDMA 使用时,我需要写入权限。但是,最终我想确保本地进程无法写入共享内存对象。

答案1

这在 Linux 权限模型中根本不可能实现。您所要求的形式不太可能有任何直接机制。

为什么?

一旦进程 mmap 了一个文件,它对文件的访问就通过虚拟寻址。不检查单独的读/写,这是为了性能而故意的。这其实就是内存映射的重点。当与DMA,内存映射允许以接近零的 CPU 开销访问文件。也就是说,在文件被内存映射之后,内核只需要参与尚未从磁盘加载页面的情况,或者有充分的理由开始将更改刷新回磁盘。其他一切都是通过虚拟寻址处理的。

事实上,这个问题比你想象的要严重得多。允许进程读取和写入文件,使用读()写()没有曾经拥有该文件的权限。所需要的只是一个开放的FD(文件描述符)。文件权限通常情况下阻止进程实现这一点,但不是完全阻止。 FD 可以使用 unix-domain-sockets 在进程之间传递。因此,一个有权限的进程可以将打开的 FD 传递给另一个没有任何权限的进程。

解决办法

你的问题并不完全清楚。我认为您要求应用程序具有只读访问权限,并要求其他东西(通过 RDMA)具有读写访问权限。

如果是这种情况,我建议简单地将文件内存映射两次,一次有写访问权限,一次没有写访问权限。只要您进行设置,对一个内存映射所做的更改就会传递到另一个内存映射MAP_SHARED

如果您必须在进程中保持写访问打开才能使 RDMA 发挥作用,那么您始终可以叉(),并在一个进程中保留写访问权限,而另一个进程(您的应用程序)则具有只读访问权限。从你的问题中我不清楚你是否需要这个。

相关内容