X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsecurity-core-clr.c;h=f874043e15b6e58f423ea2752fdcc12795a4fbe6;hb=56ad8f4e5dfb8198e4671f631a3103b1e8b83dd3;hp=43e06db574b9ab524bfb06748b7db29413d6f448;hpb=fe15af27f184fd043d1c8129b8c56a4f94125c89;p=mono.git diff --git a/mono/metadata/security-core-clr.c b/mono/metadata/security-core-clr.c index 43e06db574b..f874043e15b 100644 --- a/mono/metadata/security-core-clr.c +++ b/mono/metadata/security-core-clr.c @@ -6,6 +6,7 @@ * Sebastien Pouliot * * 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 @@ -16,7 +17,7 @@ #include #include #include -#include +#include #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)) @@ -633,34 +625,38 @@ get_method_access_exception (const char *format, MonoMethod *caller, MonoMethod * Transparent code cannot access to Critical fields and can only use * them if they are visible from it's point of view. * - * A FieldAccessException is thrown if the field is cannot be accessed. + * Returns TRUE if acess is allowed. Otherwise returns FALSE and sets @error to a FieldAccessException if the field is cannot be accessed. */ -void -mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field) +gboolean +mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field, MonoError *error) { + mono_error_init (error); MonoMethod *caller = get_reflection_caller (); /* CoreCLR restrictions applies to Transparent code/caller */ if (mono_security_core_clr_method_level (caller, TRUE) != MONO_SECURITY_CORE_CLR_TRANSPARENT) - return; + return TRUE; if (mono_security_core_clr_get_options () & MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION) { if (!mono_security_core_clr_is_platform_image (mono_field_get_parent(field)->image)) - return; + return TRUE; } /* Transparent code cannot [get|set]value on Critical fields */ if (mono_security_core_clr_class_level (mono_field_get_parent (field)) == MONO_SECURITY_CORE_CLR_CRITICAL) { - mono_raise_exception (get_field_access_exception ( + mono_error_set_exception_instance (error, get_field_access_exception ( "Transparent method %s cannot get or set Critical field %s.", caller, field)); + return FALSE; } /* also it cannot access a fields that is not visible from it's (caller) point of view */ if (!check_field_access (caller, field)) { - mono_raise_exception (get_field_access_exception ( + mono_error_set_exception_instance (error, get_field_access_exception ( "Transparent method %s cannot get or set private/internal field %s.", caller, field)); + return FALSE; } + return TRUE; } /* @@ -670,34 +666,38 @@ mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field) * Transparent code cannot call Critical methods and can only call them * if they are visible from it's point of view. * - * A MethodAccessException is thrown if the field is cannot be accessed. + * If access is allowed returns TRUE. Returns FALSE and sets @error to a MethodAccessException if the field is cannot be accessed. */ -void -mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method) +gboolean +mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method, MonoError *error) { + mono_error_init (error); MonoMethod *caller = get_reflection_caller (); /* CoreCLR restrictions applies to Transparent code/caller */ if (mono_security_core_clr_method_level (caller, TRUE) != MONO_SECURITY_CORE_CLR_TRANSPARENT) - return; + return TRUE; if (mono_security_core_clr_get_options () & MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION) { if (!mono_security_core_clr_is_platform_image (method->klass->image)) - return; + return TRUE; } /* Transparent code cannot invoke, even using reflection, Critical code */ if (mono_security_core_clr_method_level (method, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL) { - mono_raise_exception (get_method_access_exception ( + mono_error_set_exception_instance (error, get_method_access_exception ( "Transparent method %s cannot invoke Critical method %s.", caller, method)); + return FALSE; } /* also it cannot invoke a method that is not visible from it's (caller) point of view */ if (!check_method_access (caller, method)) { - mono_raise_exception (get_method_access_exception ( + mono_error_set_exception_instance (error, get_method_access_exception ( "Transparent method %s cannot invoke private/internal method %s.", caller, method)); + return FALSE; } + return TRUE; } /* @@ -735,19 +735,20 @@ can_avoid_corlib_reflection_delegate_optimization (MonoMethod *method) /* * mono_security_core_clr_ensure_delegate_creation: * - * Return TRUE if a delegate can be created on the specified method. - * CoreCLR also affect the binding, so throwOnBindFailure must be - * FALSE to let this function return (FALSE) normally, otherwise (if - * throwOnBindFailure is TRUE) it will throw an ArgumentException. + * Return TRUE if a delegate can be created on the specified + * method. CoreCLR can also affect the binding, this function may + * return (FALSE) and set @error to an ArgumentException. * - * A MethodAccessException is thrown if the specified method is not + * @error is set to a MethodAccessException if the specified method is not * visible from the caller point of view. */ gboolean -mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean throwOnBindFailure) +mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, MonoError *error) { MonoMethod *caller; + mono_error_init (error); + /* note: mscorlib creates delegates to avoid reflection (optimization), we ignore those cases */ if (can_avoid_corlib_reflection_delegate_optimization (method)) return TRUE; @@ -759,13 +760,10 @@ mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean th /* otherwise it (as a Transparent caller) cannot create a delegate on a Critical method... */ if (mono_security_core_clr_method_level (method, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL) { - /* but this throws only if 'throwOnBindFailure' is TRUE */ - if (!throwOnBindFailure) - return FALSE; - - mono_raise_exception (get_argument_exception ( + mono_error_set_exception_instance (error, get_argument_exception ( "Transparent method %s cannot create a delegate on Critical method %s.", caller, method)); + return FALSE; } if (mono_security_core_clr_get_options () & MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_DELEGATE) { @@ -775,9 +773,10 @@ mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean th /* also it cannot create the delegate on a method that is not visible from it's (caller) point of view */ if (!check_method_access (caller, method)) { - mono_raise_exception (get_method_access_exception ( + mono_error_set_exception_instance (error, get_method_access_exception ( "Transparent method %s cannot create a delegate on private/internal method %s.", caller, method)); + return FALSE; } return TRUE; @@ -917,7 +916,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 +929,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 +950,13 @@ 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); } /* @@ -1043,12 +1042,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) { } @@ -1058,19 +1057,24 @@ mono_security_core_clr_require_elevated_permissions (void) return FALSE; } -void -mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field) +gboolean +mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field, MonoError *error) { + mono_error_init (error); + return TRUE; } void -mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method) +mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method, MonoError *error) { + mono_error_init (error); + return TRUE; } gboolean -mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean throwOnBindFailure) +mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, MonoError *error) { + mono_error_init (error); return TRUE; } @@ -1099,7 +1103,7 @@ 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; }