Search code examples
cunixmemory-management

How to protect a random block of some size of a memory page returned by mmap()?


I am doing a memory-management exercise in which I am implementing an api with similar functionality like malloc.

page = mmap(NULL,PAGESIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

first I initialize an empty page using mmap. I have another function which lets user specify some amount of bytes within the limit of page size. Page size is 4KB.

 void *allocate(int size){
    // search for empty block in the page
    void *start = (void *)(page+offset);
    
    // protect the memory
    return start;
  }

Now, before I return the pointer to the memory block of size size, I want to protect it because with subsequent call to allocate() nothing is stopping user from overwriting other memory blocks.

I tried mprotect() but it can only protect the address within the range of page boundary so if my start is somewhere in the middle of the page, it returns Invalid argument.

Is there anyway to protect these random chunks of the page before making them available to user?


Solution

  • Assuming you are working with x86 system, it's not possible (*) to protect memory region less than page size (4KiB). What mprotect() does is setting some bits on approriate page table entry (see x86 paging), which controls what operations are allowed for the given page. Since 4KiB is what's the hardware supports, there no good/performant way to circumvent that from software.

    (*) Technically, you can play around with x86 segmentation, but it's an acient feature and not currently widely used in any meaningful way (e.g., Linux only has several segments to separate userspace/kernel and code/data). See this answer for more in depth explanation.