Bugzilla – Bug 315667
MCS doesn't encode SecurityAttributes properly
Last modified: 2007-09-15 21:24:23 UTC
---- Reported by sebastien@ximian.com 2004-08-03 09:26:19 MST ---- Description of Problem: MCS encodes "SecurityAttribute"s like any other Attribute. Attributes deriving from SecurityAttributes should be XML encoded in the assembly metadata. Steps to reproduce the problem: 1. Source code sample using System; using System.Security; using System.Security.Permissions; [assembly: SecurityPermission (SecurityAction.RequestMinimum, Execution=true)] [assembly: SecurityPermission (SecurityAction.RequestOptional, Unrestricted=true)] [assembly: SecurityPermission (SecurityAction.RequestRefuse, SkipVerification=true)] [SecurityPermission (SecurityAction.Demand, ControlAppDomain=true)] public class Program { [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)] static public void Main (string[] args) { Console.WriteLine ("Hello Mono!"); } } 2. Compile the previous code with MCS and disassemble it 3. Compile the previous code with CSC and disassemble it Actual Results (compiled with MCS / disassembled by monodis): .assembly extern mscorlib { .ver 1:0:5000:0 } .assembly 'secattrs' { .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 08 00 00 00 01 00 54 02 09 45 78 65 63 75 // ........T..Execu 74 69 6F 6E 01 ) // tion. .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 09 00 00 00 01 00 54 02 0C 55 6E 72 65 73 // ........T..Unres 74 72 69 63 74 65 64 01 ) // tricted..assembly extern mscorlib { .ver 1:0:5000:0 } .assembly 'secattrs' { .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 08 00 00 00 01 00 54 02 09 45 78 65 63 75 // ........T..Execu 74 69 6F 6E 01 ) // tion. .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 09 00 00 00 01 00 54 02 0C 55 6E 72 65 73 // ........T..Unres 74 72 69 63 74 65 64 01 ) // tricted. .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 0A 00 00 00 01 00 54 02 10 53 6B 69 70 56 // ........T..SkipV 65 72 69 66 69 63 61 74 69 6F 6E 01 ) // erification. .hash algorithm 0x00008004 .ver 0:0:0:0 } .module secattrs.exe // GUID = {4253E319-1732-4D0F-874E-405AE51B30D5} .class public auto ansi beforefieldinit Program extends [mscorlib]System.Object { .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 02 00 00 00 01 00 54 02 10 43 6F 6E 74 72 // ........T..Contr 6F 6C 41 70 70 44 6F 6D 61 69 6E 01 ) // olAppDomain. // method line 1 .method public hidebysig specialname rtspecialname instance default void .ctor () cil managed { // Method begins at RVA 0x20ec // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Program::instance default void .ctor () // method line 2 .method public static hidebysig default void Main (string[] args) cil managed { .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 02 00 00 00 01 00 54 02 10 43 6F 6E 74 72 // ........T..Contr 6F 6C 50 72 69 6E 63 69 70 61 6C 01 ) // olPrincipal. .param [1] // Method begins at RVA 0x20f4 .entrypoint // Code size 11 (0xb) .maxstack 8 IL_0000: ldstr "Hello Mono!" IL_0005: call void class [mscorlib]System.Console::WriteLine(string) IL_000a: ret } // end of method Program::default void Main (string[] args) } // end of class Program .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 0A 00 00 00 01 00 54 02 10 53 6B 69 70 56 // ........T..SkipV 65 72 69 66 69 63 61 74 69 6F 6E 01 ) // erification. .hash algorithm 0x00008004 .ver 0:0:0:0 } .module secattrs.exe // GUID = {4253E319-1732-4D0F-874E-405AE51B30D5} .class public auto ansi beforefieldinit Program extends [mscorlib]System.Object { .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 02 00 00 00 01 00 54 02 10 43 6F 6E 74 72 // ........T..Contr 6F 6C 41 70 70 44 6F 6D 61 69 6E 01 ) // olAppDomain. // method line 1 .method public hidebysig specialname rtspecialname instance default void .ctor () cil managed { // Method begins at RVA 0x20ec // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Program::instance default void .ctor () // method line 2 .method public static hidebysig default void Main (string[] args) cil managed { .custom instance void class [mscorlib]System.Security.Permissions.SecurityPermissionAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction) = ( 01 00 02 00 00 00 01 00 54 02 10 43 6F 6E 74 72 // ........T..Contr 6F 6C 50 72 69 6E 63 69 70 61 6C 01 ) // olPrincipal. .param [1] // Method begins at RVA 0x20f4 .entrypoint // Code size 11 (0xb) .maxstack 8 IL_0000: ldstr "Hello Mono!" IL_0005: call void class [mscorlib]System.Console::WriteLine(string) IL_000a: ret } // end of method Program::default void Main (string[] args) } // end of class Program Expected Results (compiled with CSC / disassembled by ildasm): (too big see attachement) How often does this happen? Always as current MCS source code doesn't seems to be using AddDeclarativeSecurity anywhere. Additional Information: * Section 5 of the document "DeclarativeSecuritySupport.doc" has some information on how to encode security attributes from managed code. * This also adds "false" additions (attributes) to corcompare results. * The same issue probably applies to other compilers / assembler. * Workaround is to use CSC to compile the assemblies. ---- Additional Comments From sebastien@ximian.com 2004-08-03 09:27:26 MST ---- Created an attachment (id=166575) csc-ildasm ---- Additional Comments From sebastien@ximian.com 2004-09-16 11:39:54 MST ---- Informational Note (this shouldn't affect the compiler): The 2.0 runtime doesn't encode security permission as XML. They are encoded just like other "normal" permissions (space saver). However they are still located in the same place - and can't be read by GetCustomAttribute(s). ---- Additional Comments From sebastien@ximian.com 2004-10-05 10:49:58 MST ---- There are also three "hidden" security actions (with different IDs) that deals with non-CAS permissions. I.e. permissions that do not derive from CodeAccessPermission - but still implements IPermission (e.g. PrincipalPermission). from /mono/mono/metadata/tabledefs.h (recent CVS) SECURITY_ACTION_NONCASDEMAND = 13, SECURITY_ACTION_NONCASLINKDEMAND = 14, SECURITY_ACTION_NONCASINHERITANCE = 15, This requires the compiler to split entries for Demand, LinkDemand and InheritDemand based on the type of the permission. * see attached: casnoncas.cs compile with CSC and disassemble with ILDASM (or CVS monodis) Calling .AddDeclarativeSecurity, with the appropriate (visible or hidden) SecurityAction should encode permissions correctly in the metadata. Note 1: It seems that adding only a non-CAS permission also creates an (empty) CAS permission set. I don't know if this is important (i.e. required on MS runtime ?) because it has no value (empty) and takes more processing (adds an unrequired call from unmanaged to managed). * see attached: noncasonly.cs compile with CSC and disassemble with ILDASM (or CVS monodis) Note 2: the "hidden" actions doesn't seems to be used in the new metadata format used by 2.0. ---- Additional Comments From sebastien@ximian.com 2004-10-05 11:31:47 MST ---- Samples were posted to wrong bug :( Here are the links to them [1] casnoncas.cs http://bugzilla.ximian.com/showattachment.cgi?attach_id=12062 [2] noncasonly.cs http://bugzilla.ximian.com/showattachment.cgi?attach_id=12063 ---- Additional Comments From sebastien@ximian.com 2004-10-06 10:41:42 MST ---- Another case to check (related to the previous one) Non-CAS permissions cannot be used for SecurityAction.Assert, Deny or PermitOnly (see new attachement cs0647-assert.cs). $ csc cs0647-assert.cs Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4 for Microsoft (R) .NET Framework version 1.1.4322 Copyright (C) Microsoft Corporation 2001-2002. All rights reserved. cs0647-assert.cs(7,2): error CS0647: Error emitting 'System.Security.Permissions.PrincipalPermissionAttribute' attribute -- 'Invalid SecurityAction for non-Code Access Security permission.' Note: This check is done only in 1.0/1.1 (CSC 7.0/7.1). C# 2.0 (CSC 8.0) does compile the assembly (and the assert is encoded into the assembly metadata, but probably ignored later). ---- Additional Comments From sebastien@ximian.com 2004-10-06 10:42:35 MST ---- Created an attachment (id=166576) cs0647-assert.cs ---- Additional Comments From marek.safar@seznam.cz 2004-10-27 17:09:16 MST ---- Fixed in CVS Uff :-) Imported an attachment (id=166575) Imported an attachment (id=166576)