Chapter 12. Enforcing Application-Specific Programming Model Constraints

As the managed code programming model becomes more widely adopted both within Microsoft and in the community in general, the range of capabilities available through managed class libraries will continue to grow. This trend will become even more apparent in future versions of the Microsoft Windows operating system when more and more of the existing Microsoft Win32 API is superseded with managed class libraries. However, not all of the capabilities available to add-ins through managed class libraries are appropriate in all hosting scenarios. For example, the ability to display a user interface doesn’t fit at all in server scenarios, and the ability to call a managed API that will cause the process to exit isn’t appropriate in hosting scenarios that require long process lifetimes.

What’s required is a mechanism for an extensible application to block certain categories of functionality that don’t fit with its overall programming model. The CLR hosting interfaces offer a feature called host protection that is designed specifically for this purpose. Because host protection is exposed through the CLR hosting interfaces, your application must be a full CLR host to use the feature.

The host protection feature identifies categories of functionality that are deemed of interest in various hosting scenarios. Hosts can then indicate that certain categories of functionality are not allowed within the host’s process. Examples of host protection categories in Microsoft .NET Framework 2.0 include the ability to share state or perform synchronization across threads, the ability to affect the host’s process or any of its threads, the ability to display user interface, and so on.

Given the identification of the host protection categories, two steps are necessary to enable a host to prevent categories of functionality from being used in their process. First, the .NET Framework class libraries must be annotated with a custom attribute called the HostProtectionAttribute that identifies which APIs belong to which categories. For example, the System.Threading.Thread class has several methods that would allow an add-in to affect how threads are created and used within a process. These members have all been marked with the HostProtectionAttribute, indicating that they belong to the threading category. HostProtectionAttribute is typically applied to types and members, but can also be applied to entire assemblies, value types, and delegates as well. Also, members of interfaces can also be annotated. In this case, all implementations of those methods in derived classes are automatically considered annotated as well. The annotation of the .NET Framework class libraries has been done as part of the version 2.0 release. The host must then enable host protection by indicating which categories of functionality should be blocked. This is done using the host protection manager in the CLR hosting interfaces. Specifically, the host asks the CLR for an interface of type ICLRHostProtectionManager through which it tells the CLR which categories should be blocked.

The host protection feature in its current form has been designed specifically with the requirements of the Microsoft SQL Server 2005 host in mind. This design is apparent in two ways. First, the host protection categories that have been defined in .NET Framework 2.0 are designed specifically to meet the needs of the SQL programming model. Second, not all of the .NET Framework class libraries have been annotated with the HostProtectionAttribute. Only those assemblies that SQL Server 2005 allows in its process have been annotated. (SQL Server uses an assembly loading manager to restrict which .NET Framework assemblies can be loaded, as described in Chapter 8.) The methods and types in an assembly that has not been annotated cannot be blocked using host protection. As time goes on, I expect both that the number of host protection categories will be expanded to meet the needs of other hosts and that the number of managed code libraries that are annotated with HostProtectionAttribute will increase. Nevertheless, if your hosting requirements are similar to those of SQL Server, you might find the current host protection categories adequate.

The goals of host protection are often confused with the goals of Code Access Security (CAS) for obvious reasons—both are techniques used to prevent a particular class or method from being used in a process. However, the motivation behind these two features is quite different. CAS is about protecting your process and the machine on which it is running from malicious access to protected resources, whereas host protection is merely about enforcing specific characteristics of a given host’s programming model. The difference between CAS and host protection can best be seen by looking at the consequences that could occur were each feature to be compromised. A vulnerability in CAS (or its use) results in unauthorized access to a protected resource, or a security vulnerability. In contrast, compromising host protection results only in a violation of the programming model. Such a violation can cause the host to perform poorly or even to crash, but it does not allow unauthorized access to a protected resource. There is one case in which CAS and host protection are directly related, however. When a host specifies that certain categories of functionality should be blocked, those categories are blocked only for partially trusted assemblies. Assemblies granted full trust are exempt from host protection—they can use any API they want.

