changeset 202:030fbb70aa1b

- 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
author Tassilo Philipp
date Mon, 20 Mar 2017 23:12:58 +0100
parents 136409adbdd1
children 3999750fae28
files dyncallback/dyncall_alloc_wx.h dyncallback/dyncall_alloc_wx_malloc.c dyncallback/dyncall_alloc_wx_mmap.c dyncallback/dyncall_alloc_wx_win32.c dyncallback/dyncall_callback_arm32.c dyncallback/dyncall_callback_arm64.c dyncallback/dyncall_callback_mips.c dyncallback/dyncall_callback_ppc32.c dyncallback/dyncall_callback_ppc64.c dyncallback/dyncall_callback_sparc32.c dyncallback/dyncall_callback_sparc64.c dyncallback/dyncall_callback_x64.c dyncallback/dyncall_callback_x86.c
diffstat 13 files changed, 103 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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
 }
--- 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 <stdlib.h>
 
 
-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);
 }
+
--- 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)
--- 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 <windows.h>
 #include <assert.h>
 
-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);
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }
 
--- 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;
 }