Beispiel #1
0
/*
 * Ensure that the restrictions for partially trusted code are satisfied.
 *
 * @domain	The current application domain
 * @caller	The method calling
 * @callee	The called method
 * return value: TRUE if a security violation is detected, FALSE otherwise.
 *
 * If callee's assembly is strongnamed and doesn't have an 
 * [AllowPartiallyTrustedCallers] attribute then we must enforce a LinkDemand
 * for FullTrust on all public/protected methods on public class.
 *
 * Note: APTC is only effective on stongnamed assemblies.
 */
static gboolean
mono_declsec_linkdemand_aptc (MonoDomain *domain, MonoMethod *caller, MonoMethod *callee)
{
	MonoSecurityManager* secman = NULL;
	MonoAssembly *assembly;
	guint32 size = 0;

	InterlockedIncrement (&mono_jit_stats.cas_linkdemand_aptc);

	/* A - Applicable only if we're calling into *another* assembly */
	if (caller->klass->image == callee->klass->image)
		return FALSE;

	/* B - Applicable if we're calling a public/protected method from a public class */
	if (!(callee->klass->flags & TYPE_ATTRIBUTE_PUBLIC) || !(callee->flags & FIELD_ATTRIBUTE_PUBLIC))
		return FALSE;

	/* C - Applicable if the callee's assembly is strongnamed */
	if ((mono_image_get_public_key (callee->klass->image, &size) == NULL) || (size < MONO_ECMA_KEY_LENGTH))
		return FALSE;

	/* D - the callee's assembly must have [AllowPartiallyTrustedCallers] */
	assembly = mono_image_get_assembly (callee->klass->image);
	if (!MONO_SECMAN_FLAG_INIT (assembly->aptc)) {
		MonoCustomAttrInfo* cinfo = mono_custom_attrs_from_assembly (assembly);
		gboolean result = FALSE;
		secman = mono_security_manager_get_methods ();
		if (secman && cinfo) {
			/* look for AllowPartiallyTrustedCallersAttribute */
			result = mono_custom_attrs_has_attr (cinfo, secman->allowpartiallytrustedcallers);
		}
		if (cinfo)
			mono_custom_attrs_free (cinfo);
		MONO_SECMAN_FLAG_SET_VALUE (assembly->aptc, result);
	}

	if (MONO_SECMAN_FLAG_GET_VALUE (assembly->aptc))
		return FALSE;

	/* E - the caller's assembly must have full trust permissions */
	assembly = mono_image_get_assembly (caller->klass->image);
	if (mono_declsec_is_assembly_fulltrust (domain, assembly))
		return FALSE;

	/* g_warning ("FAILURE *** JIT LinkDemand APTC check *** %s.%s calls into %s.%s",
		caller->klass->name, caller->name, callee->klass->name, callee->name); */

	return TRUE;	/* i.e. throw new SecurityException(); */
}
Beispiel #2
0
static MonoObject *
mono_jit_exec_virt (MonoAssembly *assembly, char *mtd_name, MonoArray *v_args)
{
  MonoImage *image = mono_assembly_get_image (assembly);
  MonoMethod *method;
  MonoClass *class;
  MonoMethodDesc *desc;
  MonoObject *exc = NULL, *ret;

  class = mono_class_from_name (image, "", "VInvoke");
  desc = mono_method_desc_new (mtd_name, 1);
  method = mono_method_desc_search_in_image (desc, image);

  mono_assembly_set_main (
      mono_image_get_assembly (
	mono_class_get_image (
	  mono_method_get_class (method))));
  /*mono_start_method = mono_marshal_get_runtime_invoke (method);*/

  ret = virt_mono_runtime_exec_main (method, v_args, &exc);
  if (exc)
    virt_mono_throw_unhandled_exception (exc);

  return ret;
}
Beispiel #3
0
/*
 * Ensure that the restrictions for calling internal calls are satisfied.
 *
 * @domain	The current application domain
 * @caller	The method calling
 * @icall	The internal call method
 * return value: TRUE if a security violation is detected, FALSE otherwise.
 *
 * We can't trust the icall flags/iflags as it comes from the assembly
 * that we may want to restrict and we do not have the public/restricted
 * information about icalls in the runtime. Actually it is not so bad 
 * as the CLR 2.0 doesn't enforce that restriction anymore.
 * 
 * So we'll limit the icalls to originate from ECMA signed assemblies 
 * (as this is required for partial trust scenarios) - or - assemblies that 
 * have FullTrust.
 */
