Linux 共享内存只允许读访问
Linux shared memory only allow read access
我有一个 parent 进程分配共享内存并写入它。
它还会启动 child 个只读取共享内存的进程。但是,我无法控制那些 child 过程的见解。它们是由其他程序员编写的。这些 child 进程不应该写入共享内存。所以我想知道我是否可以允许他们读取权限,但不允许写入权限。
但是 shmget
只能指定一般权限,无法区分读写权限。
我还考虑过切换到 shm_open
和 mmap
,因为您似乎可以使用 O_RDONLY
打开共享内存,这会强制使用 PROT_READ
(read-only 访问)在 mmap
调用中。是否有可能在 parent 进程中创建两个带有 shm_open
的文件描述符:一个带有 O_RDONLY
,一个带有 O_RDWR
,然后将 O_RDONLY
一个传递给child 进程然后可以将其映射到他们的进程 space?当然,child人不应该有使用shm_open
自行打开共享内存的权限,因为这将使他们能够使用O_RDWR
打开共享内存。
还是我理解错了?是我想要的吗?
[T]he children shouldn't have the permission to open the shared memory on their own"暗示这是一个安全边界,所以共享内存可能是不合适的。共享内存涉及各种奇怪的同步问题,您确实希望所有用户都能很好地相互配合。
shm_open()
只不过是一个辅助函数,用于在“/dev/shm”和 open()
中生成集合文件的名称。然后你自己去ftruncate()
和mmap()
。如果您在 read-only 文件描述符上请求 PROT_WRITE
,mmap()
调用将失败,这会为您提供更好的控制。
所以你可以做的一件事是在 parent 中 shm_open(..., O_RDWR)
并在关闭句柄之前为 parent 设置一个可写映射,然后 shm_open(..., O_RDONLY)
得到将传递给 children 的 read-only 文件句柄,后跟 shm_unlink()
,这样 children 就无法 re-open 文件。 Children 然后将此 read-only 文件句柄用于他们自己的映射。
如果 child 在 parent 完成 shm_unlink()
之后执行 read-write shm_open()
,它将获得一个新的集合点文件并且因此不能影响 parent 或其他 children 中的映射。但是,当 parent 创建新映射时,坚定的攻击者可能会尝试利用竞争条件。这些 child 流程有多不可信?
您不会说这些 child 进程是否是单独的可执行文件。如果是,您将希望使用 fcntl()
将 fd 复制到未标记 close-on-exec 的 well-known fd 编号,以便 child 可以找到它它已启动。
不过,如果您不信任 child 进程,我建议您重新考虑对共享内存的需求,并考虑通过管道或套接字对发送消息。
我有一个 parent 进程分配共享内存并写入它。 它还会启动 child 个只读取共享内存的进程。但是,我无法控制那些 child 过程的见解。它们是由其他程序员编写的。这些 child 进程不应该写入共享内存。所以我想知道我是否可以允许他们读取权限,但不允许写入权限。
但是 shmget
只能指定一般权限,无法区分读写权限。
我还考虑过切换到 shm_open
和 mmap
,因为您似乎可以使用 O_RDONLY
打开共享内存,这会强制使用 PROT_READ
(read-only 访问)在 mmap
调用中。是否有可能在 parent 进程中创建两个带有 shm_open
的文件描述符:一个带有 O_RDONLY
,一个带有 O_RDWR
,然后将 O_RDONLY
一个传递给child 进程然后可以将其映射到他们的进程 space?当然,child人不应该有使用shm_open
自行打开共享内存的权限,因为这将使他们能够使用O_RDWR
打开共享内存。
还是我理解错了?是我想要的吗?
[T]he children shouldn't have the permission to open the shared memory on their own"暗示这是一个安全边界,所以共享内存可能是不合适的。共享内存涉及各种奇怪的同步问题,您确实希望所有用户都能很好地相互配合。
shm_open()
只不过是一个辅助函数,用于在“/dev/shm”和 open()
中生成集合文件的名称。然后你自己去ftruncate()
和mmap()
。如果您在 read-only 文件描述符上请求 PROT_WRITE
,mmap()
调用将失败,这会为您提供更好的控制。
所以你可以做的一件事是在 parent 中 shm_open(..., O_RDWR)
并在关闭句柄之前为 parent 设置一个可写映射,然后 shm_open(..., O_RDONLY)
得到将传递给 children 的 read-only 文件句柄,后跟 shm_unlink()
,这样 children 就无法 re-open 文件。 Children 然后将此 read-only 文件句柄用于他们自己的映射。
如果 child 在 parent 完成 shm_unlink()
之后执行 read-write shm_open()
,它将获得一个新的集合点文件并且因此不能影响 parent 或其他 children 中的映射。但是,当 parent 创建新映射时,坚定的攻击者可能会尝试利用竞争条件。这些 child 流程有多不可信?
您不会说这些 child 进程是否是单独的可执行文件。如果是,您将希望使用 fcntl()
将 fd 复制到未标记 close-on-exec 的 well-known fd 编号,以便 child 可以找到它它已启动。
不过,如果您不信任 child 进程,我建议您重新考虑对共享内存的需求,并考虑通过管道或套接字对发送消息。