I'm expermenting with function pointers on Linux and trying to execute this C program:
#include <stdio.h>
#include <string.h>
int myfun()
{
return 42;
}
int main()
{
char data[500];
memcpy(data, myfun, sizeof(data));
int (*fun_pointer)() = (void*)data;
printf("%d\n", fun_pointer());
return 0;
}
Unfortunately it segfaults on fun_pointer()
call. I suspect that it is connected with some memory flags, but I don't found information about it.
Could you explain why this code segfaults? Don't see to the fixed data
array size, it is ok and copying without calling the function is successfull.
UPD: Finally I've found that the memory segment should be marked as executable using mprotect system call called with PROT_EXEC
flag. Moreover the memory segment should be returned by mmap function as stated in the POSIX specification.
There is the same code that uses allocated by mmap
memory with PROT_EXEC
flag (and works):
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
int myfun()
{
return 42;
}
int main()
{
size_t size = (char*)main - (char*)myfun;
char *data = mmap(NULL, size, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
memcpy(data, myfun, size);
int (*fun_pointer)() = (void*)data;
printf("%d\n", fun_pointer());
munmap(data, size);
return 0;
}
This example should be complied with -fPIC
gcc option to ensure that the code in functions is position-independent.