# HG changeset patch # User Tassilo Philipp # Date 1490047978 -3600 # Node ID 030fbb70aa1b42f89c49706abed3a00504e99fb3 # Parent 136409adbdd17f1e7a4e52d592c1a8c53eaa01fa - changed allocwx code: * to introduce a call allowing to switch the written page to be executable (e.g. using mprotect) * changed mmap based code so page is always W^X diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_alloc_wx.h --- a/dyncallback/dyncall_alloc_wx.h Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_alloc_wx.h Mon Mar 20 23:12:58 2017 +0100 @@ -35,8 +35,9 @@ extern "C" { #endif -DCerror dcAllocWX(DCsize size, void** p); -void dcFreeWX (void* p, DCsize size); +DCerror dcAllocWX (DCsize size, void** p); +DCerror dcInitExecWX(void* p, DCsize size); +void dcFreeWX (void* p, DCsize size); #ifdef __cplusplus } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_alloc_wx_malloc.c --- a/dyncallback/dyncall_alloc_wx_malloc.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_alloc_wx_malloc.c Mon Mar 20 23:12:58 2017 +0100 @@ -29,13 +29,19 @@ #include -int dcAllocWX(size_t size, void** pp) +DCerror dcAllocWX(size_t size, void** pp) { *pp = malloc(size); return 0; } +DCerror dcInitExecWX(void* p, size_t size) +{ + return 0; +} + void dcFreeWX(void* p, size_t size) { free(p); } + diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_alloc_wx_mmap.c --- a/dyncallback/dyncall_alloc_wx_mmap.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_alloc_wx_mmap.c Mon Mar 20 23:12:58 2017 +0100 @@ -41,7 +41,7 @@ #endif -int dcAllocWX(size_t size, void** pp) +DCerror dcAllocWX(size_t size, void** pp) { void* p; #if !defined(MAP_ANON) && defined(DC_UNIX) @@ -50,7 +50,7 @@ int fd = open("/dev/zero", O_RDWR); if(fd == -1) return -1; - p = mmap(0, size+sizeof(int), PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + p = mmap(0, size+sizeof(int), PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); if(p == MAP_FAILED) { close(fd); return -1; @@ -58,7 +58,7 @@ *(int*)p = fd; p += sizeof(int); #else - p = mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); + p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); if(p == MAP_FAILED) return -1; #endif @@ -67,6 +67,11 @@ return 0; } +DCerror dcInitExecWX(void* p, size_t size) +{ + return mprotect(p, size, PROT_READ|PROT_EXEC); +} + void dcFreeWX(void* p, size_t size) { #if !defined(MAP_ANON) && defined(DC_UNIX) diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_alloc_wx_win32.c --- a/dyncallback/dyncall_alloc_wx_win32.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_alloc_wx_win32.c Mon Mar 20 23:12:58 2017 +0100 @@ -28,7 +28,7 @@ #include #include -int dcAllocWX(size_t size, void** ptr) +DCerror dcAllocWX(size_t size, void** ptr) { LPVOID p = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (p == NULL) return -1; @@ -36,6 +36,11 @@ return 0; } +DCerror dcInitExecWX(void* p, size_t size) +{ + return 0; +} + void dcFreeWX(void* p, size_t size) { BOOL b = VirtualFree( p, 0, MEM_RELEASE); diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_arm32.c --- a/dyncallback/dyncall_callback_arm32.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_arm32.c Mon Mar 20 23:12:58 2017 +0100 @@ -51,10 +51,18 @@ int err; DCCallback* pcb; err = dcAllocWX(sizeof(DCCallback), (void**)&pcb); - if(err || !pcb) - return 0; + if(err) + return NULL; + dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_arm64.c --- a/dyncallback/dyncall_callback_arm64.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_arm64.c Mon Mar 20 23:12:58 2017 +0100 @@ -50,10 +50,18 @@ int err; DCCallback* pcb; err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_mips.c --- a/dyncallback/dyncall_callback_mips.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_mips.c Mon Mar 20 23:12:58 2017 +0100 @@ -52,10 +52,18 @@ int err; DCCallback* pcb; err = dcAllocWX(sizeof(DCCallback), (void**)&pcb); - if(err || !pcb) - return 0; + if(err) + return NULL; + dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_ppc32.c --- a/dyncallback/dyncall_callback_ppc32.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_ppc32.c Mon Mar 20 23:12:58 2017 +0100 @@ -53,11 +53,18 @@ { DCCallback* pcb; int err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_ppc64.c --- a/dyncallback/dyncall_callback_ppc64.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_ppc64.c Mon Mar 20 23:12:58 2017 +0100 @@ -52,11 +52,18 @@ { DCCallback* pcb; int err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_sparc32.c --- a/dyncallback/dyncall_callback_sparc32.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_sparc32.c Mon Mar 20 23:12:58 2017 +0100 @@ -49,11 +49,18 @@ { DCCallback* pcb; int err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_sparc64.c --- a/dyncallback/dyncall_callback_sparc64.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_sparc64.c Mon Mar 20 23:12:58 2017 +0100 @@ -49,11 +49,18 @@ { DCCallback* pcb; int err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_x64.c --- a/dyncallback/dyncall_callback_x64.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_x64.c Mon Mar 20 23:12:58 2017 +0100 @@ -52,7 +52,8 @@ int err; DCCallback* pcb; err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; #if defined (DC__OS_Win64) dcbInitThunk(&pcb->thunk, dcCallback_x64_win64); @@ -60,6 +61,13 @@ dcbInitThunk(&pcb->thunk, dcCallback_x64_sysv); #endif dcbInitCallback(pcb, signature, handler, userdata); + + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; } diff -r 136409adbdd1 -r 030fbb70aa1b dyncallback/dyncall_callback_x86.c --- a/dyncallback/dyncall_callback_x86.c Sun Mar 19 20:26:01 2017 +0100 +++ b/dyncallback/dyncall_callback_x86.c Mon Mar 20 23:12:58 2017 +0100 @@ -265,10 +265,18 @@ int err; DCCallback* pcb; err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); - if (err != 0) return 0; + if(err) + return NULL; dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); dcbInitCallback(pcb, signature, handler, userdata); + + err = dcInitExecWX(pcb, sizeof(DCCallback)); + if(err) { + dcFreeWX(pcb, sizeof(DCCallback)); + return NULL; + } + return pcb; }