2009-03-28 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Sat, 28 Mar 2009 14:14:47 +0000 (14:14 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Sat, 28 Mar 2009 14:14:47 +0000 (14:14 -0000)
* class.c: move coreclr inheritance/override checks to
security-core.clr.c
* security-core.clr.c|h: add code from class.c with additional
documentation. Fix override check when the method is not critical.

svn path=/trunk/mono/; revision=130464

mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/security-core-clr.c
mono/metadata/security-core-clr.h

index a8c2d6e38dd5c2a01b260f7d8762c45f48f8fc24..3bbc67ab013a2d6694035365b5e7b8e53b0e261b 100644 (file)
@@ -1,3 +1,10 @@
+2009-03-28  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * class.c: move coreclr inheritance/override checks to 
+       security-core.clr.c
+       * security-core.clr.c|h: add code from class.c with additional
+       documentation. Fix override check when the method is not critical.
+
 2009-03-28  Zoltan Varga  <vargaz@gmail.com>
 
        * debug-helpers.c (mono_method_desc_match): Make '*' match anything.
index c60f04bb14389a6191d9433ba82e1eb172a08955..94a76da12644efdf546740d76768a70f2528f9ae 100644 (file)
@@ -2727,19 +2727,6 @@ mono_class_setup_vtable (MonoClass *class)
        return;
 }
 
-static void
-check_core_clr_override_method (MonoClass *class, MonoMethod *override, MonoMethod *base)
-{
-       MonoSecurityCoreCLRLevel base_level = mono_security_core_clr_method_level (base, FALSE);
-       /* if the base method is decorated with [SecurityCritical] then the overrided method MUST be too */
-       if (base_level == MONO_SECURITY_CORE_CLR_CRITICAL) {
-               MonoSecurityCoreCLRLevel override_level = mono_security_core_clr_method_level (override, FALSE);
-               if (override_level != MONO_SECURITY_CORE_CLR_CRITICAL)
-                       mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
-       }
-}
-
-
 #define DEBUG_INTERFACE_VTABLE_CODE 0
 #define TRACE_INTERFACE_VTABLE_CODE 0
 #define VERIFY_INTERFACE_VTABLE_CODE 0
@@ -2838,7 +2825,7 @@ check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *c
                }
 
                if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
-                       check_core_clr_override_method (class, cm, im);
+                       mono_security_core_clr_check_override (class, cm, im);
                TRACE_INTERFACE_VTABLE (printf ("[NAME CHECK OK]"));
                return TRUE;
        } else {
@@ -2907,7 +2894,7 @@ check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *c
                }
 
                if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
-                       check_core_clr_override_method (class, cm, im);
+                       mono_security_core_clr_check_override (class, cm, im);
                
                TRACE_INTERFACE_VTABLE (printf ("[INJECTED INTERFACE CHECK OK]"));
                return TRUE;
@@ -3167,7 +3154,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
                        g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]);
 
                        if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
-                               check_core_clr_override_method (class, vtable [dslot], decl);
+                               mono_security_core_clr_check_override (class, vtable [dslot], decl);
                }
        }
        TRACE_INTERFACE_VTABLE (print_overrides (override_map, "AFTER OVERRIDING INTERFACE METHODS"));
@@ -3323,7 +3310,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
                                                }
 
                                                if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
-                                                       check_core_clr_override_method (class, cm, m1);
+                                                       mono_security_core_clr_check_override (class, cm, m1);
 
                                                slot = mono_method_get_vtable_slot (m1);
                                                g_assert (cm->slot < max_vtsize);
@@ -3359,7 +3346,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
                        g_hash_table_insert (override_map, decl, overrides [i * 2 + 1]);
 
                        if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
-                               check_core_clr_override_method (class, vtable [decl->slot], decl);
+                               mono_security_core_clr_check_override (class, vtable [decl->slot], decl);
                }
        }
 
@@ -3658,22 +3645,6 @@ set_failure_from_loader_error (MonoClass *class, MonoLoaderError *error)
        mono_class_set_failure (class, error->exception_type, exception_data);
 }
 
