malloc()
通常会返回可读可写的内存。一些架构(例如旧的x86)可能无法直接禁用执行权限,但这只是平台的不足之处。
如果您想要从分配的内存中执行代码,您需要明确给予执行权限,并且可能需要去除写权限,因为在某些系统上,在同一块内存上拥有写和执行权限被认为是潜在危险的(通常称为W^X)。
关于通过程序员分配的内存执行代码,已经有过几个其他的讨论主题:
malloc
并不适合用于为代码分配内存的工具。你应该使用mmap
,并根据系统上的严格安全策略,可能需要使用mprotect
来更改权限。
以下是malloc
不适合的原因:
malloc
获得的内存不太可能与页面对齐,因此您最终会在相邻的内存上设置权限,可能会破坏某些东西。free
之前不恢复旧权限,则可能会破坏malloc
的内部结构。void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
返回的内存总是以页面为单位吗?虽然length
参数似乎不能保证。 - Je Rog/proc/<pid>/maps
。 - ninjaljmprotect
,这表明由malloc
返回的内存已经具有PROT_EXEC
。 - Je RogPROT_EXEC
,可能其他操作系统采取了更为防御的方法-如果您的问题仅适用于Linux,则应该将其标记为“linux”。 - Paul Rman malloc
没有给出任何线索。此外,我不知道它是否特定于Linux,因此我认为添加该标签不合适。 - Je Rogmalloc()库函数由C语言标准指定,因此在所有操作系统上都是相同的。内存保护是处理器和操作系统的功能,因此在Windows、Linux等系统上执行方式不同。
自malloc()被定义以来,其工作方式已经发生了变化。我记得大多数处理器不支持内存的单独“可执行”权限 - 如果它是可读的,那么它就是可执行的。许多嵌入式系统根本没有任何内存保护,所有内存都可以读取、写入和执行。在所有这些情况下,malloc()函数的工作方式都是相同的。
malloc
隐式返回的内存具有PROT_READ
或PROT_EXEC
,因为它不需要像mmap
返回的内存一样进行mprotect(p, 1024, PROT_READ|PROT_EXEC)
操作。 - Je Rog