This chapter describes how to use host protection to limit the functionality available to the add-ins you load into your extensible application. I start by describing the host protection categories. The description of each category includes a list of the types, methods, and properties that are currently identified as belonging to that category using the HostProtectionAttribute. After the categories are described, I show you how to use ICLRHostProtectionManager to tell the CLR which categories should be blocked.

The Host Protection Categories

The host protection categories are defined by the HostProtectionResource enumeration from the System.Security.Permissions namespace:

[Flags, Serializable]
   public enum HostProtectionResource
   {
       None                        = 0x0,
       Synchronization             = 0x1,
       SharedState                 = 0x2,
       ExternalProcessMgmt         = 0x4,
       SelfAffectingProcessMgmt    = 0x8,
       ExternalThreading           = 0x10,
       SelfAffectingThreading      = 0x20,
       SecurityInfrastructure      = 0x40,
       UI                          = 0x80,
       MayLeakOnAbort              = 0x100,
       All                         = 0x1ff,
   }

Given that host protection has initially been designed with SQL Server 2005 in mind, the best way to understand the motivation behind the host protection categories is to think of them in the context of the SQL Server programming model. Two aspects of the SQL Server programming model drove the definition of these categories: reliability and scalability. Recall from Chapter 11 that the basis of the CLR’s reliability design in .NET Framework 2.0 is the ability to shut down an application domain without leaking any resources, so one of the host protection categories (MayLeakOnAbort) is used to annotate code that cannot be guaranteed to free all resources when an application domain is unloaded. In addition, many of the host protection categories are aimed at preventing an add-in from inadvertently limiting the scalability of the host process. The SQL Server scheduler is highly tuned toward providing the highest degree of scalability possible. Any attempts by an add-in to block synchronizing access to shared state, or to affect how threads behave in the process, can limit the ability of SQL Server to scale. SQL Server add-ins such as user-defined types and stored procedures that are written in native code (using the T-SQL programming language) don’t have the ability to perform operations that limit scalability in this way. Many of the host protection categories are designed to ensure that SQL Server add-ins written in managed code don’t have those capabilities either.

The next several sections describe the individual host protection categories in detail. For each category, I describe the motivation for the category and the characteristics of the .NET Framework APIs that belong to that category. Each section also includes a full list of the .NET Framework APIs that belong to the particular category.

Synchronization

The synchronization host protection category includes APIs that allow an add-in to synchronize access to a particular resource explicitly across multiple threads. For example, many of the collection classes in the System.Collections namespace have a method called Synchronized that returns an instance of the collection to which only one thread can have access at a time. In addition, the System.Threading namespace includes several types that can be used to create and hold various types of operating system locks such as mutexes and semaphores. Synchronizing access to a resource means that at least one thread must wait if multiple threads are trying to access the resource simultaneously. Waiting on a resource limits scalability and should be avoided when possible in scenarios requiring high throughput. Hosts can block access to the APIs in the synchronization category to prevent an add-in from limiting scalability by waiting for access to a resource. In addition, synchronization can also hurt both scalability and reliability by causing the host to terminate an entire application domain instead of just an individual thread. Chapter 11 discusses how a host can specify policy that will cause the CLR to unload an entire application domain when a thread that is holding a lock receives a ThreadAbortException, for example.

The set of .NET Framework APIs that belongs to the synchronization host protection category is listed in Table 12-1.

Table 12-1. Properties and Methods with the Synchronization HostProtectionAttribute

Type

Property or Method

System.Collections.ArrayList

Synchronized

System.Collections.Generic.SortedDictionary<K, V>

SyncRoot { get }

System.Collections.Generic.Stack<T>

SyncRoot { get }

System.Collections.Hashtable

Synchronized

System.Collections.Queue

Synchronized

System.Collections.SortedList

Synchronized

System.Collections.Stack

Synchronized

System.IO.TextReader

Synchronized

System.IO.TextWriter

Synchronized

