我正在尝试分配一个整数数组,然后使用 mmap()将页面映射到两个不同的静态堆,然后使用 mprotect()带保护PROT_NONE。
似乎mprotect()比我告诉它要做的堆保护的要多很多(
int main(){
//shared data
int *p_array;
struct sigaction sa;
int i=0;
p_array = (int *)malloc(sizeof(int)*NUM_ELEMENTS); // allocate 100 ints
size_t size_of_p_array = sizeof(p_array);
//SIGSEGV Handler initialization
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
handle_error("sigaction");
protected_Heap = mmap (p_array, size_of_p_array, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); /* anonymous mapping doesn't need a file desc */
nonprotected_Heap = mmap (p_array, size_of_p_array, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); /* anonymous mapping doesn't need a file desc */
//write to the page to obtain a private copy
for (i=0; i<NUM_ELEMENTS;i++){
protected_Heap[i]=i;
nonprotected_Heap[i]=i;
}
// Make the memory unwritable
mprotect(protected_Heap,sizeof(int)*NUM_ELEMENTS, PROT_NONE);
printf("will write and it should not trigger an Access violation\n");
nonprotected_Heap[3] =0; // Should not trigger the SIGSEGV
protected_Heap[NUM_ELEMENTS+2]=0; //Should not trigger signal but it does
printf("will write and it should trigger an Access Violation\n");
protected_Heap[3] =0; // Should trigger the SIGSEGV
//Unmap the memory
munmap (protected_Heap,size_of_p_array);
munmap (nonprotected_Heap,size_of_p_array);
return 0;
}
有没有什么方法可以保护到阵列结束而不是进一步?
答案 0 :(得分:2)
mprotect
粒度是有限的,它将始终保护整页。由于x86上的页面大小为4kB,因此无法保护100个int数组。
其次,当前的mmap
有点奇怪,因为你可以通过mmap来解决已在进程中占用的问题。传递NULL并分配全新的内存,稍后通过调用munmap
释放。
最后但并非最不重要 - 要实现上述目标,您可以分配整页,然后调整数组指针,使结束指向页面的末尾。