Whidbey's Security Off Model
Although the v1.0 and v1.1 versions of CasPol provided a switch to disable the CLR's security system, running without CAS enforcement on was never a scenario that we encouraged for obvious reasons. The choice to disable security was a system wide switch that affected any managed application on any version of the runtime, and made running managed code incredibly unsafe.
As of Whidbey, you'll find that the switch to turn security off no longer works as it used to. If you run caspol -s off with beta 2 or later of Whidbey installed, you'll see:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215>CasPol.exe -s off
Microsoft (R) .NET Framework CasPol 2.0.50215.44
Copyright (C) Microsoft Corporation. All rights reserved.
CAS enforcement is being turned off temporarily. Press <ENTER> when you want to
restore the setting back on.
Security will then be disabled as long as the CasPol process remains active. When CasPol is terminated, it returns security to the on state. Even abruptly terminating the CasPol process will still return security to its on state.
This works because the implementation of the internal security off flag has changed. Instead of using a registry key to indicate the status of CLR security, we now use a named mutex which CasPol holds to indicate to the CLR that it should disable security. Examining the the handles held by the CasPol process in a debugger will enable you to quickly identify this mutex:
0:000>!handle 0 4 Mutant
Handle 4c
Name \BaseNamedObjects\CLR_CASOFF_MUTEX
Handle 428
Name <none>
Handle 4a8
Name \BaseNamedObjects\ShimCacheMutex
Handle 624
Name <none>
4 handles of type Mutant
Since security is being disabled by this mutex, the CasPol process is resilient to being terminated unexpectedly, because Windows will just clean up the handle for CasPol when cleaning up the process. Another side effect is that if the machine is rebooted, the security state will revert to on.
If we fire up the kernel debugger, we can take a look at the ACL of the mutex:
lkd> !object \BaseNamedObjects\CLR_CASOFF_MUTEX
Object: 85088d88 Type: (8679f040) Mutant
ObjectHeader: 85088d70
HandleCount: 1 PointerCount: 2
Directory Object: e179f980 Name: CLR_CASOFF_MUTEX
lkd> dt nt!_OBJECT_HEADER 85088d70
+0x000 PointerCount : 2
+0x004 HandleCount : 1
+0x004 NextToFree : 0x00000001
+0x008 Type : 0x8679f040
+0x00c NameInfoOffset : 0x10 ''
+0x00d HandleInfoOffset : 0 ''
+0x00e QuotaInfoOffset : 0 ''
+0x00f Flags : 0x20 ' '
+0x010 ObjectCreateInfo : 0x853e3678
+0x010 QuotaBlockCharged : 0x853e3678
+0x014 SecurityDescriptor : 0xe2c57b2c
+0x018 Body : _QUAD
lkd> ?? 0xe2c57b2c & ~0x7
unsigned int 0xe2c57b28
lkd> !sd e2c57b28 1
->Revision: 0x1
->Sbz1 : 0x0
->Control : 0x8004
SE_DACL_PRESENT
SE_SELF_RELATIVE
->Owner : S-1-5-32-544 (Alias: BUILTIN\Administrators)
->Group : S-1-5-21-2127521184-1604012920-1887927527-513 (Group: REDMOND\Domain Users)
->Dacl :
->Dacl : ->AclRevision: 0x2
->Dacl : ->Sbz1 : 0x0
->Dacl : ->AclSize : 0x34
->Dacl : ->AceCount : 0x2
->Dacl : ->Sbz2 : 0x0
->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl : ->Ace[0]: ->AceFlags: 0x0
->Dacl : ->Ace[0]: ->AceSize: 0x18
->Dacl : ->Ace[0]: ->Mask : 0x001f0001
->Dacl : ->Ace[0]: ->SID: S-1-5-32-544 (Alias: BUILTIN\Administrators)
->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl : ->Ace[1]: ->AceFlags: 0x0
->Dacl : ->Ace[1]: ->AceSize: 0x14
->Dacl : ->Ace[1]: ->Mask : 0x001f0001
->Dacl : ->Ace[1]: ->SID: S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM)
->Sacl : is NULL
That shows that the mutex is created with an ACL that prevents anyone who isn't an administrator from owning it. And although Windows does not provide a way to prevent non-administrators from creating this mutex, internally the CLR will not respect the existence of the named mutex if it is abandoned or not owned by the BUILTIN\Administrators group. This prevents a squatting attack where a malicious user could turn off security simply by creating this mutex himself.
One of the more interesting effects to note of disabling security with this mutex is that the v2.0 CLR will no longer respect the registry key used by older versions of the runtime, and those versions will not have their security disabled by the new CasPol switch.
Although there still is the ability to turn off security, the ability to turn it off permanently has been removed. The new switch is useful mostly for debugging purposes, to establish if a problem you're diagnosing is related to the security system or not. The recommendation is still to avoid using this mechanism if at all possible.
Comments
- Anonymous
April 28, 2005
I've been wondering about some of the pickier details of this for a while and, since the beta docs still don't seem to have been updated to reflect this change, perhaps you might be willing to answer a few questions...?
1. Is it intended that "caspol -s on" still declare its own success despite the fact that it does nothing? If not, shouldn't the option either be eliminated or its result message be altered?
2. Since the setter for the SecurityManager.SecurityEnabled property no longer does anything, shouldn't it be obsoleted and/or throw a NotSupportedException?
3. The beta 2 behaviour appears to have the switch acting at the user level rather than the system level. While I'm quite happy to see the most restrictive possible behaviour, I'm guessing that folks who disable CAS for troubleshooting purposes might run into a few problems with a user-level switch, so I'm wondering if this is really the intended behaviour. - Anonymous
April 28, 2005
Sure,
1. CasPol -s on needed to be kept around for backwards compatibility. We didn't want to break any scripts that relied on calling CasPol -s on.
2. For the same reason, we could not cause SecurityEnabled to throw an exception. That would break anyone who tried to toggle the property in the first place. Unfortunately the ObsoleteAttribute cannot be applied directly to the setter, and the getter is useful so we don't want to obsolete the property as a whole.
3. The behavior should be per-system. For instance, on my Windows 2003 machine, I turned security off on the console session, then connected via terminal server to a second session as a second user. The second session respsected the settings of the first one.
-Shawn - Anonymous
April 28, 2005
The comment has been removed - Anonymous
April 28, 2005
Great feedback -- I've filed tracking issues on the first two points and we'll make sure to look at them.
You're right about the Windows XP thing, when I follow your steps I reproduce the problem. The correct behavior is to be a per-machine switch, so I've also filed a bug on that issue.
Thanks for all the feedback!
-Shawn - Anonymous
April 28, 2005
The comment has been removed - Anonymous
April 28, 2005
Turning Off Code Access Security in .NET 2.0 - Anonymous
April 28, 2005
Many thanks for filing the bug reports. Do you happen to know if there's already a documentation revision in the works for this stuff? It doesn't seem quite fair to impose upon you for intended behaviour confirmation just because you're the only one actually describing the changed behaviour. It's even worse when you then shoulder the grunt work of generating the bug reports... ;) - Anonymous
April 29, 2005
Kevin -- correct, as of now, CasPol is the only shipping way to toggle the security switch.
Nicole -- if the information didn't make it to the MSDN docs that shipped with beta 2, then unfortunately it won't get doced until we RTM. No problem confirming what you see and filing bugs though :-)
-Shawn - Anonymous
May 04, 2005
Last time we looked at how the Whidbey version of CasPol uses a mutex to indicate the state of the security... - Anonymous
May 10, 2005
I've got just a few loose ends to tie up about our new security off behavior, and then we'll move on... - Anonymous
July 27, 2005
caspol -s off turned security checks into no-ops under 1.1. for severely performance critical applications that run in a controlled environment, what configuration gives you the most raw speed? - Anonymous
July 27, 2005
Brien -- you should not be using caspol -s off for performance reasons on any framework. This leaves your machine wide open to attack for little performance gain.
In v2.0 we've done a lot of work to make sure the security subsystem is even faster, so using it for this reason is even more unnecessary.
-Shawn - Anonymous
July 28, 2005
Shawn,
I understand your statement for a general purpose machine, or a desktop, but how is caspol -s a risk for a dedicated server used only for internal server applications?
Brien - Anonymous
July 28, 2005
The rules of performance work are measure, measure, measure. [http://blogs.msdn.com/ricom]. It is extremely unlikely that you're in a situation where security is causing your application ot slow down appreciably. Have you demonstrated that security is the perf problem with your app? In general, trading security for performance is a very bad idea.
-Shawn - Anonymous
July 29, 2005
Shawn,
For background, over the next few months I'll be building a system that needs to operate in real time and will be sensitive to sub-millisecond delays. It will be built and deployed under 1.1 but eventually ported to Whidbey when it is released. Absolute speed is a requirement. Hopefully, I've convinced you that my requirements fall in the "extremely unlikely" bucket.
So, assuming I do everything I can to make my application code fast, I'm trying to understand what I can do to the CLR to juice it. Every few percent counts.
Your generalizations make sense, but for my specific circumstances, please assume that speed equates to money and there is a non-linear cost benefit the faster you go.
Thanks,
Brien - Anonymous
August 24, 2005
There's a ton of new and enhanced security features coming with the v2.0 release of the CLR.&nbsp; However,... - Anonymous
August 31, 2005
There's a ton of new and enhanced security features coming with the v2.0 release of the CLR.&nbsp; However,...