System.Threading.AutoResetEvent

All methods and properties

System.Threading.EventWaitHandle

All methods and properties

System.Threading.Interlocked

All methods and properties

System.Threading.ManualResetEvent

All methods and properties

System.Threading.Monitor

All methods and properties

System.Threading.Mutex

All methods and properties

System.Threading.ReaderWriterLock

All methods and properties

System.Threading.Semaphore

All methods and properties

System.Threading.Thread

Start

Join

SpinWait

ApartmentState { set }

TrySetApartmentState { set }

SetApartmentState

BeginCriticalRegion

EndCriticalRegion

System.Threading.ThreadPool

All methods and properties

System.Threading.Timer

All methods and properties

System.ComponentModel.AttributeCollection

All methods and properties

System.ComponentModel.ComponentCollection

All methods and properties

System.ComponentModel.EventDescriptorCollection

All methods and properties

System.ComponentModel.ISynchronizeInvoke

BeginInvoke

System.ComponentModel.PropertyDescriptorCollection

All methods and properties

System.Diagnostics.TraceListener

All properties and methods

System.Data.TypedDataSetGenerator

All properties and methods

System.Xml.XmlDataDocument

All properties and methods

System.Diagnostics.Process

All properties and methods

System.Text.RegularExpressions.Group

Synchronized

System.Text.RegularExpressions.Match

Synchronized

System.Diagnostics.EventLog

SynchronizingObject

System.Diagnostics.PerformanceCounter

All properties and methods

System.Diagnostics.PerformanceCounterCategory

All properties and methods

System.Timers.Timer

All properties and methods

Shared State

The sharing of state between threads is related to synchronization in that access to the shared state must be synchronized for that state to remain consistent, so the shared state host protection category exists for many of the same reasons that the synchronization category does. The most obvious example of an API that allows you to share state between threads is the AllocDataSlot (and related) APIs on System.Threading.Thread. These APIs essentially provide a managed-code view of the thread local store feature of Win32.

The complete set of APIs in the shared state category is listed in Table 12-2.

Table 12-2. Properties and Methods with the SharedState HostProtectionAttribute

Type

Property or Method

System.Threading.Thread

AllocateDataSlot

AllocateNamedDataSlot

FreeNamedDataSlot

GetData

SetData

System.Diagnostics.Debug

Listeners { get }

System.Diagnostics.Trace

Listeners { get }

System.Data.TypedDataSetGenerator

All properties and methods

System.Diagnostics.Process

All properties and methods

System.Diagnostics.ProcessStartInfo

All properties and methods

System.Diagnostics.PerformanceCounter

All properties and methods

System.Diagnostics.PerformanceCounterCategory

All properties and methods

External Process Management

The external process management category contains APIs that add-ins can use to manipulate processes other than the host process itself. The APIs in this category can’t affect the integrity or the reliability of the host process specifically, but they can have an indirect effect through the ability to create and manipulate other processes on the system. For example, SQL Server runs best when it is one of just a few processes on a system and it can therefore take advantage of the majority of the system’s resources, including memory. The presence of many other processes competing for the same resources can adversely affect SQL Server performance. The Process class in the System.Diagnostics namespace is a great example of a class that can be used to affect other processes. Process has methods that allow an add-in to create and kill processes, interact with processes through the standard input and output streams, and so on.

Table 12-3 lists the types in the external process management category.

Table 12-3. Properties and Methods with the ExternalProcessMgmt HostProtectionAttribute

Type

Property or Method

System.ComponentModel.LicenseManager

All properties and methods

System.Diagnostics.Process

All properties and methods

Self-Affecting Process Management

Whereas the APIs in the external process management category cannot affect the host’s process directly, the APIs in the self-affecting process management category can, so the APIs in this category can directly affect the stability of the host.

The APIs in the self-affecting process management category are all in the System.Diagnostics namespace and are all either on the Process class or its relatives. The self-affecting process APIs allow an add-in to affect characteristics of the host process, including its priority and the processor affinity of threads running in the process. The full list of self-affecting process APIs is given in Table 12-4.

