如何保护Linux进程间共享的内存

5
在Linux或其他现代操作系统中,每个进程的内存都是受保护的,这样一个进程中的任意写操作不会导致其他进程崩溃。现在假设我们有一块被进程A和进程B共享的内存。现在假设由于软件错误,进程A无意中向该内存区域写入了一些内容。如果进程A和进程B都对该内存具有完全的写访问权限,那么有没有什么方法能够保护它免受此类攻击的影响呢?
2个回答

3
当您调用shm_open时,可以将O_RDONLY标志传递给模式参数。
或者,您可以使用mprotect将特定页面标记为(例如)只读。您需要两个进程之间的合作和信任才能做到这一点,B没有办法使用mprotect阻止A写入它。
如果您确实希望确保另一个进程无法干扰,则通过某种管道或套接字进行通信可能是一个明智的选择。
您也可以使用mmap将某些内容(例如在/dev/shm中)映射到文件权限使得其中一个进程不可能写入。例如,如果您拥有由用户producer和组consumer拥有并将文件权限设置为0640的/dev/shm/myprocess,然后通过以该UID和GID运行的进程映射它,则可以防止第二个进程写入它。

我知道mprotect,但正如我所说,两者都具有完全的读写访问权限。对我来说,似乎不可能实现这一点,我认为可靠性是共享内存系统的一个主要问题。不是吗? - MetallicPriest
1
@MetallicPriest 更新了 open 调用的 O_RDONLY 标志。然而,还有其他解决方案。不久后我会再次更新。 - Flexo
谢谢awoodland。我想到的一个解决方案是对每次访问共享内存使用互斥锁,并只有在进程锁定互斥锁时才给予写入权限。这将减少意外写入的可能性。然而,当共享内存访问频率很高时,我认为这种方案会非常低效。 - MetallicPriest
1
@MetallicPriest,如果你有野指针,那么互斥锁本身可能已经损坏了... - bdonlan
直接更改/dev/shm中的“文件”的权限是不可移植的。相反,您应该在使用shm_openO_CREAT创建共享内存对象时指定所需的模式(权限)。或者,只需使用普通文件系统中的文件而不是shm_open来获取共享内存即可。 - R.. GitHub STOP HELPING ICE

1

您可以在每次写入时使用简单的校验和。因此,当一个进程在读取操作时检测到错误的校验和时,这是另一个进程失败的迹象。


1
你可以使用校验和,但是考虑使用信号量,因为仅仅使用校验和而没有任何形式的同步会导致糟糕的解决方案。但如果你真的想要确保最佳解决方案,那么就应该有一个单一的主控端来写入和读取内存,并通过套接字与其通信,以便验证每次写入。 - Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接