I am experimenting with function pointers on Linux and trying to run this program in C:
#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 does not answer the call to fun_pointer() . I suspect it is associated with some memory flags, but I did not find information about this.
Could you explain why this code is segfaults? I do not see the fixed size of the data array, this is normal and copying without calling the function is successful.
UPD Finally, I found that the memory segment should be marked as executable with mprotect called with the PROT_EXEC flag. In addition, the memory segment must be returned by the mmap function, as specified in the POSIX specification. There is the same code that uses allocated mmap memory with the 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 run with the -fPIC gcc option to ensure that the code in the functions is position-independent.
source share