From f3945c293bef6afbeeb7b589713bdfbde37fc44a Mon Sep 17 00:00:00 2001 From: thaystg Date: Sun, 26 Jan 2020 00:23:38 +0000 Subject: [PATCH] [debugger] Access invalid memory address using PointerValue Command. Creating a fork process to access address that came from IDE using PointerValue. The IDE can send an invalid address and it was crashing mono. Fixes mono/mono#18191 --- src/mono/mono/mini/debugger-agent.c | 67 ++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index c7c71e6e1e1..f4efdf5e9df 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -45,6 +45,7 @@ #include #endif #include +#include #endif #ifdef HOST_ANDROID @@ -104,6 +105,13 @@ #include +#include +#include + +#ifndef S_IWUSR + #define S_IWUSR S_IWRITE +#endif + #define THREAD_TO_INTERNAL(thread) (thread)->internal_thread typedef struct { @@ -603,6 +611,10 @@ static MonoThreadHandle *debugger_thread_handle; static int log_level; +static int file_check_valid_memory = -1; + +static char* filename_check_valid_memory; + static gboolean embedding; static FILE *log_file; @@ -1104,6 +1116,12 @@ mono_debugger_agent_cleanup (void) ids_cleanup (); mono_de_cleanup (); + + if (file_check_valid_memory != -1) { + remove (filename_check_valid_memory); + g_free (filename_check_valid_memory); + close (file_check_valid_memory); + } } /* @@ -9513,6 +9531,44 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf) return ERR_NONE; } +static void +create_file_to_check_memory_address (void) +{ + if (file_check_valid_memory != -1) + return; + char *file_name = g_strdup_printf ("debugger_check_valid_memory.%d", getpid()); + filename_check_valid_memory = g_build_filename (g_get_tmp_dir (), file_name, (const char*)NULL); + file_check_valid_memory = open(filename_check_valid_memory, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR); + g_free (file_name); +} + +static gboolean +valid_memory_address (gpointer addr, gint size) +{ +#ifndef _MSC_VER + gboolean ret = TRUE; + create_file_to_check_memory_address (); + if(file_check_valid_memory < 0) { + return TRUE; + } + write (file_check_valid_memory, (gpointer)addr, 1); + if (errno == EFAULT) { + ret = FALSE; + } +#else + int i = 0; + gboolean ret = FALSE; + __try { + for (i = 0; i < size; i++) + *((volatile char*)addr+i); + ret = TRUE; + } __except(1) { + return ret; + } +#endif + return ret; +} + static ErrorCode pointer_commands (int command, guint8 *p, guint8 *end, Buffer *buf) { @@ -9520,6 +9576,9 @@ pointer_commands (int command, guint8 *p, guint8 *end, Buffer *buf) gint64 addr; MonoClass* klass; MonoDomain* domain = NULL; + MonoType *type = NULL; + int align; + int size = 0; switch (command) { case CMD_POINTER_GET_VALUE: @@ -9531,7 +9590,13 @@ pointer_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (m_class_get_byval_arg (klass)->type != MONO_TYPE_PTR) return ERR_INVALID_ARGUMENT; - buffer_add_value (buf, m_class_get_byval_arg (m_class_get_element_class (klass)), (gpointer)addr, domain); + type = m_class_get_byval_arg (m_class_get_element_class (klass)); + size = mono_type_size (type, &align); + + if (!valid_memory_address((gpointer)addr, size)) + return ERR_INVALID_ARGUMENT; + + buffer_add_value (buf, type, (gpointer)addr, domain); break; default: -- GitLab