Hello Mark,
The current check for the overrides is not correct. Here's a fix for it
(which also moves the coreclr checks code into security-core-clr.c*).
The patch includes additional tests for coreclr-security.cs
Thanks again
Sebastien
* that should make it easier to allow people to compile (a smaller)
mono, without support for coreclr, by adding stubs for the exported
functions.
Index: metadata/security-core-clr.c
===
--- metadata/security-core-clr.c (revision 130414)
+++ metadata/security-core-clr.c (working copy)
@@ -46,6 +46,66 @@
}
/*
+ * 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:
*
* Find the first managed caller that is either:
Index: metadata/security-core-clr.h
===
--- metadata/security-core-clr.h (revision 130414)
+++ metadata/security-core-clr.h (working copy)
@@ -22,6 +22,9 @@
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;
Index: metadata/ChangeLog
===
--- metadata/ChangeLog (revision 130414)
+++ metadata/ChangeLog (working copy)
@@ -1,3 +1,10 @@
+2009-03-27 Sebastien Pouliot sebast...@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-27 Sebastien Pouliot sebast...@ximian.com
* appdomain.h: Export a new callback type and a new function to
Index: metadata/class.c
===
--- metadata/class.c (revision 130414)
+++ metadata/class.c (working copy)
@@ -2727,19 +2727,6 @@
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 !=