I just saw this question:
Understanding .NET’s “SecurityAction” parameter for permissions
And I have a question. With the following code:
private void button1_Click(object sender, EventArgs e) { Layer1(); MessageBox.Show('OK'); } private void Layer1() { try { Layer2(); } catch (SecurityException) { MessageBox.Show('Caught'); } Layer2b(); } private void Layer2() { new System.Security.Permissions.FileIOPermission(PermissionState.Unrestricted).Deny(); GC.Collect(); Layer3(); } private void Layer2b() { Layer3(); } [FileIOPermission(SecurityAction.LinkDemand, Write=@'C:\temp')] private void Layer3() { using (FileStream stream = new FileStream(@'C:\temp\test.txt', FileMode.Create)) { } }
why does the code produce a security exception with the call to Layer2? How is the permission object treated, I’d imagine that the garbage collector would destroy the object, since I don’t have an active reference to it, but the code says Caught, and then OK, so clearly the permission denial is in effect for the call through Layer2.
What gives? What am I missing? I’ll admit to being a total beginner when it comes to the security/permission system in .NET so forgive me if this question is really basic.
Does a security permission/denial like this flag the stack or something? Otherwise, why is it not in effect for Layer2b? It’s the same thread, so clearly, while it isn’t killed by garbage collection, it is getting removed/destroyed/cleaned out at some point.
Calling .Deny() on a CodeAccessPermission will cause the .NET Security runtime to set the deny flag on the security object for the current stack frame for that permission. So even if you call GC.Collect() after calling .Deny(), it doesn’t really matter, the permission will stay in effect. The permission object is just a representation of state of the part of the .NET security runtime at a point in time (a stack frame).
Just use .NET Reflector to learn more.