Table 12-4. Properties and Methods with the SelfAffectingProcessMgmt HostProtectionAttribute

Type

Property or Method

System.Diagnostics.Process

All properties and methods

System.Diagnostics.ProcessStartInfo

All properties and methods

System.Diagnostics.ProcessThread

All properties and methods

Self-Affecting Threading

Whereas the APIs in the self-affecting process management category can directly affect various aspects of the host’s process, the APIs in the self-affecting threading category can affect specific threads running within the host process. Examples of APIs in this category are those on System.Threading.Thread that allow a thread’s priority to be altered, its COM apartment state to be set, and so on.

As I mentioned in the beginning of this chapter, the line between which APIs are blocked using CAS and which are blocked using host protection can often be blurry. For example, the System.Threading.Thread.Abort method can clearly be used to affect the threads in a process, so you’d expect Abort to be annotated with HostProtectionAttribute, identifying it as belonging to the self-affecting threading category. It is not, however. Instead, to be called, Abort demands a CAS permission (SecurityPermission.ControlThread). In this particular case, Abort was not annotated with HostProtectionAttribute because it already has a CAS demand. There are many cases in which a method or type that was protected using CAS wasn’t annotated with HostProtectionAttribute even though it logically belonged to one of the host protection categories, so a host must use a combination of CAS, as described in Chapter 10, and host protection to ensure that no inappropriate APIs can be used in the process.

The list of APIs in the self-affecting threading category is given in Table 12-5.

Table 12-5. Properties and Methods with the SelfAffectingThreading HostProtectionAttribute

Type

Property or Method

System.Security.Principal.WindowsImpersonationContext

All properties and methods

System.Threading.Thread

Priority { set }

IsBackground { set }

ApartmentState { set }

TrySetApartmentState { set }

SetApartmentState

External Threading

The external threading category contains those APIs that can affect threads in the host process but cannot directly impact the host’s stability. In most cases, the external threading APIs are those that allow an add-in to start an asynchronous operation such as reading from a network socket or a file.

Many of the types in the System.Threading namespace are also included in the external threading category, as shown in Table 12-6.

Table 12-6. Properties and Methods with the ExternalThreading HostProtectionAttribute

Type

Property or Method

System.ICancelableAsyncResult

Cancel

System.IO.FileStream

BeginRead

BeginWrite

System.IO.Stream

BeginRead

BeginWrite

System.Threading.AutoResetEvent

All methods and properties

System.Threading.CancellationRegion

SetNonCancelable

SetCancelable

System.Threading.CancellationSignal

CancelSynchronousIO

System.Threading.EventWaitHandle

All methods and properties

System.Threading.Interlocked

All methods and properties

System.Threading.ManualResetEvent

All methods and properties

System.Threading.Monitor

All methods and properties

System.Threading.Mutex

All methods and properties

System.Threading.ReaderWriterLock

All methods and properties

System.Threading.Semaphore

All methods and properties

System.Threading.Thread

Start

Join

SpinWait

AllocateDataSlot

AllocateNamedDataSlot

FreeNamedDataSlot

GetData

SetData

CurrentUICulture { set }

Name { set }

BeginCriticalRegion

EndCriticalRegion

System.Threading.ThreadPool

All methods and properties

System.Threading.Timer

All methods and properties

System.ComponentModel.ISynchronizeInvoke

BeginInvoke

System.Data.ProviderBase.DbConnectionInternal

BeginOpen

System.Data.SqlClient.SqlCommand

BeginExecuteNonQuery

BeginExecuteXmlReader

BeginExecuteReader

System.Data.SqlClient.SqlConnection

BeginOpen

System.Data.SqlClient.SqlDependency

All constructors

System.Net.Authenticator

BeginAuthenticate

BeginAcceptAuthRequest

System.Net.Dns

BeginGetHostByName

BeginResolveToAddresses

BeginResolve

System.Net.FileWebRequest

