Host Protection
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
- Synchronization
- Shared state
- UI
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.
Comments
Anonymous
October 12, 2005
Hi,
I am working on runtime for a language vendor and I have a question for you!
Q. If you have an assembly that has a loose contract between two static methods and you need to pass information between but without using "this" or as a parameter how can you do this? But still want the assembly to be SQLCLR SAFE.
For example:
private static readonly LocalDataStoreSlot localSlot;
static SQLSUB()
{
localSlot = Thread.AllocateDataSlot();
}
private static string GetMessage()
{
return Thread.GetData(localSlot).ToString() +" from HelloSub";
}
public static string Message()
{
Thread.SetData(localSlot, "Hello");
return GetMessage()+" [CS]";
}
This example will fail in the class constructor with a HostProtection exception (requires: SharedState, ExternalThreading permissions). The use of [ThreadStatic] does not help because the attribute is not permitted and it also applies to “static field”.
What options do I have?
--
stephen at gennard . netAnonymous
November 04, 2005
Stephen,
Could you setup a static Dictionary<int, string> to enable this scenario?
-ShawnAnonymous
March 30, 2009
Shawn, I am creating a Custom Data Extension for SSRS over our data access layer which uses nHibernate. I am getting the 'Attempted to perform an operation that was forbidden by the CLR host' error. Is there anyway I can disable the CLR Host Protection for my Custom Data Extension. Thanks in advance, AmitabhAnonymous
May 21, 2009
The CLR doesn't provide a general mechanism to disable host protection (otherwise the hosts wouldn't be too happy :-) ). Individual hosts may have a way to do so, but in general that won't be possible. -ShawnAnonymous
October 24, 2010
Is it this Host Protection that is blocking my Trace.Writes to not cross boundaries like System account to logged in user account?