hel*_*rtz 6 c++ linux shared-memory
我试图让两个进程通过共享内存进行通信。我注意到,如果我使用不同的用户运行它们,第二个用户将在 shm_open() 上失败并拒绝权限,即使它们来自同一组。但是,如果我将执行位添加到模式中,第二个进程在调用 shm_open() 时不会失败。
我想了解这种行为,在 shm_open() 的情况下执行位到底在做什么?特别是,如果在调用 shm_open() 期间设置了执行位,进程可以在 /dev/shm 中执行 shellcode 吗?
手册页是我找到的关于此的最好文档。从 O_CREAT 中的内容来看:
如果共享内存对象不存在,则创建该对象。对象的用户和组所有权取自调用进程的相应有效ID,并且对象的权限位根据模式的低9位设置,除了在进程文件模式创建掩码中设置的那些位(参见 umask(2))为新对象清除
根据我的理解,它从模式中获取权限位(我的 umask 设置为 0002,但更改为 0 似乎不会产生不同的结果)。我在两个程序中都保留了 O_CREAT,因为手册指出“如果共享内存对象不存在,则创建它”,所以我想为两个程序重用相同的代码。
微量元素:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main() {
const char* name = "com/page";
int flags = O_CREAT | O_RDWR;
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
int fd = shm_open(name, flags, mode);
if (fd < 1) {
printf("shm_open() failed: %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* ... */
shm_unlink(name);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
按照目前的情况,如果程序使用不同的用户运行,但都在同一组中,则上面的代码片段将返回 -1,并将 errno 设置为权限被拒绝。
如果我将上面的第 12 行替换为:
int mode = S_IRWXU | S_RWXG
Run Code Online (Sandbox Code Playgroud)
然后调用 shm_open() 返回 0。
这似乎与目录缺少执行位有关,并且我们无法 cd 进入该目录。我尝试使用路径而不是文件名(预先创建 /dev/shm 中的文件夹结构),但随后 shm_open() 因参数无效而失败。