限制子进程访问共享内存和消息队列

Posted

技术标签:

【中文标题】限制子进程访问共享内存和消息队列【英文标题】:Restrict child process access to shared memory and message queues 【发布时间】:2017-09-06 15:53:36 【问题描述】:

我正在编写一个服务器,它将接受在运行时使用 Boost.DLL 加载的不受信任的动态库模块(DLL、SO/DSO)。

我想在一个单独的进程中运行不受信任的模块,该进程只能访问相关的共享内存(有时是只读的)和进程间队列。

Boost 确实允许permissions 对象与共享内存相关联。

似乎有办法创建一个进程on windows和Linux,然后调整权限。

如何创建一个进程

没有权限开始(例如,也许在 Windows 上使用AdjustTokenPrivileges?),但是 然后被授予对共享内存映射文件的读取访问权限(例如,通过在constructing 共享内存段时设置permissions?)

或者这本身就太冒险了?

【问题讨论】:

【参考方案1】:

首先,来自文档:

Boost.Interprocess 提供的命名资源必须应对创建文件时也存在的平台相关权限问题。如果程序员想要在用户之间共享共享内存、内存映射文件或命名同步机制(互斥锁、信号量等),则有必要指定这些权限。遗憾的是,传统的 UNIX 和 Windows 权限非常不同,Boost.Interprocess 不会尝试标准化权限,但不会忽略它们。

所有命名资源创建函数都采用一个可选的权限对象,该对象可以配置依赖于平台的权限。

请注意,如果您这样做,那么您必须立即了解特定平台所需的权限g:

由于每种机制都可以通过不同的机制来模拟(信号量可能是使用映射文件或本机信号量来实现),因此当命名资源的实现发生变化时,权限类型可能会有所不同(例如:在 Windows 中,互斥体需要同步权限,但仅此而已不是文件的情况)。为避免这种情况,Boost.Interprocess [通常¹,红色。] 依赖于类似文件的权限,需要文件读写权限才能打开命名同步机制(互斥,信号量等)和共享内存的适当读取或读写删除权限。这种方法有两个优点:它类似于 UNIX 哲学,程序员不需要知道命名资源是如何实现的。

¹当传递权限对象时


您的其他问题:

没有权限开始(例如,也许在 Windows 上使用AdjustTokenPrivileges?),但是 然后被授予对共享内存映射文件的读取访问权限(例如,通过在构造共享内存段时设置权限?)

没有。 permissions 对象确实授予调用进程的权限。 permissions 对象限制其他进程的访问。我敢打赌,只有在create_onlyopen_or_create 上指定permissions 才有意义。

我想象的是 Windows/Linux 上的通常路线:

您以特定用户帐户启动服务器 您使用同一个帐户启动客户端 您创建的 IPC 对象只能从创建它们的帐户(所有者)访问

我敢打赌,由于其访问控制列表(未对此进行测试),Windows 将允许更细粒度的控制:它们应该允许您指定具有访问权限的其他/不同帐户。

在 linux 上,很可能要实现这种控制,需要额外的系统调用(例如,更改共享对象的所有者/组和/或将这样的组添加到客户端用户帐户作为主要/次要组) .

总结:_我将专注于授予特定收件人访问权限,而不是“在没有任何权限的情况下启动收件人”。后者是不切实际的(进程甚至可能“没有任何权限”就无法运行),并且在运行时提升权限比使用静态分配/管理的权限要困难得多。更不用说动态添加权限本身就不太安全。

【讨论】:

这很有帮助。看来真正的挑战是了解每个平台的权限。 我完全同意这个评价。

以上是关于限制子进程访问共享内存和消息队列的主要内容,如果未能解决你的问题,请参考以下文章

8.7 进程间的通讯:管道消息队列共享内存信号量信号Socket

Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存

linux 进程间通信——内存共享映射mmap和munmap

使用共享内存的 IPC

管道通信为啥比共享内存效率低

Linux Program信号量共享内存和消息队列