One of our new Whidbey hosting features is called Host Protection — basically it allows an application hosting the CLR to declare some types of operations off limits for use by hosted code. This is orthogonal to CAS in that CAS allows an administrator to say what is allowed and a CAS grant set can change depending on the evidence of an assembly. In contrast, host protection allows a host to say what is not allowed, and this set of operations is independent of the assembly’s evidence.
It’s important to make the distinction that host protection isn’t a security feature as much as it’s a reliability feature. It’s design is to allow for hosts to say “In my environment, it doesn’t make sense for code to do x”. For instance normally partially trusted code can wait on a named mutex, as long as the user account has rights to that mutex. However, SQL Server 2005 obviously doesn’t want one of its threads waiting on an external synchronization object. Another obvious example is that SQL Server also doesn’t want any assemblies to show user interface. Chris Brumme explains more about how host protection is a reliability feature rather than a security feature in his entry on hosting (scroll down to item #2 in his unsafe category — that’s where he starts talking about it).
Rather than specifying a set of permissions to disallow, the host specifies categories of operations. These categories can be found in the System.Security.Permissions.HostProtectionResource enumeration and it’s unmanaged counterpart the EApiCategories enumeration, which is defined in mscoree.h. The operations that can be protected in v2.0 include:
- External process management
- External threading
- May leak on abort
- Security infrastructure
- Self affecting process management
- Self affecting threading
- Shared state
Managed APIs that fall into one of these categories declare this by decorating themselves with the HostProtectionAttribute specifying which combination of categories they expose. For instance, the Process class has a HostProtectionAttribute marked with shared state, synchronization, external process management, and self affecting process management. ReaderWriterLock is decorated with synchronization and external threading.
If the host enables protection on a specific category, APIs marked with a HostProtecitonAttribute for that category will essentially have a security demand for HostProtectionPermission placed on them. Since HostProtectionPermission is a permission internal to mscorlib, no user code will ever be granted it and therefore enabling protection on a category prevents hosted code from ever calling into it. If a category is not protected, the attribute “evaporates” away, and the API as if there were no extra demands on it. Incidentally this is where the original name of this feature, permission evaporation, came from.
HostProtectionPermission is a special permission not only in that it is internal to mscorlib and should never appear in your grant set, but also in what happens when a demand for it fails. When the CLR detects that a demand for HostProtectionPermission fails, instead of throwing a SecurityException, we’ll actually throw a HostProtectionException instead. The English message that goes with HostProtectionException will be “Attempted to perform an operation that was forbidden by the CLR host.”
Notice that since host protection is implemented as a demand for HostProtectionPermission under the covers that fully trusted code will in fact satisfy the demand and still be granted access to the protected APIs.
Next time we’ll take a look at how you actually go about enabling host protection in your CLR host.