+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
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;
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;
}
}
+/**
+ * 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;
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;
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);
{
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;
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;
{
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 ())
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;