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...


Mono Security Manager Part IV - LinkDemand

It took me some time to blog about them but a lot of new CAS features have been added in Mono 1.1.5. You can keep an eye on the CAS status page for more frequent updates on any new feature.

One of the new features is support for LinkDemand. LinkDemands are very similar to demands (which are sometimes called "full demands" when compared to linkdemands). The main difference is that linkdemand are executed at JIT time (instead of at run time). If you google about them you'll see that many articles and books will stop their description right there, while some will give more details (e.g. "it's less secure") without explaining why.

First methods are JITed only once (well that's true for the current versions of Mono but even with dynamic re-compilation the method won't be recompiled at every execution). Evaluating the stack at this time would be pointless. E.g.

public void DoSomethingSafe () { // secure everything CallSomethingCritical (); // clean up } public void DoSomethingEvil () { // prepare evil conquests CallSomethingCritical (); // send bugs and spam to everyone }

JITing CallSomethingCritical when being called from DoSomethingSafe would results in a different decision (stack wise) from JITing it from DoSomethingEvil. So instead of a stack walk (or the often mis-described one frame stack walk) we reverse the problem like this:

When JITing DoSomethingSafe we ask ourself if we have the permission to link to CallSomethingCritical. The same thing happens when we JIT DoSomethingEvil (hopefully with a different decision). Now the name LinkDemand make a little more sense :-).

The problem with reversing is that we loose the context of the call (actually there isn't much, security wise, at JIT time anyway). This is why this is (truely) less secure than a full demand. But linkdemands make sense when you use them properly (and not as a cheap version of full demands). Want a trick ? when in doubt use full demands ;-).

Another difference is that linkdemands can only be made declaratively by the programmer (or in a few special case by the CLR itself). No big lose since imperative link demand wouldn't make any sense at JIT time.

Special cases

There are a few special cases with linkdemands that requires more details:

  • Internal calls are protected by the CLR with something similar to linkdemands. I say similar because it's doesn't quite follow the same rules (you probably guessed that a stack walk wasn't needed/done for icalls). Actually 1.x and 2.0 CLR seems to use different rules about them too. Let's just assume that internal calls aren't made to be called outside a few trusted assemblies (e.g. by any application code) and you'll be safe in the future.

  • Some assemblies aren't designed to be executed under partial trust. In fact all strongnamed assemblies are considered, by default, unsafe for partial trust. The CLR enforce this by adding a LinkDemand for FullTrust on every publicly accessible (public and protected) methods on all publicly available classes in a assembly - unless the assembly is marked as safe by including the AllowPartiallyTrustedCallers attribute.

  • Reflection is cool but mess up the caller logic used by linkdemands. This is because the caller is always some code inside corlib (which is fully trusted). This would results in every linkdemand being granted when using reflection (it's not as bad as it sounds as reflection should only be granted to trusted code IMHO). Anyway the fix to this problem is to turn the linkdemand into a full demand. However this isn't not a perfect fix as the demand has far more chance to fail this way (when evaluating all the other frames in the stack).

There is another special case related to unmanaged code that I'll keep for a further entry...

4/15/2005 15:42:02 | Comments

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