CVE-2010-4254: Improper Input Validation (CWE-20)
value: Mono, when Moonlight before 2.3.0.1 or 2.99.x before 2.99.0.10 is used, does not properly validate arguments to generic methods, which allows remote attackers to bypass generic constraints, and possibly execute arbitrary code, via a crafted method call.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Published: 2010-12-06T13:44Z
Repository: https://github.com/mono/mono
Language: C
Files changed: mono/metadata/reflection.c, mono/metadata/verify-internals.h, mono/metadata/verify.c
Commit date: 2010-11-25 14:23:31 -0200
Commit message: Handle invalid instantiation of generic methods.

	* verify.c: Add new function to internal verifier API to check
	method instantiations.

	* reflection.c (mono_reflection_bind_generic_method_parameters):
	Check the instantiation before returning it.

	Fixes #655847

Diff: diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c
index d43ad08902..15e649681a 100644
--- a/mono/metadata/reflection.c
+++ b/mono/metadata/reflection.c
@@ -10603,10 +10603,13 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
 		 */
 		mono_loader_lock ();
 		mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
 		mono_loader_unlock ();
 	}
+
+	if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
+		mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
 	
 	return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
diff --git a/mono/metadata/verify-internals.h b/mono/metadata/verify-internals.h
index 1d0fb75f45..e01325ef83 100644
--- a/mono/metadata/verify-internals.h
+++ b/mono/metadata/verify-internals.h
@@ -20,10 +20,11 @@ gboolean mono_verifier_is_enabled_for_method (MonoMethod *method) MONO_INTERNAL;
 gboolean mono_verifier_is_enabled_for_class (MonoClass *klass) MONO_INTERNAL;
 
 gboolean mono_verifier_is_method_full_trust (MonoMethod *method) MONO_INTERNAL;
 gboolean mono_verifier_is_class_full_trust (MonoClass *klass) MONO_INTERNAL;
 gboolean mono_verifier_class_is_valid_generic_instantiation (MonoClass *class) MONO_INTERNAL;
+gboolean mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method) MONO_INTERNAL;
 
 gboolean mono_verifier_verify_class (MonoClass *klass) MONO_INTERNAL;
 
 GSList* mono_method_verify_with_current_settings (MonoMethod *method, gboolean skip_visibility) MONO_INTERNAL;
 
diff --git a/mono/metadata/verify.c b/mono/metadata/verify.c
index a1d5bcf88e..81eb1effbc 100644
--- a/mono/metadata/verify.c
+++ b/mono/metadata/verify.c
@@ -6040,10 +6040,18 @@ gboolean
 mono_verifier_class_is_valid_generic_instantiation (MonoClass *class)
 {
 	return mono_class_is_valid_generic_instantiation (NULL, class);
 }
 
+gboolean
+mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method)
+{
+	if (!method->is_inflated)
+		return TRUE;
+	return mono_method_is_valid_generic_instantiation (NULL, method);
+}
+
 #else
 
 gboolean
 mono_verifier_verify_class (MonoClass *class)
 {
@@ -6111,7 +6119,14 @@ gboolean
 mono_verifier_class_is_valid_generic_instantiation (MonoClass *class)
 {
 	return TRUE;
 }
 
+gboolean
+mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method)
+{
+	return TRUE;
+}
+
+
 
 #endif

Fixed code: 
	if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
		mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
gboolean mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method) MONO_INTERNAL;
gboolean
mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method)
{
	if (!method->is_inflated)
		return TRUE;
	return mono_method_is_valid_generic_instantiation (NULL, method);
}

gboolean
mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method)
{
	return TRUE;
}