executable - 共享可执行内存

标签 executable virtual-memory shared-memory mmap

我有这个简短的 C 片段:

const char *name = "/asdf";
int desc = shm_open(name, O_RDWR | O_CREAT, 0777);
ftruncate(desc, 4096);
void *block = mmap(NULL, 4096, PROT_EXEC, MAP_SHARED, desc, 0);
shm_unlink(name);

它创建了一个共享内存对象,每个人都可写、可读和可执行;然后将其映射到具有可执行权限的内存中。然而,mmap调用失败 EPERM因为某些原因。
Strace 给出了以下内容:

statfs("/dev/shm/", {f_type=0x1021994, f_bsize=4096, f_blocks=450722, f_bfree=450372, f_bavail=450372, f_files=450722, f_ffree=450713, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
futex(0x7fa7f4c8b330, FUTEX_WAKE_PRIVATE, 2147483647) = 0
open("/dev/shm/asdf", O_RDWR|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0777) = 3
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
ftruncate(3, 4096)                      = 0
mmap(NULL, 4096, PROT_EXEC, MAP_SHARED, 3, 0) = -1 EPERM (Operation not permitted)

问题似乎来自于 PROT_EXEC 的使用, 如 mmap只要没有 PROT_EXEC,任何权限组合都会成功.mmap没有执行权限,然后尝试 mprotect它也失败了。

最佳答案

假设您在这里运行 Linux,[no]exec /dev/shm mount 被传播到由 shm_open 创建的共享内存区域在当前的 Linux 内核中。因此,如果您的 /dev/shm,您的问题就会发生。安装在 noexec挂载选项(某些发行版(Debian?)默认情况下可能会这样做)。

我已修改您的代码以添加 perror (并返回 2)在 mmap 的情况下失败:

testbox $ mount|grep shm
tmpfs on /dev/shm type tmpfs (rw)
testbox $ ./a.out ; echo $?
0
testbox $ sudo mount -o remount,noexec /dev/shm
testbox $ mount|grep shm
tmpfs on /dev/shm type tmpfs (rw,noexec)
testbox $ ./a.out ; echo $?
mmap: Operation not permitted
2

关于executable - 共享可执行内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25275777/

相关文章:

node.js - 如何设置将运行可执行文件的默认应用程序

linux - 我可以将图标与 Linux 中的可执行应用程序合并吗?

memory - 既然现代计算机都使用了虚拟内存,为什么还会遇到 "out of memory"问题呢?

python - 共享内存和多处理

c - 对多个客户端使用共享内存和信号量

java - 从 Java 运行 "sandbox"内的可执行文件

dll - 用 Cygwin 编译独立的 exe

linux - 在 linux 中配置虚拟页面大小

cpu-architecture - 拥有比有效地址大的虚拟地址有什么意义?

c++ - OSX 上 32 和 64 位程序之间共享内存中的 boost::进程间同步机制(互斥体、条件)