Jump to navigation

Poupou's Corner of the Web

Looking for perfect security? Try a wireless brick.
Otherwise you may find some unperfect stuff here...


Being ignored

Code Access Security (CAS) work in progressing. Right now I'm looking into executing declarative security attributes, starting with SecurityAction.LinkDemand. LinkDemand is different because it is a JIT time action (and my first time hacking into mini). This means that any SecurityException will be thrown when the JIT compiles IL into native code.

In order to test this I have created a DebugPermission and it's associated DebugPermissionAttribute. This isn't a CAS permission, i.e. DebugPermission doesn't derive from CodeAccessPermission but directly implements IPermission (just like PrincipalPermission does) - and the JIT doesn't have to care about this. The important thing is that this allows the permission to provide it's own Demand implementation - required for my testing/debugging purpose. Anyway LinkDemand doesn't involve a stack walk, so I ain't loosing nothing.

The cool thing about DebugPermission is that is shows when and how compilers and the JIT use the permission. Much cooler is that this indirectly shows what's being ignored!

// This sample tries to use as much different LinkDemand as possible (from a // valid C# compiler point of view) without actually triggering the JIT to // call Demand. // // The problem is that there is no relation between an AttributeTarget // (enforced by the compiler) and a SecurityAction (enforced by the JIT, // runtime or security manager). // // Commented LinkDemand cause compilation failures (CS1577, CS0647) // Non commented LinkDemand are ignored by the JIT using System; using System.Security; using System.Security.Permissions; using Mono.Permissions; // CS1577: Assembly generation failed -- SecurityAction type invalid on assembly. //[assembly: DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="assembly")] [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="interface")] public interface Display { [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="interface method")] int Show (string message); } [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="enum")] public enum Kind { // CS0647 - Security custom attribute attached to invalid parent. // [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="enum member")] WithLinkDemand, WithoutLinkDemand } [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="struct")] public struct Data { // CS0647 - Security custom attribute attached to invalid parent. // [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="struct member")] public string Message; } public delegate int DisplayHandler (string msg); public class Program : Display { // CS0647 - Security custom attribute attached to invalid parent. // [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="static field")] static string ep; static Data data; // CS0647 - Security custom attribute attached to invalid parent. // [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="field")] string product = "Mono"; // CS0647 - Security custom attribute attached to invalid parent. // [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="event")] public event DisplayHandler OnShow; [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="static constructor")] static Program () { ep = "entrypoint"; data = new Data (); data.Message = "Hello {0}!"; } // CS0647 - Security custom attribute attached to invalid parent. // [return: DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="return value")] public int Show (string message) { return OnShow (message); } public int Display ( // CS0647 - Security custom attribute attached to invalid parent. // [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="parameter")] string message) { Console.WriteLine (message); return 0; } [DebugPermission (SecurityAction.LinkDemand, Fail=true, Message="entrypoint")] static public void Main (string [] args) { Console.WriteLine ("{0}.starts", ep); Program p = new Program (); p.OnShow += new DisplayHandler (p.Display); p.Show (String.Format (data.Message, p.product)); Console.WriteLine ("{0}.end", ep); } }

First thing we notice is that even if DebugPermissionAttribute supports all targets, AttributeTargets.All, the compiler will reject some usages. This is because there's is no relation between AttributeTargets and SecurityAction (neither in design nor documented AFAIK).

Second thing we see is that DebugPermission is very verbose about its usage and shows a nice (but too long to be included here) log when compiled by CSC. This means the compiler is actually doing work for all, non-commented, security attributes in the sample (actually it call IsSubsetOf and, if true is returned, ToXml). However when we execute the sample we get... nothing from DebugPermission.

# linkdemand_ignored.exe entrypoint.starts Hello Mono! entrypoint.end

Nothing because the JIT ignores them! So if you ever used LinkDemand in your code I hope you tested them well enough because getting them compiled wasn't enough ;-)

Note: Please email me any other ignored case I may have missed in my sample, as this will ends up in the Mono regression testing.

9/30/2004 10:15:37 | Comments

The views expressed on this website/weblog are mine alone and do not necessarily reflect the views of my employer.