Tue Mar 18 12:39:27 CET 2008 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Tue, 18 Mar 2008 10:50:26 +0000 (10:50 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Tue, 18 Mar 2008 10:50:26 +0000 (10:50 -0000)
* mini.h, mini-amd64.c, mini-x86.c, tramp-amd64.c, tramp-x86.c: change
the mono_breakpoint_clean_code() code to perform bound checks.

svn path=/trunk/mono/; revision=98527

mono/mini/ChangeLog
mono/mini/mini-amd64.c
mono/mini/mini-x86.c
mono/mini/mini.h
mono/mini/tramp-amd64.c
mono/mini/tramp-x86.c

index 7fec1d45d962d93e8a6efea00580f6c00f5f34fa..97b0f9899c069ea8bae46c505b627660a55476c1 100644 (file)
@@ -1,4 +1,9 @@
 
+Tue Mar 18 12:39:27 CET 2008 Paolo Molaro <lupus@ximian.com>
+
+       * mini.h, mini-amd64.c, mini-x86.c, tramp-amd64.c, tramp-x86.c: change
+       the mono_breakpoint_clean_code() code to perform bound checks.
+
 Tue Mar 18 11:50:14 CET 2008 Paolo Molaro <lupus@ximian.com>
 
        * mini.h, mini-trampolines.c, tramp-*.c: change the signature of
index a07f58546995156ca680ba987554d1a84467b2ef..c6fe43f544b65b8223ccf30173881478e2c43f9f 100644 (file)
@@ -5494,12 +5494,33 @@ mono_arch_get_patch_offset (guint8 *code)
        return 3;
 }
 
+/**
+ * mono_breakpoint_clean_code:
+ *
+ * Copy @size bytes from @code - @offset to the buffer @buf. If the debugger inserted software
+ * breakpoints in the original code, they are removed in the copy.
+ *
+ * Returns TRUE if no sw breakpoint was present.
+ */
 gboolean
-mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size)
+mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size)
 {
        int i;
        gboolean can_write = TRUE;
-       memcpy (buf, code, size);
+       /*
+        * If method_start is non-NULL we need to perform bound checks, since we access memory
+        * at code - offset we could go before the start of the method and end up in a different
+        * page of memory that is not mapped or read incorrect data anyway. We zero-fill the bytes
+        * instead.
+        */
+       if (!method_start || code - offset >= method_start) {
+               memcpy (buf, code - offset, size);
+       } else {
+               int diff = code - method_start;
+               memset (buf, 0, size);
+               memcpy (buf + offset - diff, method_start, diff + size - offset);
+       }
+       code -= offset;
        for (i = 0; i < MONO_BREAKPOINT_ARRAY_SIZE; ++i) {
                int idx = mono_breakpoint_info_index [i];
                guint8 *ptr;
@@ -5524,8 +5545,8 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
        gint32 disp;
        guint8 rex = 0;
 
-       mono_breakpoint_clean_code (code - 10, buf, sizeof (buf));
-       code = buf + 10;
+       mono_breakpoint_clean_code (NULL, code, 9, buf, sizeof (buf));
+       code = buf + 9;
 
        *displacement = 0;
 
index b13e91d6494ab197dc9ab7d17004be02564d2f78..ad3e36ff384130048d23a3fade2ff0a35b031739 100644 (file)
@@ -4570,12 +4570,33 @@ mono_arch_get_patch_offset (guint8 *code)
        }
 }
 
+/**
+ * mono_breakpoint_clean_code:
+ *
+ * Copy @size bytes from @code - @offset to the buffer @buf. If the debugger inserted software
+ * breakpoints in the original code, they are removed in the copy.
+ *
+ * Returns TRUE if no sw breakpoint was present.
+ */
 gboolean
-mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size)
+mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size)
 {
        int i;
        gboolean can_write = TRUE;
-       memcpy (buf, code, size);
+       /*
+        * If method_start is non-NULL we need to perform bound checks, since we access memory
+        * at code - offset we could go before the start of the method and end up in a different
+        * page of memory that is not mapped or read incorrect data anyway. We zero-fill the bytes
+        * instead.
+        */
+       if (!method_start || code - offset >= method_start) {
+               memcpy (buf, code - offset, size);
+       } else {
+               int diff = code - method_start;
+               memset (buf, 0, size);
+               memcpy (buf + offset - diff, method_start, diff + size - offset);
+       }
+       code -= offset;
        for (i = 0; i < MONO_BREAKPOINT_ARRAY_SIZE; ++i) {
                int idx = mono_breakpoint_info_index [i];
                guint8 *ptr;
@@ -4599,7 +4620,7 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
        guint8 reg = 0;
        gint32 disp = 0;
 
-       mono_breakpoint_clean_code (code - 8, buf, sizeof (buf));
+       mono_breakpoint_clean_code (NULL, code, 8, buf, sizeof (buf));
        code = buf + 8;
 
        *displacement = 0;
index 9e66314fc26099a8f8aa906df98e4e1e9227d354..ccb8fe68f2e084dd89da511ce6af9f158cecaf5b 100644 (file)
@@ -1318,7 +1318,7 @@ void      mono_debugger_run_finally             (MonoContext *start_ctx);
 
 extern gssize mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
 
-gboolean mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size);
+gboolean mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size);
 
 /* Mono Debugger support */
 void      mono_debugger_init                    (void);
index fcd74abb5801e09444082e5097ccf122a51d208b..a15464d3208ece1cf99e813a6834d331f6dce823 100644 (file)
@@ -73,7 +73,7 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
 {
        guint8 *code;
        guint8 buf [16];
-       gboolean can_write = mono_breakpoint_clean_code (orig_code - 14, buf, sizeof (buf));
+       gboolean can_write = mono_breakpoint_clean_code (method_start, orig_code, 14, buf, sizeof (buf));
 
        code = buf + 14;
 
@@ -127,7 +127,7 @@ void
 mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
 {
        guint8 buf [16];
-       gboolean can_write = mono_breakpoint_clean_code (code - 7, buf, sizeof (buf));
+       gboolean can_write = mono_breakpoint_clean_code (NULL, code, 7, buf, sizeof (buf));
 
        if (!can_write)
                return;
index ce976aacf98fc5489a82cda44bc5e23d36bc05d7..3aa12baa297965b92018bcfabb0af9bd26a9b989 100644 (file)
@@ -62,7 +62,7 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
 {
        guint8 *code;
        guint8 buf [8];
-       gboolean can_write = mono_breakpoint_clean_code (orig_code - 8, buf, sizeof (buf));
+       gboolean can_write = mono_breakpoint_clean_code (method_start, orig_code, 8, buf, sizeof (buf));
 
        code = buf + 8;
        if (mono_running_on_valgrind ())
@@ -111,7 +111,7 @@ void
 mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
 {
        guint8 buf [16];
-       gboolean can_write = mono_breakpoint_clean_code (code - 6, buf, sizeof (buf));
+       gboolean can_write = mono_breakpoint_clean_code (NULL, code, 6, buf, sizeof (buf));
 
        if (!can_write)
                return;