-static void
-check_core_clr_inheritance (MonoClass *class)
-{
-       MonoSecurityCoreCLRLevel class_level, parent_level;
-       MonoClass *parent = class->parent;
-
-       if (!parent)
-               return;
-
-       class_level = mono_security_core_clr_class_level (class);
-       parent_level = mono_security_core_clr_class_level (parent);
-
-       if (class_level < parent_level)
-               mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
-}
-
 /**
  * mono_class_init:
  * @class: the class to initialize
@@ -3724,7 +3695,7 @@ mono_class_init (MonoClass *class)
        }
 
        if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
-               check_core_clr_inheritance (class);
+               mono_security_core_clr_check_inheritance (class);
 
        mono_stats.initialized_class_count++;
 
index f2200c491e94bba221caef40aedef026b8578d5b..119e42af90548c2953e042f5f47c9468d1db5a4c 100644 (file)
@@ -45,6 +45,66 @@ security_safe_critical_attribute (void)
        return class;
 }
 
+/*
+ * mono_security_core_clr_check_inheritance:
+ *
+ *     Determine if the specified class can inherit from its parent using 
+ *     the CoreCLR inheritance rules.
+ *
+ *     Base Type       Allow Derived Type
+ *     ------------    ------------------
+ *     Transparent     Transparent, SafeCritical, Critical
+ *     SafeCritical    SafeCritical, Critical
+ *     Critical        Critical
+ *
+ *     Reference: http://msdn.microsoft.com/en-us/magazine/cc765416.aspx#id0190030
+ */
+void
+mono_security_core_clr_check_inheritance (MonoClass *class)
+{
+       MonoSecurityCoreCLRLevel class_level, parent_level;
+       MonoClass *parent = class->parent;
+
+       if (!parent)
+               return;
+
+       class_level = mono_security_core_clr_class_level (class);
+       parent_level = mono_security_core_clr_class_level (parent);
+
+       if (class_level < parent_level)
+               mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
+}
+
+/*
+ * mono_security_core_clr_check_override:
+ *
+ *     Determine if the specified override can "legally" override the 
+ *     specified base method using the CoreCLR inheritance rules.
+ *
+ *     Base (virtual/interface)        Allowed override
+ *     ------------------------        -------------------------
+ *     Transparent                     Transparent, SafeCritical
+ *     SafeCritical                    Transparent, SafeCritical
+ *     Critical                        Critical
+ *
+ *     Reference: http://msdn.microsoft.com/en-us/magazine/cc765416.aspx#id0190030
+ */
+void
+mono_security_core_clr_check_override (MonoClass *class, MonoMethod *override, MonoMethod *base)
+{
+       MonoSecurityCoreCLRLevel base_level = mono_security_core_clr_method_level (base, FALSE);
+       MonoSecurityCoreCLRLevel override_level = mono_security_core_clr_method_level (override, FALSE);
+       /* if the base method is decorated with [SecurityCritical] then the overrided method MUST be too */
+       if (base_level == MONO_SECURITY_CORE_CLR_CRITICAL) {
+               if (override_level != MONO_SECURITY_CORE_CLR_CRITICAL)
+                       mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
+       } else {
+               /* base is [SecuritySafeCritical] or [SecurityTransparent], override MUST NOT be [SecurityCritical] */
+               if (override_level == MONO_SECURITY_CORE_CLR_CRITICAL)
+                       mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
+       }
+}
+
 /*
  * get_caller_no_reflection_related:
  *
index 58d0dfbcf6c8e5940f378987a6c0393c02641a4f..c1b9524365e1c738647521c0c774fcb38f902a32 100644 (file)
@@ -22,6 +22,9 @@ typedef enum {
 
 extern gboolean mono_security_core_clr_test;
 
+extern void mono_security_core_clr_check_inheritance (MonoClass *class) MONO_INTERNAL;
+extern void mono_security_core_clr_check_override (MonoClass *class, MonoMethod *override, MonoMethod *base) MONO_INTERNAL;
+
 extern void mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field) MONO_INTERNAL;
 extern void mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method) MONO_INTERNAL;
 extern gboolean mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean throwOnBindFailure) MONO_INTERNAL;