From bfff327c1020038d473e7180da9decbd0f412cc8 Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Tue, 20 Aug 2013 19:09:47 -0400 Subject: [PATCH] [runtime]Add some error checking to custom attr parsing and plug a memory leak. Fixes #13435. --- mono/metadata/reflection.c | 30 ++++++++++++++++++++++++++++-- mono/mini/debugger-agent.c | 3 ++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 66f5590f7a988..9f29e0c12c2cc 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -202,6 +202,19 @@ static void init_type_builder_generics (MonoObject *type); #define mono_type_array_get_and_resolve(array, index) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index)) +#define CHECK_ADD4_OVERFLOW_UN(a, b) ((guint32)(0xFFFFFFFFU) - (guint32)(b) < (guint32)(a)) +#define CHECK_ADD8_OVERFLOW_UN(a, b) ((guint64)(0xFFFFFFFFFFFFFFFFUL) - (guint64)(b) < (guint64)(a)) + +#if SIZEOF_VOID_P == 4 +#define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD4_OVERFLOW_UN(a, b) +#else +#define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD8_OVERFLOW_UN(a, b) +#endif + +#define ADDP_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADDP_OVERFLOW_UN (a, b)) +#define ADD_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADD4_OVERFLOW_UN (a, b)) + + void mono_reflection_init (void) { @@ -8317,6 +8330,9 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth gint type_len; char *type_name; type_len = mono_metadata_decode_blob_size (named, &named); + if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, type_len, data + len)) + goto fail; + type_name = g_malloc (type_len + 1); memcpy (type_name, named, type_len); type_name [type_len] = 0; @@ -8325,6 +8341,8 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth g_free (type_name); } name_len = mono_metadata_decode_blob_size (named, &named); + if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, name_len, data + len)) + goto fail; name = g_malloc (name_len + 1); memcpy (name, named, name_len); name [name_len] = 0; @@ -8365,6 +8383,11 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth *typed_args = typedargs; *named_args = namedargs; + return; +fail: + mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid."); + g_free (arginfo); + *named_arg_info = NULL; } void @@ -8374,7 +8397,7 @@ mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoArray *typedargs, *namedargs; MonoImage *image; MonoMethod *method; - CattrNamedArg *arginfo; + CattrNamedArg *arginfo = NULL; MonoError error; int i; @@ -8397,8 +8420,10 @@ mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, if (mono_loader_get_last_error ()) mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ())); - if (!typedargs || !namedargs) + if (!typedargs || !namedargs) { + g_free (arginfo); return; + } for (i = 0; i < mono_method_signature (method)->param_count; ++i) { MonoObject *obj = mono_array_get (typedargs, MonoObject*, i); @@ -8425,6 +8450,7 @@ mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, *ctor_args = typedargs; *named_args = namedargs; + g_free (arginfo); } static MonoObject* diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 18c6ea5037e39..6f6b30885365e 100755 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -7381,7 +7381,7 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass if (!attr_klass || mono_class_has_parent (attr->ctor->klass, attr_klass)) { MonoArray *typed_args, *named_args; MonoType *t; - CattrNamedArg *arginfo; + CattrNamedArg *arginfo = NULL; MonoError error; mono_reflection_create_custom_attr_data_args (image, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo, &error); @@ -7425,6 +7425,7 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass } else { buffer_add_int (buf, 0); } + g_free (arginfo); } } }