First set of licensing changes
[mono.git] / mono / metadata / security-core-clr.c
index 1be63ffc2240dbfcce52661320765620449a384d..4c6589176b8da7d36be39242e0997c12c5e40afa 100644 (file)
@@ -6,6 +6,7 @@
  *     Sebastien Pouliot  <sebastien@ximian.com>
  *
  * Copyright 2007-2010 Novell, Inc (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <mono/metadata/class-internals.h>
@@ -16,7 +17,7 @@
 #include <mono/metadata/object.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/debug-helpers.h>
-#include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-logger-internals.h>
 
 #include "security-core-clr.h"
 
@@ -122,30 +123,21 @@ mono_security_core_clr_is_platform_image (MonoImage *image)
 
 #ifndef DISABLE_SECURITY
 
+/* Class lazy loading functions */
+static GENERATE_GET_CLASS_WITH_CACHE (security_critical, System.Security, SecurityCriticalAttribute)
+static GENERATE_GET_CLASS_WITH_CACHE (security_safe_critical, System.Security, SecuritySafeCriticalAttribute)
+
 static MonoClass*
 security_critical_attribute (void)
 {
-       static MonoClass *class = NULL;
-
-       if (!class) {
-               class = mono_class_from_name (mono_defaults.corlib, "System.Security", 
-                       "SecurityCriticalAttribute");
-       }
-       g_assert (class);
-       return class;
+       return mono_class_get_security_critical_class ();
 }
 
 static MonoClass*
 security_safe_critical_attribute (void)
 {
-       static MonoClass *class = NULL;
+       return mono_class_get_security_safe_critical_class ();
 
-       if (!class) {
-               class = mono_class_from_name (mono_defaults.corlib, "System.Security", 
-                       "SecuritySafeCriticalAttribute");
-       }
-       g_assert (class);
-       return class;
 }
 
 /* sometime we get a NULL (not found) caller (e.g. get_reflection_caller) */
@@ -164,17 +156,17 @@ get_method_full_name (MonoMethod * method)
  *     debugging purposes.
  */
 static void
-set_type_load_exception_type (const char *format, MonoClass *class)
+set_type_load_exception_type (const char *format, MonoClass *klass)
 {
-       char *type_name = mono_type_get_full_name (class);
-       char *parent_name = mono_type_get_full_name (class->parent);
+       char *type_name = mono_type_get_full_name (klass);
+       char *parent_name = mono_type_get_full_name (klass->parent);
        char *message = g_strdup_printf (format, type_name, parent_name);
 
        g_free (parent_name);
        g_free (type_name);
        
        mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_SECURITY, message);
-       mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, message);
+       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, message);
        // note: do not free string given to mono_class_set_failure
 }
 
@@ -255,30 +247,30 @@ get_default_ctor (MonoClass *klass)
  *     Reference: fxcop CA2132 rule
  */
 void
-mono_security_core_clr_check_inheritance (MonoClass *class)
+mono_security_core_clr_check_inheritance (MonoClass *klass)
 {
        MonoSecurityCoreCLRLevel class_level, parent_level;
-       MonoClass *parent = class->parent;
+       MonoClass *parent = klass->parent;
 
        if (!parent)
                return;
 
-       class_level = mono_security_core_clr_class_level (class);
+       class_level = mono_security_core_clr_class_level (klass);
        parent_level = mono_security_core_clr_class_level (parent);
 
        if (class_level < parent_level) {
                set_type_load_exception_type (
                        "Inheritance failure for type %s. Parent class %s is more restricted.",
-                       class);
+                       klass);
        } else {
                MonoMethod *parent_ctor = get_default_ctor (parent);
                if (parent_ctor && ((parent_ctor->flags & METHOD_ATTRIBUTE_PUBLIC) != 0)) {
-                       class_level = mono_security_core_clr_method_level (get_default_ctor (class), FALSE);
+                       class_level = mono_security_core_clr_method_level (get_default_ctor (klass), FALSE);
                        parent_level = mono_security_core_clr_method_level (parent_ctor, FALSE);
                        if (class_level < parent_level) {
                                set_type_load_exception_type (
                                        "Inheritance failure for type %s. Default constructor security mismatch with %s.",
-                                       class);
+                                       klass);
                        }
                }
        }
@@ -299,7 +291,7 @@ mono_security_core_clr_check_inheritance (MonoClass *class)
  *     Reference: http://msdn.microsoft.com/en-us/magazine/cc765416.aspx#id0190030
  */
 void
