限制子进程访问共享内存和消息队列
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_only
或open_or_create
上指定permissions
才有意义。
我想象的是 Windows/Linux 上的通常路线:
您以特定用户帐户启动服务器 您使用同一个帐户启动客户端 您创建的 IPC 对象只能从创建它们的帐户(所有者)访问我敢打赌,由于其访问控制列表(未对此进行测试),Windows 将允许更细粒度的控制:它们应该允许您指定具有访问权限的其他/不同帐户。
在 linux 上,很可能要实现这种控制,需要额外的系统调用(例如,更改共享对象的所有者/组和/或将这样的组添加到客户端用户帐户作为主要/次要组) .
总结:_我将专注于授予特定收件人访问权限,而不是“在没有任何权限的情况下启动收件人”。后者是不切实际的(进程甚至可能“没有任何权限”就无法运行),并且在运行时提升权限比使用静态分配/管理的权限要困难得多。更不用说动态添加权限本身就不太安全。
【讨论】:
这很有帮助。看来真正的挑战是了解每个平台的权限。 我完全同意这个评价。以上是关于限制子进程访问共享内存和消息队列的主要内容,如果未能解决你的问题,请参考以下文章
8.7 进程间的通讯:管道消息队列共享内存信号量信号Socket
Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存