/* * Ensure that the restrictions for partially trusted code are satisfied. * * @domain The current application domain * @assembly The assembly to query * return value: TRUE if the assembly is runnning at FullTrust, FALSE otherwise. */ static gboolean mono_declsec_is_assembly_fulltrust (MonoDomain *domain, MonoAssembly *assembly) { if (!MONO_SECMAN_FLAG_INIT (assembly->fulltrust)) { MonoReflectionAssembly *refass = (MonoReflectionAssembly*) mono_assembly_get_object (domain, assembly); MonoSecurityManager *secman = mono_security_manager_get_methods (); if (secman && refass) { MonoObject *res; gpointer args [1]; args [0] = refass; res = mono_runtime_invoke (secman->linkdemandfulltrust, NULL, args, NULL); if (*(MonoBoolean *) mono_object_unbox(res)) { /* keep this value cached as it will be used very often */ MONO_SECMAN_FLAG_SET_VALUE (assembly->fulltrust, TRUE); return TRUE; } } MONO_SECMAN_FLAG_SET_VALUE (assembly->fulltrust, FALSE); return FALSE; } return MONO_SECMAN_FLAG_GET_VALUE (assembly->fulltrust); }
static MonoReflectionAssembly * ves_icall_VInvoke_LoadAssemblyFromVirtuoso (MonoAppDomain *ad, MonoString *message) { char *asm_name; caddr_t name = NULL; caddr_t code = NULL; long len; MonoAssembly *ass; MonoDomain *domain = virtuoso_domain; MonoImage *image = NULL; #ifdef OLD_KIT_1_1_5 MonoImageOpenStatus *status; #else MonoImageOpenStatus status; #endif asm_name = mono_string_to_utf8 (message); name = box_copy (asm_name); code = mono_get_assembly_by_name (&name); if (!code) return NULL; len = box_length (code); image = mono_image_open_from_data (code, len, 0, NULL); if (!image) return NULL; #ifdef OLD_KIT_1_1_5 ass = mono_assembly_open ("", NULL, image); #else ass = mono_assembly_load_from (image, "", &status); #endif if (!ass && !status) return NULL; return mono_assembly_get_object (domain, ass); }
/* * Ensure that the restrictions for calling native code are satisfied. * * @domain The current application domain * @caller The method calling * @native The native method called * return value: TRUE if a security violation is detected, FALSE otherwise. * * Executing Platform Invokes (P/Invoke) is a is a restricted operation. * The security policy must allow (SecurityPermissionFlag.UnmanagedCode) * an assembly to do this. * * This LinkDemand case is special because it only needs to call managed * code once per assembly. Further calls on this assembly will use a cached * flag for better performance. This is not done before the first call (e.g. * when loading the assembly) because that would break the lazy policy * evaluation that Mono use (another time saving optimization). * * Note: P/Invoke checks are ALWAYS (1) done at JIT time (as a LinkDemand). * They are also checked at runtime, using a Demand (stack walk), unless the * method or it's class has a [SuppressUnmanagedCodeSecurity] attribute. * * (1) well as long as the security manager is active (i.e. --security) */ static gboolean mono_declsec_linkdemand_pinvoke (MonoDomain *domain, MonoMethod *caller, MonoMethod *native) { MonoAssembly *assembly = mono_image_get_assembly (caller->klass->image); InterlockedIncrement (&mono_jit_stats.cas_linkdemand_pinvoke); /* Check for P/Invoke flag for the assembly */ if (!MONO_SECMAN_FLAG_INIT (assembly->unmanaged)) { /* Check if we know (and have) or FullTrust status */ if (MONO_SECMAN_FLAG_INIT (assembly->fulltrust) && MONO_SECMAN_FLAG_GET_VALUE (assembly->fulltrust)) { /* FullTrust includes UnmanagedCode permission */ MONO_SECMAN_FLAG_SET_VALUE (assembly->unmanaged, TRUE); return FALSE; } else { MonoReflectionAssembly *refass = (MonoReflectionAssembly*) mono_assembly_get_object (domain, assembly); MonoSecurityManager* secman = mono_security_manager_get_methods (); if (secman && refass) { MonoObject *res; gpointer args [1]; args [0] = refass; res = mono_runtime_invoke (secman->linkdemandunmanaged, NULL, args, NULL); if (*(MonoBoolean *) mono_object_unbox(res)) { MONO_SECMAN_FLAG_SET_VALUE (assembly->unmanaged, TRUE); return FALSE; } } } MONO_SECMAN_FLAG_SET_VALUE (assembly->unmanaged, FALSE); } if (MONO_SECMAN_FLAG_GET_VALUE (assembly->unmanaged)) return FALSE; /* g_warning ("FAILURE *** JIT LinkDemand P/Invoke check *** %s.%s calls into %s.%s", caller->klass->name, caller->name, native->klass->name, native->name); */ return TRUE; /* i.e. throw new SecurityException(); */ }
/* * Execute any LinkDemand, NonCasLinkDemand, LinkDemandChoice declarative * security attribute present on the called method or it's class. * * @domain The current application domain * @caller The method calling * @callee The called method. * return value: TRUE if a security violation is detection, FALSE otherwise. * * Note: The execution is done in managed code in SecurityManager.LinkDemand */ static gboolean mono_declsec_linkdemand_standard (MonoDomain *domain, MonoMethod *caller, MonoMethod *callee) { MonoDeclSecurityActions linkclass, linkmethod; InterlockedIncrement (&mono_jit_stats.cas_linkdemand); if (mono_declsec_get_linkdemands (callee, &linkclass, &linkmethod)) { MonoAssembly *assembly = mono_image_get_assembly (caller->klass->image); MonoReflectionAssembly *refass = (MonoReflectionAssembly*) mono_assembly_get_object (domain, assembly); MonoSecurityManager *secman = mono_security_manager_get_methods (); MonoObject *res; gpointer args [3]; args [0] = refass; args [1] = &linkclass; args [2] = &linkmethod; res = mono_runtime_invoke (secman->linkdemand, NULL, args, NULL); return !(*(MonoBoolean *) mono_object_unbox(res)); } return FALSE; }