在数组上使用mprotect()

时间:2016-02-14 11:50:05

标签: c linux

我正在尝试分配一个整数数组,然后使用 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;
}


有没有什么方法可以保护到阵列结束而不是进一步?

1 个答案:

答案 0 :(得分:2)

mprotect粒度是有限的,它将始终保护整页。由于x86上的页面大小为4kB,因此无法保护100个int数组。

其次,当前的mmap有点奇怪,因为你可以通过mmap来解决已在进程中占用的问题。传递NULL并分配全新的内存,稍后通过调用munmap释放。

最后但并非最不重要 - 要实现上述目标,您可以分配整页,然后调整数组指针,使结束指向页面的末尾。