Skip to content

Commit aa9587d

Browse files
Debugger: Prevent Abort on Invalid Virtual Method
If the debugger is asked to invoke an interface or virtual method on a class the mono_object_get_virtual_method_internal will assert & abort (or crash). mono_object_get_virtual_method_internal assumes that it is being asked to invoke a virtual method on an instance that implements it. If that's not true it will assert & abort or access invalid memory if assertions are disabled. To protect against this we check if the this_arg can be cast to the interface or base class type. If it can then we should be safe to call mono_object_get_virtual_method_internal.
1 parent 30ec273 commit aa9587d

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

mono/mini/debugger-agent.c

+8
Original file line numberDiff line numberDiff line change
@@ -6545,6 +6545,10 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
65456545
PRINT_DEBUG_MSG (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer) (gsize) mono_native_thread_id_get ());
65466546
return ERR_INVALID_ARGUMENT;
65476547
}
6548+
if (!mono_object_isinst_checked(this_arg, m->klass, error)) {
6549+
PRINT_DEBUG_MSG (1, "[%p] Error: Interface method invoked on object that doesn't implement the interface.\n", (gpointer) (gsize) mono_native_thread_id_get ());
6550+
return ERR_INVALID_ARGUMENT;
6551+
}
65486552
m = mono_object_get_virtual_method_internal (this_arg, m);
65496553
/* Transform this to the format the rest of the code expects it to be */
65506554
if (m_class_is_valuetype (m->klass)) {
@@ -6556,6 +6560,10 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
65566560
PRINT_DEBUG_MSG (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer) (gsize) mono_native_thread_id_get ());
65576561
return ERR_INVALID_ARGUMENT;
65586562
}
6563+
if (!mono_object_isinst_checked(this_arg, m->klass, error)) {
6564+
PRINT_DEBUG_MSG (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag on object that object that doesn't implement the method.\n", (gpointer) (gsize) mono_native_thread_id_get ());
6565+
return ERR_INVALID_ARGUMENT;
6566+
}
65596567
m = mono_object_get_virtual_method_internal (this_arg, m);
65606568
if (m_class_is_valuetype (m->klass)) {
65616569
this_buf = (guint8 *)g_alloca (mono_class_instance_size (m->klass));

0 commit comments

Comments
 (0)