static gboolean
mono_declsec_linkdemand_icall (MonoDomain *domain, MonoMethod *caller, MonoMethod *icall)
{
	MonoAssembly *assembly;

	InterlockedIncrement (&mono_jit_stats.cas_linkdemand_icall);

	/* check if the _icall_ is defined inside an ECMA signed assembly */
	assembly = mono_image_get_assembly (icall->klass->image);
	if (!MONO_SECMAN_FLAG_INIT (assembly->ecma)) {
		guint32 size = 0;
		const char *pk = mono_image_get_public_key (icall->klass->image, &size);
		MONO_SECMAN_FLAG_SET_VALUE (assembly->ecma, mono_is_ecma_key (pk, size));
	}

	if (MONO_SECMAN_FLAG_GET_VALUE (assembly->ecma))
		return FALSE;

	/* else check if the _calling_ assembly is running at FullTrust */
	assembly = mono_image_get_assembly (caller->klass->image);
	return !mono_declsec_is_assembly_fulltrust (domain, assembly);
}
	void MonoAssembly::loadFromImage(MonoImage* image)
	{
		::MonoAssembly* monoAssembly = mono_image_get_assembly(image);
		if(monoAssembly == nullptr)
		{
			BS_EXCEPT(InvalidParametersException, "Cannot get assembly from image.");
		}

		mMonoAssembly = monoAssembly;
		mMonoImage = image;

		mIsLoaded = true;
		mIsDependency = true;
	}
Beispiel #5
0
Error GDMonoAssembly::wrapper_for_image(MonoImage *p_image) {

	ERR_FAIL_COND_V(loaded, ERR_FILE_ALREADY_IN_USE);

	assembly = mono_image_get_assembly(p_image);
	ERR_FAIL_NULL_V(assembly, FAILED);

	image = p_image;

	mono_image_addref(image);

	loaded = true;

	return OK;
}
Beispiel #6
0
/*
 * Context propagation is required when:
 * (a) the security manager is active (1.x and later)
 * (b) other contexts needs to be propagated (2.x and later)
 *
 * returns NULL if no context propagation is required, else the returns the
 * MonoMethod to call to Capture the ExecutionContext.
 */
MonoMethod*
mono_get_context_capture_method (void)
{
	static MonoMethod *method = NULL;

	if (mono_image_get_assembly (mono_defaults.corlib)->aname.major < 2)
		return NULL;

	/* older corlib revisions won't have the class (nor the method) */
	MonoClass *execution_context = mono_class_try_get_execution_context_class ();
	if (execution_context && !method) {
		mono_class_init (execution_context);
		method = mono_class_get_method_from_name (execution_context, "Capture", 0);
	}

	return method;
}
Beispiel #7
0
/*
 * Context propagation is required when:
 * (a) the security manager is active (1.x and later)
 * (b) other contexts needs to be propagated (2.x and later)
 *
 * returns NULL if no context propagation is required, else the returns the
 * MonoMethod to call to Capture the ExecutionContext.
 */