BeginGetRequestStream

BeginGetResponse

System.Net.FtpWebRequest

BeginGetRequestStream

BeginGetResponse

System.Net.HttpListener

BeginGetContext

System.Net.HttpWebRequest

BeginGetRequestStream

BeginGetResponse

System.Net.IPAddress

BeginResolveToAddresses

System.Net.Mail.SmtpClient

SendAsync

System.Net.NetworkInformation.Ping

SendAsync

System.Net.Security.NegotiateStream

BeginClientAuthenticate

BeginServerAuthenticate

BeginRead

BeginWrite

System.Net.Security.SslStream

BeginClientAuthenticate

BeginServerAuthenticate

BeginRead

BeginWrite

System.Net.Sockets.NetworkStream

BeginRead

BeginWrite

System.Net.Sockets.Socket

BeginSendFile

BeginConnect

BeginDisconnect

BeginSend

BeginSendTo

BeginReceive

BeginReceiveFrom

BeginAccept

System.Net.Sockets.TcpClient

BeginConnect

System.Net.Sockets.TcpListener

BeginAcceptSocket

BeginAcceptTcpClient

System.Net.Sockets.UdpClient

BeginSend

BeginReceive

System.Net.WebClient

OpenReadAsync

OpenWriteAsync

DownloadStringAsync

DownloadDataAsync

DownloadFileAsync

UploadStringAsync

UploadDataAsync

UploadFileAsync

UploadValuesAsync

System.Net.WebRequest

BeginGetResponse

BeginGetRequestStream

Security Infrastructure

There are only two types in the security infrastructure host protection category, as shown in Table 12-7. These types allow an add-in to manipulate different aspects of the underlying Windows security system, including how impersonation is done and how security principals are managed.

Table 12-7. Properties and Methods with the SecurityInfrastructure HostProtectionAttribute

Type

Property or Method

System.Security.Principal. WindowsImpersonationContext

All properties and methods

System.Security.Principal.WindowsPrincipal

All properties and methods

User Interface

The number of types and methods in the user interface category is surprisingly small given the breadth of UI-related class libraries in the .NET Framework. There are two reasons for this. First, many of the types that allow the display of user interface are already protected by CAS permissions. In many cases, those types have not been annotated with HostProtectionAttribute as well. Also, recall that only the .NET Framework assemblies that SQL Server 2005 allows in its process have been annotated with the HostProtectionAttribute. This automatically eliminates System. Windows.Forms, one of the primary class libraries for building applications with user interfaces. As it stands in .NET Framework 2.0, only the user interface–related classes in the System.Console class are included in the user interface host protection category, as shown in Table 12-8.

Table 12-8. Properties and Methods with the UI HostProtectionAttribute

Type

Property or Method

System.Console

Error { get }

In { get }

Out { get }

Beep

ReadKey

KeyAvailable { get }

OpenStandardError

OpenStandardInput

OpenStandardOutput

SetIn

SetOut

SetError

Read

ReadLine

WriteLine

Write

"May Leak on Abort"

As discussed in Chapter 11, the ability to unload an application domain without leaking any resources is a core concept in the CLR’s design to provide a system that can execute predictably in scenarios requiring high availability. The "may leak on abort" host protection category is used to identify those types and methods that are not guaranteed to be leakproof when an application domain is unloaded. A type or method can leak resources if it doesn’t adhere to the guidelines for writing reliable managed code that were outlined in Chapter 11. For example, if a type maintains a handle to an operating system resource without wrapping it using the SafeHandle class, the CLR cannot guarantee that the handle will not be leaked in all abort and shutdown scenarios. Hosts should be aware that they must block the "may leak on abort" host protection category if they require a highly available system.

The list of methods and types that can leak resources on abort or shutdown is given in Table 12-9.

Table 12-9. Properties and Methods with the MayLeakOnAbort HostProtectionAttribute

Type

Property or Method

System.Reflection.Assembly

Load(byte[] rawAssembly,...)

LoadFile