-mono_security_core_clr_check_override (MonoClass *class, MonoMethod *override, MonoMethod *base)
+mono_security_core_clr_check_override (MonoClass *klass, 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);
@@ -332,7 +324,7 @@ mono_security_core_clr_check_override (MonoClass *class, MonoMethod *override, M
 static gboolean
 get_caller_no_reflection_related (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
 {
-       MonoMethod **dest = data;
+       MonoMethod **dest = (MonoMethod **)data;
        const char *ns;
 
        /* skip unmanaged frames */
@@ -436,7 +428,7 @@ typedef struct {
 static gboolean
 get_caller_of_elevated_trust_code (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
 {
-       ElevatedTrustCookie *cookie = data;
+       ElevatedTrustCookie *cookie = (ElevatedTrustCookie *)data;
 
        /* skip unmanaged frames and wrappers */
        if (!managed || (m->wrapper_type != MONO_WRAPPER_NONE))
@@ -917,7 +909,7 @@ mono_security_core_clr_level_from_cinfo (MonoCustomAttrInfo *cinfo, MonoImage *i
        if (cinfo && mono_custom_attrs_has_attr (cinfo, security_critical_attribute ()))
                level = MONO_SECURITY_CORE_CLR_CRITICAL;
 
-       return level;
+       return (MonoSecurityCoreCLRLevel)level;
 }
 
 /*
@@ -930,17 +922,17 @@ mono_security_core_clr_level_from_cinfo (MonoCustomAttrInfo *cinfo, MonoImage *i
  *     - a check for the class and outer class(es) ...
  */
 static MonoSecurityCoreCLRLevel
-mono_security_core_clr_class_level_no_platform_check (MonoClass *class)
+mono_security_core_clr_class_level_no_platform_check (MonoClass *klass)
 {
        MonoSecurityCoreCLRLevel level = MONO_SECURITY_CORE_CLR_TRANSPARENT;
-       MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_class (class);
+       MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_class (klass);
        if (cinfo) {
-               level = mono_security_core_clr_level_from_cinfo (cinfo, class->image);
+               level = mono_security_core_clr_level_from_cinfo (cinfo, klass->image);
                mono_custom_attrs_free (cinfo);
        }
 
-       if (level == MONO_SECURITY_CORE_CLR_TRANSPARENT && class->nested_in)
-               level = mono_security_core_clr_class_level_no_platform_check (class->nested_in);
+       if (level == MONO_SECURITY_CORE_CLR_TRANSPARENT && klass->nested_in)
+               level = mono_security_core_clr_class_level_no_platform_check (klass->nested_in);
 
        return level;
 }
@@ -951,13 +943,47 @@ mono_security_core_clr_class_level_no_platform_check (MonoClass *class)
  *     Return the MonoSecurityCoreCLRLevel for the specified class.
  */
 MonoSecurityCoreCLRLevel
-mono_security_core_clr_class_level (MonoClass *class)
+mono_security_core_clr_class_level (MonoClass *klass)
 {
        /* non-platform code is always Transparent - whatever the attributes says */
-       if (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (class->image))
+       if (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (klass->image))
                return MONO_SECURITY_CORE_CLR_TRANSPARENT;
 
-       return mono_security_core_clr_class_level_no_platform_check (class);
+       return mono_security_core_clr_class_level_no_platform_check (klass);
+}
+
+/*
+ * mono_security_core_clr_field_level:
+ *
+ *     Return the MonoSecurityCoreCLRLevel for the specified field.
+ *     If with_class_level is TRUE then the type (class) will also be
+ *     checked, otherwise this will only report the information about
+ *     the field itself.
+ */
+MonoSecurityCoreCLRLevel
+mono_security_core_clr_field_level (MonoClassField *field, gboolean with_class_level)
+{
+       MonoCustomAttrInfo *cinfo;
+       MonoSecurityCoreCLRLevel level = MONO_SECURITY_CORE_CLR_TRANSPARENT;
+
+       /* if get_reflection_caller returns NULL then we assume the caller has NO privilege */
+       if (!field)
+               return level;
+
+       /* non-platform code is always Transparent - whatever the attributes says */
+       if (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (field->parent->image))
+               return level;
+
+       cinfo = mono_custom_attrs_from_field (field->parent, field);
+       if (cinfo) {
+               level = mono_security_core_clr_level_from_cinfo (cinfo, field->parent->image);
+               mono_custom_attrs_free (cinfo);
+       }
+
+       if (with_class_level && level == MONO_SECURITY_CORE_CLR_TRANSPARENT)
+               level = mono_security_core_clr_class_level (field->parent);
+
+       return level;
 }
 
 /*
@@ -1009,12 +1035,12 @@ mono_security_enable_core_clr ()
 #else
 
 void
-mono_security_core_clr_check_inheritance (MonoClass *class)
+mono_security_core_clr_check_inheritance (MonoClass *klass)
 {
 }
 
 void
-mono_security_core_clr_check_override (MonoClass *class, MonoMethod *override, MonoMethod *base)
+mono_security_core_clr_check_override (MonoClass *klass, MonoMethod *override, MonoMethod *base)
 {
 }
 
@@ -1065,7 +1091,13 @@ mono_security_core_clr_is_call_allowed (MonoMethod *caller, MonoMethod *callee)
 }
 
 MonoSecurityCoreCLRLevel
-mono_security_core_clr_class_level (MonoClass *class)
+mono_security_core_clr_class_level (MonoClass *klass)
+{
+       return MONO_SECURITY_CORE_CLR_TRANSPARENT;
+}
+
+MonoSecurityCoreCLRLevel
+mono_security_core_clr_field_level (MonoClassField *field, gboolean with_class_level)
 {
        return MONO_SECURITY_CORE_CLR_TRANSPARENT;
 }