在C或C ++中,在Linux上,我想在系统内存页面大小的整页中分配堆内存。
(目的是我希望增加有害缓冲区溢出导致分段错误的可能性。)
当我使用C ++数组new(pointer = new char[size]
)分配内存时,其中size是sysconf(_SC_PAGESIZE)
的倍数,那么分配的内存的(虚拟)地址通常不会是{{的倍数1}},表示我有一个较大块的子集,通过写入指针[size]和稍微超出(强制缓冲区溢出)这一事实证实通常不会导致分段错误。
我的问题是,我可以以某种方式影响内存分配,以便为我提供完整的内存页面。
我感兴趣的处理器架构是x86_64 aka amd64。操作系统是最新的Ubuntu,或者是稳定的CentOS Linux(7.3),后者附带内核3.10和gcc-4.8。
我不在乎解决方案是使用C还是C ++,因此我要求在此问题中保留C标记。
答案 0 :(得分:3)
1)只需从pointer = new char[size]
切换到pointer = aligned_alloc(sysconf(_SC_PAGESIZE), size)
,就会导致正确的页面对齐和(到目前为止,小型测试程序)超出分配范围时一致生成分段错误。正如@JohnBollinger在对该问题的第一次评论中指出的那样,单独分配方法无法保证分段错误的产生。这可以用2)修复:
2)函数mprotect的Linux手册页包含一个限制访问内存页面的完整示例。该示例还为SIGSEGV提供了一个信号处理程序,我对此并不感兴趣,默认操作(abort)对我来说已经足够了。手册页的示例部分如下。请注意,将mprotect应用于与mmap无关的内存区域是POSIX未涵盖的特定于Linux的扩展。
实施例
下面的程序分配四页内存,第三项 这些页面只读,然后执行循环遍历 向上通过分配的区域修改字节。
运行程序时我们可能会看到的一个例子是 以下内容:
$ ./a.out Start of region: 0x804c000 Got SIGSEGV at address: 0x804e000
节目来源
#include <unistd.h> #include <signal.h> #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <errno.h> #include <sys/mman.h> #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) static char *buffer; static void handler(int sig, siginfo_t *si, void *unused) { printf("Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { char *p; int pagesize; struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = handler; if (sigaction(SIGSEGV, &sa, NULL) == -1) handle_error("sigaction"); pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize == -1) handle_error("sysconf"); /* Allocate a buffer aligned on a page boundary; initial protection is PROT_READ | PROT_WRITE */ buffer = memalign(pagesize, 4 * pagesize); if (buffer == NULL) handle_error("memalign"); printf("Start of region: 0x%lx\n", (long) buffer); if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ) == -1) handle_error("mprotect"); for (p = buffer ; ; ) *(p++) = 'a'; printf("Loop completed\n"); /* Should never happen */ exit(EXIT_SUCCESS); }
前一句话的归属:
此页面是Linux man-pages项目4.04版的一部分 项目描述,有关报告错误的信息,以及 该页面的最新版本可在http://www.kernel.org/doc/man-pages/找到。