LoadModule

System.Reflection.Emit.AssemblyBuilder

All properties and methods

System.Reflection.Emit.ConstructorBuilder

All properties and methods

System.Reflection.Emit.CustomAttributeBuilder

All properties and methods

System.Reflection.Emit.EnumBuilder

All properties and methods

System.Reflection.Emit.EventBuilder

All properties and methods

System.Reflection.Emit.FieldBuilder

All properties and methods

System.Reflection.Emit.MethodBuilder

All properties and methods

System.Reflection.Emit.MethodRental

All properties and methods

System.Reflection.Emit.ModuleBuilder

All properties and methods

System.Reflection.Emit.PropertyBuilder

All properties and methods

System.Reflection.Emit.TypeBuilder

All properties and methods

System.Reflection.Emit.UnmanagedMarshal

All properties and methods

Using the Host Protection Manager

CLR hosts specify which host protection categories they’d like to block using the host protection manager from the CLR hosting interfaces. The host protection manager has just one interface, ICLRHostProtectionManager. As its name indicates (following the naming convention used throughout the hosting interfaces), ICLRHostProtectionManager is implemented by the CLR, not by the host. A host obtains an ICLRHostProtectionManager interface pointer from the CLR through the standard CLR control object described in Chapter 2. Given this pointer, a host then calls its SetProtectedCategories method to specify which host protection categories to block. Here’s the definition of ICLRHostProtectionManager from mscoree.idl:

interface ICLRHostProtectionManager : IUnknown
{
    HRESULT SetProtectedCategories([in] EApiCategories categories);
};

The host specifies which categories to block by performing an OR operation on values from the EApiCategories enumeration. EApiCategories is the unmanaged equivalent of the System.Security.Permissions.HostProtectionResource enumerations used to specify the host protection categories in managed code:

typedef enum
{
    eNoChecks                 = 0,
    eSynchronization          = 0x1,
    eSharedState              = 0x2,
    eExternalProcessMgmt      = 0x4,
    eSelfAffectingProcessMgmt = 0x8,
    eExternalThreading        = 0x10,
    eSelfAffectingThreading   = 0x20,
    eSecurityInfrastructure   = 0x40,
    eUI                       = 0x80,
    eMayLeakOnAbort           = 0x100,
    eAll                      = 0x1ff
} EApiCategories;

As you can see, enabling host protection is relatively straightforward. The real challenge with this feature is not in writing the code required to enable it, but rather in the analysis to determine which host protection categories should be blocked in your particular scenario.

Now that I’ve covered the details of the host protection features, let’s enable it in one of our existing example hosts.

Host Protection in the Cocoon Deployment Model

In Chapter 8, I wrote a CLR host called runcocoon.exe that executes applications contained in OLE-structured storage files called cocoons. In this section, I extend runcocoon.exe to use host protection to prevent the assemblies contained in cocoon files from using any of the .NET Framework APIs that are annotated with HostProtectionAttribute. Remember that only partially trusted assemblies are prevented from accessing members blocked by host protection, so the extensions I made to runcocoon.exe in Chapter 10 apply here as well. In that chapter, I used an application domain CAS policy tree to assign a partial level of trust to all assemblies loaded from a cocoon. Because those assemblies are only partially trusted, they’re subject to the host protection settings I’ll add to runcocoon.exe in this section. I won’t list the entire source for the runcocoon.exe host again here. Instead, I’ll just provide those portions of the implementation that are specific to host protection. A complete source code listing can be found on this book’s companion Web site.

Enabling host protection in runcocoon.exe requires two steps:

  1. Obtaining the ICLRHostProtectionManager interface from the CLR

  2. Using SetProtectedCategories to specify which categories to block

These two steps are described in more detail in the next sections.

Step 1: Obtaining the ICLRHostProtectionManager Interface Pointer

As described in Chapter 2, all of the primary hosting interfaces implemented by the CLR are obtained using the GetCLRManager method on ICLRControl. The following code snippet initializes the CLR with CorBindToRuntimeEx, and then uses ICLRControl::GetCLRManager to get the CLR’s implementation of ICLRHostProtectionManager:

