[runtime]Add some error checking to custom attr parsing and plug a memory leak. Fixes...
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 20 Aug 2013 23:09:47 +0000 (19:09 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 20 Aug 2013 23:10:45 +0000 (19:10 -0400)
mono/metadata/reflection.c
mono/mini/debugger-agent.c

index 66f5590f7a98896097f686f4a14c182f16575d98..9f29e0c12c2cc7c0105e3f6ffcba2dba55d16b96 100644 (file)
@@ -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*
index 18c6ea5037e399d8d8346de0d16f5be088deeca5..6f6b30885365ec3e302c549a246c559c008f6e98 100755 (executable)
@@ -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);
                }
        }
 }