Alecto
Alecto

Reputation: 10740

Calling mprotect on dynamically allocated memory results in error with error code EACCES

After hearing about it in a C course I've been experimenting with self-modifying code. I have a function which sets the memory protections for a segment of memory using mprotect:

int SetMemoryProtections(void* addr, size_t length, int protection_flag)
{
  size_t addr_as_int = (size_t)(byte*)addr;
  size_t page_size = getpagesize();
  //Address must be multiple of system page size
  size_t aligned_addr_as_int = (addr_as_int / page_size) * page_size;
  size_t additional_length = addr_as_int - aligned_addr_as_int;
  void* aligned_addr = (byte*)addr - additional_length;
  if(mprotect(aligned_addr, length + additional_length, protection_flag))
  {
    return -1;
  }
  else
  {
    return 0;
  }
}

However when I try calling it on my chunk of dynamically allocated memory, I get an error with error code EACCES. Why is this happening, and is there any way to get around it? When f_data_buffer is allocated on the stack, there's no error message (that's the commented out line).

Code calling SetMemoryProtections:

//byte f_data_buffer[16384];//Converts function pointer to byte pointer
byte* f_data_buffer = malloc(sizeof(byte) * getpagesize() * 3);
byte* f_data = f_data_buffer + getpagesize();
if(SetMemoryProtections(f_data, 20, PROT_READ | PROT_WRITE | PROT_EXEC))
{
  printf("SetMemoryProtections encountered error. Error code: ");
  switch(errno)
  {
    case EACCES: printf("EACCES"); break;
    case EINVAL: printf("EINVAL"); break;
    case ENOMEM: printf("ENOMEM"); break;
  }
  printf("\n");
  return -1;
}

Update: I rewrote the code to that it reads errno before calling printf. (It creates a local variable called err, sets err to errno, then calls the switch with err) and I get the same EACCES error code.

Upvotes: 0

Views: 1574

Answers (0)

Related Questions