summaryrefslogtreecommitdiff
path: root/src/vm/securitydeclarative.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/securitydeclarative.cpp')
-rw-r--r--src/vm/securitydeclarative.cpp889
1 files changed, 2 insertions, 887 deletions
diff --git a/src/vm/securitydeclarative.cpp b/src/vm/securitydeclarative.cpp
index e0aff16ddd..5771138b7d 100644
--- a/src/vm/securitydeclarative.cpp
+++ b/src/vm/securitydeclarative.cpp
@@ -12,9 +12,6 @@
#include "securitydeclarative.inl"
#include "eventtrace.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif // FEATURE_REMOTING
//-----------------------------------------------------------------------------
@@ -198,19 +195,11 @@ void SecurityDeclarative::AddDeclAction(CorDeclSecurity action, PsetCacheEntry *
break;
case DS_UNION:
-#ifdef FEATURE_CAS_POLICY
- LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, false, action), pMeth);
-#else // FEATURE_CAS_POLICY
_ASSERTE(!"Declarative permission sets may not be unioned together in CoreCLR. Are you attempting to have a declarative demand or deny on both a method and its enclosing class?");
-#endif // FEATURE_CAS_POLICY
break;
case DS_INTERSECT:
-#ifdef FEATURE_CAS_POLICY
- LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, true, action), pMeth);
-#else // FEATURE_CAS_POLICY
_ASSERTE(!"Declarative permission sets may not be intersected in CoreCLR. Are you attempting to have a declarative permit only on both a method and its enclosing class?");
-#endif // FEATURE_CAS_POLICY
break;
case DS_APPLY_METHOD_THEN_CLASS:
@@ -269,14 +258,7 @@ DeclActionInfo* SecurityDeclarative::DetectDeclActions(MethodDesc *pMeth, DWORD
if (pClass->HasSuppressUnmanagedCodeAccessAttr())
{
-#ifdef FEATURE_CORECLR
hr = S_OK;
-#else
- hr = pInternalImport->GetCustomAttributeByName(pMT->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL);
-#endif // FEATURE_CORECLR
if (hr != S_OK)
{
g_IBCLogger.LogEEClassCOWTableAccess(pMT);
@@ -536,15 +518,7 @@ HRESULT SecurityDeclarative::GetDeclarationFlags(IMDInternalImport *pInternalImp
BOOL hasSuppressUnmanagedCodeAccessAttr;
if (pfHasSuppressUnmanagedCodeAccessAttr == NULL)
{
-#ifdef FEATURE_CORECLR
hasSuppressUnmanagedCodeAccessAttr = TRUE;
-#else
- hasSuppressUnmanagedCodeAccessAttr =
- (pInternalImport->GetCustomAttributeByName(token,
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK);
-#endif
}
else
hasSuppressUnmanagedCodeAccessAttr = *pfHasSuppressUnmanagedCodeAccessAttr;
@@ -605,175 +579,10 @@ void SecurityDeclarative::MethodInheritanceCheck(MethodDesc *pMethod, MethodDesc
//
//-----------------------------------------------------------------------------
-#ifdef FEATURE_APTCA
-void DECLSPEC_NORETURN SecurityDeclarative::ThrowAPTCAException(Assembly *pCaller, MethodDesc *pCallee)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- MethodDescCallSite throwSecurityException(METHOD__SECURITY_ENGINE__THROW_SECURITY_EXCEPTION);
-
- OBJECTREF callerObj = NULL;
- if (pCaller != NULL && pCaller->GetDomain() == GetAppDomain())
- callerObj = pCaller->GetExposedObject();
-
- ARG_SLOT args[7];
- args[0] = ObjToArgSlot(callerObj);
- args[1] = ObjToArgSlot(NULL);
- args[2] = ObjToArgSlot(NULL);
- args[3] = PtrToArgSlot(pCallee);
- args[4] = (ARG_SLOT)dclLinktimeCheck;
- args[5] = ObjToArgSlot(NULL);
- args[6] = ObjToArgSlot(NULL);
- throwSecurityException.Call(args);
-
- UNREACHABLE();
-}
-#endif // FEATURE_APTCA
-
-#ifdef FEATURE_CAS_POLICY
-void DECLSPEC_NORETURN SecurityDeclarative::ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF hpException = NULL;
- GCPROTECT_BEGIN(hpException);
-
- MethodTable* pMT = MscorlibBinder::GetClass(CLASS__HOST_PROTECTION_EXCEPTION);
- hpException = (OBJECTREF) AllocateObject(pMT);
-
-
- MethodDescCallSite ctor(METHOD__HOST_PROTECTION_EXCEPTION__CTOR);
-
- ARG_SLOT arg[3] = {
- ObjToArgSlot(hpException),
- protectedCategories,
- demandedCategories
- };
- ctor.Call(arg);
-
- COMPlusThrow(hpException);
-
- GCPROTECT_END();
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-BOOL SecurityDeclarative::IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- Assembly *pCalleeAssembly = pCalleeMD->GetAssembly();
- _ASSERTE(pCalleeAssembly != NULL);
-
- // ATPCA is only enforced for cross-assembly calls, so if the target is not accessable from outside
- // the assembly, or if the caller and callee are both within the same assembly, we do not need to
- // do any APTCA checks
- if (pCallerAssem == pCalleeAssembly)
- {
- return FALSE;
- }
-
- if (!MethodIsVisibleOutsideItsAssembly(pCalleeMD))
- {
- return FALSE;
- }
-
- // If the target assembly allows untrusted callers unconditionally, then the call should be allowed
- if (pCalleeAssembly->AllowUntrustedCaller())
- {
- return FALSE;
- }
-
- // Otherwise, we need to ensure the caller is fully trusted
- return TRUE;
-}
-#endif // FEATURE_APTCA
-
-#ifdef FEATURE_APTCA
-// Do a fulltrust check on the caller if the callee is fully trusted and
-// callee did not enable AllowUntrustedCallerChecks
-/*static*/
-void SecurityDeclarative::DoUntrustedCallerChecks(
- Assembly *pCaller, MethodDesc *pCallee,
- BOOL fFullStackWalk)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
- BOOL fRet = TRUE;
-#ifdef _DEBUG
- if (!g_pConfig->Do_AllowUntrustedCaller_Checks())
- return;
-#endif
-
- if (!IsUntrustedCallerCheckNeeded(pCallee, pCaller))
- return;
-
- // Expensive calls after this point, this could end up resolving policy
-
- if (fFullStackWalk)
- {
- // It is possible that wrappers like VBHelper libraries that are
- // fully trusted, make calls to public methods that do not have
- // safe for Untrusted caller custom attribute set.
- // Like all other link demand that gets transformed to a full stack
- // walk for reflection, calls to public methods also gets
- // converted to full stack walk
-
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
-
- GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- EX_TRY
- {
- SecurityStackWalk::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- }
- EX_CATCH
- {
- fRet = FALSE;
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- GCPROTECT_END();
- }
- else
- {
- _ASSERTE(pCaller);
-
- // Link Demand only, no full stack walk here
- if (!pCaller->GetSecurityDescriptor()->IsFullyTrusted())
- fRet = FALSE;
- }
-
- if (!fRet)
- {
- ThrowAPTCAException(pCaller, pCallee);
- }
-}
-#endif // FEATURE_APTCA
// Retrieve all linktime demands sets for a method. This includes both CAS and
// non-CAS sets for LDs at the class and the method level, so we could get up to
@@ -791,17 +600,6 @@ void SecurityDeclarative::RetrieveLinktimeDemands(MethodDesc *pMD,
INJECT_FAULT(COMPlusThrowOM(););
} CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- MethodTable * pMT = pMD->GetMethodTable();
-
- // Class level first.
- if (pMT->GetClass()->RequiresLinktimeCheck())
- *pClassCas = TypeSecurityDescriptor::GetLinktimePermissions(pMT, pClassNonCas);
-
- // Then the method level.
- if (IsMdHasSecurity(pMD->GetAttrs()))
- *pMethodCas = MethodSecurityDescriptor::GetLinktimePermissions(pMD, pMethodNonCas);
-#endif
}
//
@@ -841,7 +639,7 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD,
LinktimeCheckReason reason = LinktimeCheckReason_None;
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
// If the method does not allow partially trusted callers, then the check is because we need to ensure all
@@ -850,7 +648,7 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD,
{
reason |= LinktimeCheckReason_AptcaCheck;
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
//
// If the method has a LinkDemand on it for either CAS or non-CAS permissions, get those and set the
@@ -952,688 +750,5 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD,
return reason;
}
-#ifdef FEATURE_CAS_POLICY
-// Issue an inheritance demand against the target assembly
-
-// static
-void SecurityDeclarative::InheritanceDemand(Assembly *pTargetAssembly, OBJECTREF refDemand)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pTargetAssembly));
- PRECONDITION(refDemand != NULL);
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF refDemand;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
- gc.refDemand = refDemand;
-
- GCPROTECT_BEGIN(gc);
-
- IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor();
- SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD,
- gc.refDemand,
- pTargetAssembly,
- dclInheritanceCheck);
- GCPROTECT_END();
-}
-
-// static
-void SecurityDeclarative::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pTargetAssembly));
- PRECONDITION(CheckPointer(pMDLinkDemand));
- }
- CONTRACTL_END;
-
- GCX_COOP();
- struct
- {
- OBJECTREF refClassCas;
- OBJECTREF refClassNonCas;
- OBJECTREF refMethodCas;
- OBJECTREF refMethodNonCas;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- Security::RetrieveLinktimeDemands(pMDLinkDemand,
- &gc.refClassCas,
- &gc.refClassNonCas,
- &gc.refMethodCas,
- &gc.refMethodNonCas);
-
- if (gc.refClassCas != NULL)
- {
- InheritanceDemand(pTargetAssembly, gc.refClassCas);
- }
-
- if (gc.refMethodCas != NULL)
- {
- InheritanceDemand(pTargetAssembly, gc.refMethodCas);
- }
-
- GCPROTECT_END();
-}
-
-// Issue a FullTrust inheritance demand against the target assembly
-
-// static
-void SecurityDeclarative::FullTrustInheritanceDemand(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- struct
- {
- OBJECTREF refFullTrust;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refFullTrust = Security::CreatePermissionSet(TRUE);
- InheritanceDemand(pTargetAssembly, gc.refFullTrust);
-
- GCPROTECT_END();
-}
-
-// Issue a FullTrust link demand against the target assembly
-
-// static
-void SecurityDeclarative::FullTrustLinkDemand(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF refFullTrust;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refFullTrust = Security::CreatePermissionSet(TRUE);
- IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor();
- SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD,
- gc.refFullTrust,
- pTargetAssembly,
- dclLinktimeCheck);
- GCPROTECT_END();
-}
-
-// Used by interop to simulate the effect of link demands when the caller is
-// in fact script constrained by an appdomain setup by IE.
-void SecurityDeclarative::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- if (!pMD->RequiresLinktimeCheck())
- return;
-
- // Find the outermost (closest to caller) appdomain. This
- // represents the domain in which the unmanaged caller is
- // considered to "live" (or, at least, be constrained by).
- AppDomain *pDomain = GetThread()->GetInitialDomain();
-
- // The link check is only performed if this app domain has
- // security permissions associated with it, which will be
- // the case for all IE scripting callers that have got this
- // far because we automatically reported our managed classes
- // as "safe for scripting".
- //
- // We also can't do the check if the AppDomain isn't fully
- // setup yet, since we might not have a domain grant set.
- // This is acceptable, since the only code that should run
- // during AppDomain creation is fully trusted.
- IApplicationSecurityDescriptor *pSecDesc = pDomain->GetSecurityDescriptor();
- if (pSecDesc == NULL || pSecDesc->IsInitializationInProgress() || pSecDesc->IsDefaultAppDomain())
- return;
-
- struct _gc
- {
- OBJECTREF refGrant;
- OBJECTREF refRefused;
- OBJECTREF refClassNonCasDemands;
- OBJECTREF refClassCasDemands;
- OBJECTREF refMethodNonCasDemands;
- OBJECTREF refMethodCasDemands;
- OBJECTREF refAssembly;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
-#ifdef FEATURE_APTCA
- // Do a fulltrust check on the caller if the callee did not enable
- // AllowUntrustedCallerChecks. Pass a NULL caller assembly:
- // DoUntrustedCallerChecks needs to be able to cope with this.
- SecurityDeclarative::DoUntrustedCallerChecks(NULL, pMD, TRUE);
-#endif // FEATURE_APTCA
-
- // Fetch link demand sets from all the places in metadata where we might
- // find them (class and method). These might be split into CAS and non-CAS
- // sets as well.
- SecurityDeclarative::RetrieveLinktimeDemands(pMD,
- &gc.refClassCasDemands,
- &gc.refClassNonCasDemands,
- &gc.refMethodCasDemands,
- &gc.refMethodNonCasDemands);
-
- // Check CAS link demands.
- bool fGotGrantSet = false;
- if (gc.refClassCasDemands != NULL || gc.refMethodCasDemands != NULL)
- {
- // Get grant (and possibly denied) sets from the app
- // domain.
- gc.refGrant = pSecDesc->GetGrantedPermissionSet(NULL);
- fGotGrantSet = true;
- gc.refAssembly = pMD->GetAssembly()->GetExposedObject();
-
- if (gc.refClassCasDemands != NULL)
- SecurityStackWalk::CheckSetHelper(&gc.refClassCasDemands,
- &gc.refGrant,
- &gc.refRefused,
- pDomain,
- pMD,
- &gc.refAssembly,
- dclLinktimeCheck);
-
- if (gc.refMethodCasDemands != NULL)
- SecurityStackWalk::CheckSetHelper(&gc.refMethodCasDemands,
- &gc.refGrant,
- &gc.refRefused,
- pDomain,
- pMD,
- &gc.refAssembly,
- dclLinktimeCheck);
-
- }
-
- // Non-CAS demands are not applied against a grant
- // set, they're standalone.
- if (gc.refClassNonCasDemands != NULL)
- CheckNonCasDemand(&gc.refClassNonCasDemands);
-
- if (gc.refMethodNonCasDemands != NULL)
- CheckNonCasDemand(&gc.refMethodNonCasDemands);
-
-#ifndef FEATURE_CORECLR
- // On CORECLR, we do this from the JIT callouts if the caller is transparent: if caller is critical, no checks needed
-
- // We perform automatic linktime checks for UnmanagedCode in three cases:
- // o P/Invoke calls (shouldn't get these here, but let's be paranoid).
- // o Calls through an interface that have a suppress runtime check
- // attribute on them (these are almost certainly interop calls).
- // o Interop calls made through method impls.
- // Just walk the stack in these cases, they'll be extremely rare and the
- // perf delta isn't that huge.
- if (pMD->IsNDirect() ||
- (pMD->IsInterface() &&
- (pMD->GetMDImport()->GetCustomAttributeByName(pMD->GetMethodTable()->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMD->GetMDImport()->GetCustomAttributeByName(pMD->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK) ) ||
- (pMD->IsComPlusCall() && !pMD->IsInterface()))
- SecurityStackWalk::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
-#endif // FEATURE_CORECLR
-
- GCPROTECT_END();
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//-----------------------------------------------------------------------------
-//
-//
-// CODE FOR PERFORMING RUN-TIME CHECKS
-//
-//
-//-----------------------------------------------------------------------------
-
-void SecurityDeclarative::EnsureAssertAllowed(MethodDesc *pMeth, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(CheckPointer(pMeth));
- PRECONDITION(pMSD == NULL || pMSD->GetMethod() == pMeth);
- } CONTRACTL_END;
-
- // Check if this Assembly has permission to assert
- if (pMSD == NULL || !pMSD->CanAssert()) // early out if we have an MSD and we already have checked this permission
- {
- Module* pModule = pMeth->GetModule();
- PREFIX_ASSUME_MSG(pModule != NULL, "Should be a Module pointer here");
-
- if (!Security::CanAssert(pModule))
- SecurityPolicy::ThrowSecurityException(g_SecurityPermissionClassName, SPFLAGSASSERTION);
- }
-
- // Check if the Method is allowed to assert based on transparent/critical classification
- if (!SecurityTransparent::IsAllowedToAssert(pMeth) && Security::IsTransparencyEnforcementEnabled())
- {
-#ifdef _DEBUG
- if (g_pConfig->LogTransparencyErrors())
- {
- SecurityTransparent::LogTransparencyError(pMeth, "Transparent method using a security assert");
- }
-#endif // _DEBUG
- // if assembly is transparent fail the ASSERT operations
- COMPlusThrow(kInvalidOperationException, W("InvalidOperation_AssertTransparentCode"));
- }
-
- return;
-}
-
-void SecurityDeclarative::InvokeDeclarativeActions (MethodDesc *pMeth, DeclActionInfo *pActions, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF refPermSet = NULL;
- ARG_SLOT arg = 0;
-
- // If we get a real PermissionSet, then invoke the action.
- switch (pActions->dwDeclAction)
- {
- case DECLSEC_DEMANDS:
- SecurityStackWalk::DemandSet(SSWT_DECLARATIVE_DEMAND, pActions->pPCE, dclDemand);
- break;
-
- case DECLSEC_ASSERTIONS:
- EnsureAssertAllowed(pMeth, pMSD);
- GetThread()->IncrementAssertCount();
- break;
-
- case DECLSEC_DENIALS:
- case DECLSEC_PERMITONLY:
- GetThread()->IncrementOverridesCount();
- break;
-
- case DECLSEC_NONCAS_DEMANDS:
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclNonCasDemand);
- if (refPermSet == NULL)
- break;
- if(!((PERMISSIONSETREF)refPermSet)->CheckedForNonCas() ||((PERMISSIONSETREF)refPermSet)->ContainsNonCas())
- {
- GCPROTECT_BEGIN(refPermSet);
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &refPermSet);
-
- arg = ObjToArgSlot(refPermSet);
- demand.Call(&arg);
- GCPROTECT_END();
- }
- break;
-
- default:
- _ASSERTE(!"Unknown action requested in InvokeDeclarativeActions");
- break;
-
- } // switch
-}
-
-
-//
-// CODE FOR PERFORMING RUN-TIME CHECKS
-//
-extern LPVOID GetSecurityObjectForFrameInternal(StackCrawlMark *stackMark, INT32 create, OBJECTREF *pRefSecDesc);
-
-namespace
-{
- inline void UpdateFrameSecurityObj(DWORD dwAction, OBJECTREF *refPermSet, OBJECTREF * pSecObj)
- {
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- GetSecurityObjectForFrameInternal(NULL, true, pSecObj);
-
- FRAMESECDESCREF fsdRef = (FRAMESECDESCREF)*pSecObj;
- switch (dwAction)
- {
- // currently we require declarative security to store the data in both the fields in the FSD
- case dclAssert:
- fsdRef->SetDeclarativeAssertions(*refPermSet);
- {
- PERMISSIONSETREF psRef = (PERMISSIONSETREF)*refPermSet;
- if (psRef != NULL && psRef->IsUnrestricted())
- fsdRef->SetAssertFT(TRUE);
- }
- break;
-
- case dclDeny:
- fsdRef->SetDeclarativeDenials(*refPermSet);
- break;
-
- case dclPermitOnly:
- fsdRef->SetDeclarativeRestrictions(*refPermSet);
- break;
-
- default:
- _ASSERTE(0 && "Unreached, add code to handle if reached here...");
- break;
- }
- }
-}
-
-void SecurityDeclarative::InvokeDeclarativeStackModifiers(MethodDesc * pMeth, DeclActionInfo * pActions, OBJECTREF * pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF refPermSet = NULL;
-
- // If we get a real PermissionSet, then invoke the action.
- switch (pActions->dwDeclAction)
- {
- case DECLSEC_DEMANDS:
- case DECLSEC_NONCAS_DEMANDS:
- // Nothing to do for demands
- break;
-
- case DECLSEC_ASSERTIONS:
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclAssert);
- if (refPermSet == NULL)
- break;
- GCPROTECT_BEGIN(refPermSet);
- // Now update the frame security object
- UpdateFrameSecurityObj(dclAssert, &refPermSet, pSecObj);
- GCPROTECT_END();
- break;
-
- case DECLSEC_DENIALS:
- // Update the frame security object
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclDeny);
-
- if (refPermSet == NULL)
- break;
-
- GCPROTECT_BEGIN(refPermSet);
-
-#ifdef FEATURE_CAS_POLICY
- // Deny is only valid if we're in legacy CAS mode
- IApplicationSecurityDescriptor *pSecDesc = GetAppDomain()->GetSecurityDescriptor();
- if (!pSecDesc->IsLegacyCasPolicyEnabled())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_CasDeny"));
- }
-#endif // FEATURE_CAS_POLICY
-
- UpdateFrameSecurityObj(dclDeny, &refPermSet, pSecObj);
-
- GCPROTECT_END();
- break;
-
- case DECLSEC_PERMITONLY:
- // Update the frame security object
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclPermitOnly);
-
- if (refPermSet == NULL)
- break;
- GCPROTECT_BEGIN(refPermSet);
- UpdateFrameSecurityObj(dclPermitOnly, &refPermSet, pSecObj);
- GCPROTECT_END();
- break;
-
-
- default:
- _ASSERTE(!"Unknown action requested in InvokeDeclarativeStackModifiers");
- break;
-
- } // switch
-}
-
-void SecurityDeclarative::DoDeclarativeActions(MethodDesc *pMeth, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
-#ifndef FEATURE_CAS_POLICY
- // In the CoreCLR, we don't support CAS actions outside mscorlib.
- // However, we do have to expose certain types in mscorlib due to compiler requirements
- // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can
- // insert a RequestMinimum for SkipVerification).
- // This means that code outside mscorlib could construct IL that has declarative security
- // in it. This is not a security issue - even if they try to create IL that asserts for
- // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop.
- // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc.
- // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib.
- if (!pMeth->GetModule()->IsSystem())
- {
- // Non-mscorlib code reached... exit
- return;
- }
-#endif //!FEATURE_CAS_POLICY
-
-
- // --------------------------------------------------------------------------- //
- // D E C L A R A T I V E S E C U R I T Y D E M A N D S //
- // --------------------------------------------------------------------------- //
- // The frame is now fully formed, arguments have been copied into place,
- // and synchronization monitors have been entered if necessary. At this
- // point, we are prepared for something to throw an exception, so we may
- // check for declarative security demands and execute them. We need a
- // well-formed frame and synchronization domain to accept security excep-
- // tions thrown by the SecurityManager. We MAY need argument values in
- // the frame so that the arguments may be finalized if security throws an
- // exception across them (unknown).
- if (pActions != NULL && pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND &&
- pActions->pNext == NULL)
- {
- /* We special-case the security check on single pinvoke/interop calls
- so we can avoid setting up the GCFrame */
-
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- return;
- }
- else
- {
-#ifdef FEATURE_COMPRESSEDSTACK
- // If this is an anonymously hosted dynamic method, there aren't any direct modifiers, but if it has a compressed stack that
- // might have modifiers, mark that there are modifiers so we make sure to do a stack walk
- if(SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pMeth))
- {
- // We don't know how many asserts or overrides might be in the compressed stack,
- // but we just need to increment the counters to ensure optimizations don't skip CS evaluation
- GetThread()->IncrementAssertCount();
- GetThread()->IncrementOverridesCount();
- }
-#endif // FEATURE_COMPRESSEDSTACK
-
- for (/**/; pActions; pActions = pActions->pNext)
- {
- if (pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND)
- {
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- }
- else
- {
- InvokeDeclarativeActions(pMeth, pActions, pMSD);
- }
- }
-
- }
-}
-void SecurityDeclarative::DoDeclarativeStackModifiers(MethodDesc *pMeth, AppDomain* pAppDomain, LPVOID pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
-#ifndef FEATURE_CAS_POLICY
- // In the CoreCLR, we don't support CAS actions outside mscorlib.
- // However, we do have to expose certain types in mscorlib due to compiler requirements
- // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can
- // insert a RequestMinimum for SkipVerification).
- // This means that code outside mscorlib could construct IL that has declarative security
- // in it. This is not a security issue - even if they try to create IL that asserts for
- // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop.
- // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc.
- // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib.
- if (!pMeth->GetModule()->IsSystem())
- {
- // Non-mscorlib code reached... exit
- return;
- }
-#endif //!FEATURE_CAS_POLICY
-
-
- AppDomain* pCurrentDomain = GetAppDomain();
-
- if (pCurrentDomain != pAppDomain)
- {
- ENTER_DOMAIN_PTR(pAppDomain, ADV_RUNNINGIN)
- {
- DoDeclarativeStackModifiersInternal(pMeth, pSecObj);
- }
- END_DOMAIN_TRANSITION;
- }
- else
- {
- DoDeclarativeStackModifiersInternal(pMeth, pSecObj);
- }
- }
-
-void SecurityDeclarative::DoDeclarativeStackModifiersInternal(MethodDesc *pMeth, LPVOID pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- Object** ppSecObject = (Object**) pSecObj;
- _ASSERTE(pMeth->IsInterceptedForDeclSecurity() && !pMeth->IsInterceptedForDeclSecurityCASDemandsOnly());
-
- MethodSecurityDescriptor MDSecDesc(pMeth);
- MethodSecurityDescriptor::LookupOrCreateMethodSecurityDescriptor(&MDSecDesc);
- DeclActionInfo* pActions = MDSecDesc.GetRuntimeDeclActionInfo();
-
- OBJECTREF fsdRef = ObjectToOBJECTREF(*ppSecObject);
- GCPROTECT_BEGIN(fsdRef);
-
- for (/**/; pActions; pActions = pActions->pNext)
- {
- InvokeDeclarativeStackModifiers(pMeth, pActions, &fsdRef);
- }
- // If we had just NON-CAS demands, we'd come here but not create an FSD.
- if (fsdRef != NULL)
- {
- ((FRAMESECDESCREF)(fsdRef))->SetDeclSecComputed(TRUE);
-
- if (*ppSecObject == NULL)
- {
- // we came in with a NULL FSD and the FSD got created here...so we need to copy it back
- // If we had come in with a non-NULL FSD, that would have been updated and this (shallow/pointer) copy
- // would not be necessary
- *ppSecObject = OBJECTREFToObject(fsdRef);
- }
-}
-
- GCPROTECT_END();
-}
-
-
-void SecurityDeclarative::CheckNonCasDemand(OBJECTREF *prefDemand)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(IsProtectedByGCFrame (prefDemand));
- } CONTRACTL_END;
-
- if(((PERMISSIONSETREF)*prefDemand)->CheckedForNonCas())
- {
- if(!((PERMISSIONSETREF)*prefDemand)->ContainsNonCas())
- return;
- }
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, prefDemand);
- ARG_SLOT arg = ObjToArgSlot(*prefDemand);
- demand.Call(&arg);
-}
-
-#endif // FEATURE_CAS_POLICY
#endif // CROSSGEN_COMPILE