MonoMethod*
mono_get_context_capture_method (void)
{
	static MonoMethod *method = NULL;

	if (mono_image_get_assembly (mono_defaults.corlib)->aname.major < 2)
		return NULL;

	/* older corlib revisions won't have the class (nor the method) */
	MonoClass *execution_context = mono_class_try_get_execution_context_class ();
	if (execution_context && !method) {
		ERROR_DECL (error);
		mono_class_init_internal (execution_context);
		method = mono_class_get_method_from_name_checked (execution_context, "Capture", 0, 0, error);
		mono_error_assert_ok (error);
	}

	return method;
}
Beispiel #8
0
/*
 * 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(); */
}
Beispiel #9
0
/*
 * 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;
}
Beispiel #10
0
static MonoObject *
virt_mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
{
  MonoDomain *domain;
  MonoObject *obj, *ret;

  g_assert (args);

  domain = mono_object_get_domain ((MonoObject *) args);
  mono_runtime_ensure_entry_assembly (domain,
      mono_image_get_assembly (
	mono_class_get_image (
	  mono_method_get_class (method))));


#if 0
#ifndef MONO_AGENT
  mono_new_thread_init (get_mono_thread(), &ret);
#endif
#endif
  obj = mono_object_new (domain, mono_method_get_class (method));

  ret = mono_runtime_invoke_array (method, obj, args, exc);

  return ret;

  /* FIXME: check signature of method
     if (method->signature->ret->type == MONO_TYPE_I4) {
     res = mono_runtime_invoke (method, NULL, pa, exc);
     if (!exc || !*exc)
     rval = *(guint32 *)((char *)res + sizeof (MonoObject));
     else
     rval = -1;
     fprintf (stderr, "[INT:%i]\n", rval);
     }
     else if (method->signature->ret->type == MONO_TYPE_SZARRAY)
     {
     MonoObject *res;
     int len;

     res = mono_runtime_invoke (method, NULL, pa, exc);
     rval = mono_array_length ((MonoArrayType *)res);
     len = mono_array_length ((MonoArray*)res);

     for (i = 0; i < len; ++i)
     {
     MonoObject *s; // = (MonoString *)mono_array_get ((MonoArray*)res, gpointer, i);
     fprintf (stderr, "[STRING:%s]\n", mono_string_to_utf8 ((MonoString *)s));
     }

     if (!exc || !*exc)
     rval = *(guint32 *)((char *)res + sizeof (MonoObject));
     else
     rval = -1;
     fprintf (stderr, "[INT:%i]\n", rval);
     } else {
     MonoObject *ress;
     ress = mono_runtime_invoke (method, NULL, pa, exc);
     fprintf (stderr, "[STRING:%s]\n", mono_string_to_utf8 ((MonoString *)ress));
     }

  //	return rval;*/
}
Beispiel #11
0
static gboolean
collect_coverage_for (MonoProfiler *prof, MonoMethod *method)
{
	int i;
	char *classname;
	char *fqn;
	MonoMethodHeader *header;
	gboolean has_positive, found;
	guint32 iflags, flags, code_size;
	MonoClass *klass;
	MonoImage *image;

	flags = mono_method_get_flags (method, &iflags);
	if ((iflags & 0x1000 /*METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL*/) ||
	    (flags & 0x2000 /*METHOD_ATTRIBUTE_PINVOKE_IMPL*/))
		return FALSE;

	//if (method->wrapper_type != MONO_WRAPPER_NONE)
	//	return FALSE;

	klass = mono_method_get_class (method);
	image = mono_class_get_image (klass);
	/* Hacky way of determining the executing assembly */
	if (! prof->outfile_name && (strcmp (mono_method_get_name (method), "Main") == 0)) {
		prof->outfile_name = g_strdup_printf ("%s.cov", mono_image_get_filename (image));
	}

	/* Check filters */
	if (prof->filters) {
		/* Check already filtered classes first */
		if (g_hash_table_lookup (prof->filtered_classes, klass))
			return FALSE;

		classname = mono_type_get_name (mono_class_get_type (klass));

		fqn = g_strdup_printf ("[%s]%s", mono_image_get_name (image), classname);

		// Check positive filters first
		has_positive = FALSE;
		found = FALSE;
		for (i = 0; i < prof->filters->len; ++i) {
			char *filter = g_ptr_array_index (prof->filters_as_str, i);
			if (filter [0] == '+') {
				filter = &filter [1];
				if (strstr (fqn, filter) != NULL)
					found = TRUE;
				has_positive = TRUE;
			}
		}
		if (has_positive && !found)
			return FALSE;

		for (i = 0; i < prof->filters->len; ++i) {
			// Is substring search suffices ???
//			GPatternSpec *spec = g_ptr_array_index (filters, i);
//			if (g_pattern_match_string (spec, classname)) {
			char *filter = g_ptr_array_index (prof->filters_as_str, i);
			if (filter [0] == '+')
				continue;

			// Skip '-'
			filter = &filter [1];
			if (strstr (fqn, filter) != NULL) {
				g_hash_table_insert (prof->filtered_classes, klass, klass);
				return FALSE;
			}
		}
		g_free (fqn);
		g_free (classname);
	}

	header = mono_method_get_header (method);

	mono_method_header_get_code (header, &code_size, NULL);
	if (code_size > 20000) {
		exit (1);
		g_warning ("Unable to instrument method %s:%s since it is too complex.", mono_class_get_name (klass), mono_method_get_name (method));
		return FALSE;
	}

	g_hash_table_insert (prof->methods, method, method);

	g_hash_table_insert (prof->classes, klass, klass);

	g_hash_table_insert (prof->assemblies, mono_image_get_assembly (image), mono_image_get_assembly (image));

	return TRUE;
}