int wmain(int argc, wchar_t* argv[])
{
   HRESULT hr = S_OK;

// Start the .NET Framework 2.0 version of the CLR
   ICLRRuntimeHost *pCLR = NULL;
   hr = CorBindToRuntimeEx(
      L"v2.0.41013",
      L"wks",
      STARTUP_CONCURRENT_GC,
      CLSID_CLRRuntimeHost,
      IID_ICLRRuntimeHost,
      (PVOID*) &pCLR);
   assert(SUCCEEDED(hr));

   // Get the CLRControl object.
   ICLRControl *pCLRControl = NULL;
   hr = pCLR->GetCLRControl(&pCLRControl);
   assert(SUCCEEDED(hr));

   // Ask the CLR for its implementation of ICLRHostProtectionManager.
   ICLRHostProtectionManager *pCLRHostProtectionManager = NULL;
   hr = pCLRControl->GetCLRManager(IID_ICLRHostProtectionManager,
(void **)&pCLRHostProtectionManager);
   assert(SUCCEEDED(hr));

   // Rest of the host's code omitted... }

Step 2: Specifying Which Host Protection Categories to Block

Now that I have a pointer of type ICLRHostProtectionManager, I simply need to call its SetProtectedCategories method to specify which categories I’d like to block. The following call to SetProtectedCategories blocks the full set of host protection categories:

// Block all host protection categories.
hr = pCLRHostProtectionManager->SetProtectedCategories (
            (EApiCategories)(
               eSelfAffectingProcessMgmt |
               eSelfAffectingThreading |
               eSynchronization |
               eSharedState |
               eExternalProcessMgmt |
               eExternalThreading |
               eSelfAffectingProcessMgmt |
               eSelfAffectingThreading |
               eSecurityInfrastructure |
               eMayLeakOnAbort |
               eUI));
   assert(SUCCEEDED(hr));

Now that I’ve enabled host protection, all attempts by cocoon assemblies to access protected APIs will result in an exception of type System.Security.HostProtectionException. The HostProtectionException has fields that describe which categories the host has blocked and which category contains the method that caused the exception to be thrown. For example, the following exception text resulted from a cocoon assembly attempting to call Console.WriteLine, which belongs to the UI host protection category:

System.Security.HostProtectionException: Attempted to perform an operation that was
   forbidden by the CLR host.
The protected resources (only available with full trust) were:
All
The demanded resources were: UI

Note

Note

Just as host protection and CAS appear similar on the surface, their implementations are very similar as well. The fact that HostProtectionAttribute is in the System.Security.Permissions namespace and that HostProtectionException is in System.Security gives a clear hint that their underlying implementations are very similar to CAS. In fact, both host protection and demands for CAS permissions are implemented using the same infrastructure within the CLR. When a host enables host protection using ICLRHostProtectionManager, the CLR introduces a link demand for a permission of type System.Security.Permissions.HostProtectionPermission into the code that is jit-compiled for each protected method. The failure of this link demand is what causes the HostProtectionException to be thrown.

Summary

Host protection enables a host to prevent partially trusted add-ins from using APIs that don’t fit well with the host’s programming model. Although on the surface the goals of host protection seem very much like those of CAS, the two features have different motivations. CAS is a mechanism used to protect a resource from unauthorized access, whereas host protection is aimed at constraining an add-in to adhere to a host’s programming model.

Host protection consists of a set of categories that define capabilities deemed of interest to hosts, a custom attribute for grouping APIs into those categories, and a hosting interface that hosts use to specify which categories of functionality don’t fit their programming model. The .NET Framework class libraries have been annotated with the custom attribute (the HostProtectionAttribute) to indicate which types and methods belong to which host protection categories. After determining which categories apply to its scenario, a host uses the ICLRHostProtectionManager interface to prevent the APIs belonging to those categories from being used in the process.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.233.43