From ddacacca00cb69f829abf9b0fd52fd6b4076d2c4 Mon Sep 17 00:00:00 2001 From: Sebastien Pouliot Date: Tue, 30 Mar 2010 20:05:27 +0000 Subject: 2010-03-30 Sebastien Pouliot * class.c (mono_class_init): Postpone coreclr inheritance check until the end of the initialization (so we can check up the default ctor manually for the core-clr inheritance rules). * security-core-clr.c: Add the missing (undocumented) checks on default constructors when verifying inheritance rules. svn path=/trunk/mono/; revision=154485 --- mono/metadata/ChangeLog | 9 ++++++++ mono/metadata/class.c | 6 +++--- mono/metadata/security-core-clr.c | 45 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 8db82ca6327..0a44c8eb8ff 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,11 @@ +2010-03-30 Sebastien Pouliot + + * class.c (mono_class_init): Postpone coreclr inheritance check + until the end of the initialization (so we can check up the + default ctor manually for the core-clr inheritance rules). + * security-core-clr.c: Add the missing (undocumented) checks on + default constructors when verifying inheritance rules. + 2010-03-30 Rodrigo Kumpera * reflection.c: Add support for new v4 type @@ -8,6 +16,7 @@ * class.c (mono_class_init): Don't set class failure after inited = 1 is set. It must be done before. + 2010-03-30 Andreas Färber * mono-config.c: Add support for OS "haiku" diff --git a/mono/metadata/class.c b/mono/metadata/class.c index fc52fc41a69..41bb47c7036 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -4439,9 +4439,6 @@ mono_class_init (MonoClass *class) mono_secman_inheritancedemand_class (class, class->parent); } - if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) - mono_security_core_clr_check_inheritance (class); - mono_stats.initialized_class_count++; if (class->generic_class && !class->generic_class->is_dynamic) { @@ -4648,6 +4645,9 @@ mono_class_init (MonoClass *class) setup_interface_offsets (class, 0); } + if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) + mono_security_core_clr_check_inheritance (class); + if (mono_loader_get_last_error ()) { if (class->exception_type == MONO_EXCEPTION_NONE) { set_failure_from_loader_error (class, mono_loader_get_last_error ()); diff --git a/mono/metadata/security-core-clr.c b/mono/metadata/security-core-clr.c index 50e0d84eafa..0ada5b6a596 100644 --- a/mono/metadata/security-core-clr.c +++ b/mono/metadata/security-core-clr.c @@ -5,7 +5,7 @@ * Mark Probst * Sebastien Pouliot * - * Copyright 2007-2009 Novell, Inc (http://www.novell.com) + * Copyright 2007-2010 Novell, Inc (http://www.novell.com) */ #include @@ -46,6 +46,34 @@ security_safe_critical_attribute (void) return class; } +/* MonoClass is not fully initialized (inited is not yet == 1) when we + * check the inheritance rules so we need to look for the default ctor + * ourselve to avoid recursion (and aborting) + */ +static MonoMethod* +get_default_ctor (MonoClass *klass) +{ + int i; + + if (!klass->methods) + return NULL; + + for (i = 0; i < klass->method.count; ++i) { + MonoMethodSignature *sig; + MonoMethod *method = klass->methods [i]; + + if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) == 0) + continue; + if ((method->name[0] != '.') || strcmp (".ctor", method->name)) + continue; + sig = mono_method_signature (method); + if (sig && (sig->param_count == 0)) + return method; + } + + return NULL; +} + /* * mono_security_core_clr_check_inheritance: * @@ -59,6 +87,12 @@ security_safe_critical_attribute (void) * Critical Critical * * Reference: http://msdn.microsoft.com/en-us/magazine/cc765416.aspx#id0190030 + * + * Furthermore a class MUST have a default constructor if its base + * class has a non-transparent default constructor. The same + * inheritance rule applies to both default constructors. + * + * Reference: message from a SecurityException in SL4RC */ void mono_security_core_clr_check_inheritance (MonoClass *class) @@ -72,8 +106,15 @@ mono_security_core_clr_check_inheritance (MonoClass *class) class_level = mono_security_core_clr_class_level (class); parent_level = mono_security_core_clr_class_level (parent); - if (class_level < parent_level) + if (class_level < parent_level) { mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); + } else { + class_level = mono_security_core_clr_method_level (get_default_ctor (class), FALSE); + parent_level = mono_security_core_clr_method_level (get_default_ctor (parent), FALSE); + if (class_level < parent_level) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); + } + } } /* -- cgit v1.2.3