[Mono-devel-list] Updated CAS patch for LinkDemand

Paolo Molaro lupus at ximian.com
Thu Feb 10 13:12:13 EST 2005


On 02/10/05 Sebastien Pouliot wrote:
> +++ metadata/security-manager.c	(working copy)
> @@ -36,11 +36,28 @@
>  		
>  	secman.demand = mono_class_get_method_from_name (secman.securitymanager,
>  		"InternalDemand", 2);	
> +	g_assert (secman.demand);

If this function is called when security is enabled it's fine to
assert, otherwise it should be either not called or it should not
assert, at least until the security aPI stabilizes.

> @@ -9003,6 +9022,23 @@
>  	if (cfg->prof_options & MONO_PROFILE_JIT_COMPILATION)
>  		mono_profiler_method_end_jit (method, MONO_PROFILE_OK);
>  
> +	/* this can only be set if the security manager is active */
> +	if (cfg->security_exception != MONO_JIT_SECURITY_OK) {
> +		MonoSecurityManager* secman = mono_security_manager_get_methods ();
> +		MonoObject *exc = NULL;
> +		gpointer args [3];
> +
> +		args [0] = (gpointer*) &cfg->security_exception;
> +		args [1] = (gpointer*) mono_assembly_get_object (domain, mono_image_get_assembly (method->klass->image));
> +		args [2] = (gpointer*) method;

The cast should not be needed here.

> Index: mini/mini.h
> ===================================================================
> --- mini/mini.h	(revision 40396)
> +++ mini/mini.h	(working copy)
> @@ -573,6 +573,7 @@
>  	guint16          *intvars;
>  	MonoProfileCoverageInfo *coverage_info;
>  	MonoCompileArch  arch;
> +	guint32          security_exception;

My idea was to add here:
	guint32          exception_type; /* from an enum: NONE, SECURITY, INALID_PROGRAM etc. */
	guint32          exception_data;
	char*            exception_message;

and at the correct points exception_type is checked and an helper
function creates the exception to be thrown. This is more general, since
we need to throw exceptions in other cases that are not directly 
security-related.

> +	* mini.c: Added LinkDemand checks in mono_method_to_ir for CEE_CALL 
> +	and CEE_CALLVIRT. Added code to throw exception at the end of

You likely want to handle also CEE_NEWOBJ and maybe CEE_JMP.

> Index: mini/declsec.c
> ===================================================================
> --- mini/declsec.c	(revision 40396)
> +++ mini/declsec.c	(working copy)
> @@ -94,3 +94,293 @@
[...]
> +mono_declsec_linkdemand_standard (MonoDomain *domain, MonoMethod *caller, MonoMethod *callee)
> +{
> +	MonoDeclSecurityActions linkclass, linkmethod;
> +
> +	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] = (gpointer*) refass;
> +		args [1] = (gpointer*) &linkclass;
> +		args [2] = (gpointer*) &linkmethod;

No cast required here and in the similar cases.

> +	assembly = mono_image_get_assembly (callee->klass->image);
> +	if (!MONO_SECMAN_FLAG_INIT (assembly->aptc)) {
> +		MonoCustomAttrInfo* cinfo = mono_custom_attrs_from_assembly (assembly);
> +		if (cinfo != NULL) {
> +			int i;
> +			/* look for AllowPartiallyTrustedCallersAttribute _inside_ mscorlib */
> +			for (i = 0; i < cinfo->num_attrs; ++i) {
> +				if (mono_defaults.corlib == cinfo->attrs [i].ctor->klass->image) {
> +					if (strncmp (cinfo->attrs [i].ctor->klass->name, 
> +					    "AllowPartiallyTrustedCallersAttribute", 38) == 0) {
> +						/* keep this value cached as it will be used very often */
> +						MONO_SECMAN_FLAG_SET_VALUE (assembly->aptc, TRUE);
> +						return FALSE;
> +					}
> +				}
> +			}

Use mono_custom_attrs_has_attr ().

> +	assembly = mono_image_get_assembly (icall->klass->image);
> +	if (!MONO_SECMAN_FLAG_INIT (assembly->ecma)) {
> +		guint32 size = 0;
> +		/* ECMA key isn't a real public key - this affect it's length (16) */
> +		/* ... and it's value 00000000000000000400000000000000 */
> +		const char *pk = mono_image_get_public_key (caller->klass->image, &size);
> +		if ((pk != NULL) && (size == MONO_ECMA_KEY_LENGTH) && (pk [8] == 0x04)) {
> +			int i, n = 0;
> +			for (i=0; i < size; i++)
> +				n += pk [i];
> +
> +			if (n == 4) {

Uhm, when char is signed it may be possible to get a public key (though with likely
quite a bit of cpu time) that gives 4 as the sum. I'd use an helper method anyway that
checks all the bytes.
Feel free to commit after the changes.
Thanks!

lupus

-- 
-----------------------------------------------------------------
lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better



More information about the Mono-devel-list mailing list