diff options
Diffstat (limited to 'src/vm/newcompressedstack.cpp')
-rw-r--r-- | src/vm/newcompressedstack.cpp | 1074 |
1 files changed, 0 insertions, 1074 deletions
diff --git a/src/vm/newcompressedstack.cpp b/src/vm/newcompressedstack.cpp deleted file mode 100644 index 5957dc37f4..0000000000 --- a/src/vm/newcompressedstack.cpp +++ /dev/null @@ -1,1074 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// - - -// - -#include "common.h" -#ifdef FEATURE_COMPRESSEDSTACK - -#include "newcompressedstack.h" -#include "security.h" -#ifdef FEATURE_REMOTING -#include "appdomainhelper.h" -#endif -#include "securitystackwalk.h" -#include "appdomainstack.inl" -#include "appdomain.inl" - - -DomainCompressedStack::DomainCompressedStack(ADID domainID) -: m_DomainID(domainID), - m_ignoreAD(FALSE), - m_dwOverridesCount(0), - m_dwAssertCount(0), - m_Homogeneous(FALSE) -{ - WRAPPER_NO_CONTRACT; -} - -BOOL DomainCompressedStack::IsAssemblyPresent(ISharedSecurityDescriptor* ssd) -{ - CONTRACTL - { - MODE_ANY; - GC_NOTRIGGER; - NOTHROW; - }CONTRACTL_END; - - - // Only checks the first level and does not recurse into compressed stacks - void* pEntry = NULL; - - if (m_EntryList.GetCount() == 0) - return FALSE; - - // Quick check the last entry we added - common case - pEntry = m_EntryList.Get(m_EntryList.GetCount() - 1); - if (pEntry == (void *)SET_LOW_BIT(ssd)) - return TRUE; - - // Go thru the whole list now - is this optimal? - ArrayList::Iterator iter = m_EntryList.Iterate(); - - while (iter.Next()) - { - pEntry = iter.GetElement(); - if (pEntry == (void *)SET_LOW_BIT(ssd)) - return TRUE; - } - return FALSE; -} - -void DomainCompressedStack::AddEntry(void * ptr) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - IfFailThrow(m_EntryList.Append(ptr)); - -} -VOID FrameSecurityDescriptorCopyFrom(FRAMESECDESCREF newFsdRef, FRAMESECDESCREF fsd) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - SO_TOLERANT; - MODE_COOPERATIVE; - } - CONTRACTL_END; - newFsdRef->SetImperativeAssertions(fsd->GetImperativeAssertions()); - newFsdRef->SetImperativeDenials(fsd->GetImperativeDenials()); - newFsdRef->SetImperativeRestrictions(fsd->GetImperativeRestrictions()); - newFsdRef->SetDeclarativeAssertions(fsd->GetDeclarativeAssertions()); - newFsdRef->SetDeclarativeDenials(fsd->GetDeclarativeDenials()); - newFsdRef->SetDeclarativeRestrictions(fsd->GetDeclarativeRestrictions()); - newFsdRef->SetAssertAllPossible(fsd->HasAssertAllPossible()); - newFsdRef->SetAssertFT(fsd->HasAssertFT()); -} - -void DomainCompressedStack::AddFrameEntry(AppDomain *pAppDomain, FRAMESECDESCREF fsdRef, BOOL bIsAHDMFrame, OBJECTREF dynamicResolverRef) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - ENTER_DOMAIN_PTR(pAppDomain,ADV_RUNNINGIN) //have it on the stack - { - struct gc - { - OBJECTREF fsdRef; - OBJECTREF newFsdRef; - OBJECTREF dynamicResolverRef; - } gc; - ZeroMemory( &gc, sizeof( gc ) ); - gc.fsdRef = (OBJECTREF)fsdRef; - gc.dynamicResolverRef = dynamicResolverRef; - - GCPROTECT_BEGIN(gc); - - static MethodTable* pMethFrameSecDesc = NULL; - if (pMethFrameSecDesc == NULL) - pMethFrameSecDesc = MscorlibBinder::GetClass(CLASS__FRAME_SECURITY_DESCRIPTOR); - - static MethodTable* pMethFrameSecDescWCS = NULL; - if (pMethFrameSecDescWCS == NULL) - pMethFrameSecDescWCS = MscorlibBinder::GetClass(CLASS__FRAME_SECURITY_DESCRIPTOR_WITH_RESOLVER); - - if(!bIsAHDMFrame) - { - gc.newFsdRef = AllocateObject(pMethFrameSecDesc); - } - else - { - gc.newFsdRef = AllocateObject(pMethFrameSecDescWCS); - } - - // We will not call the ctor and instead patch up the object based on the fsdRef passed in - FRAMESECDESCREF newFsdRef = (FRAMESECDESCREF)gc.newFsdRef; - FRAMESECDESCREF fsdRef1 = (FRAMESECDESCREF)gc.fsdRef; - if(fsdRef1 != NULL) - { - FrameSecurityDescriptorCopyFrom(newFsdRef, fsdRef1); - } - if(bIsAHDMFrame) - { - _ASSERTE(gc.dynamicResolverRef != NULL); - ((FRAMESECDESWITHRESOLVERCREF)newFsdRef)->SetDynamicMethodResolver(gc.dynamicResolverRef); - } - OBJECTHANDLEHolder tmpHnd(pAppDomain->CreateHandle(gc.newFsdRef)); - - AddEntry((void*)tmpHnd); - tmpHnd.SuppressRelease(); - GCPROTECT_END(); - - } - END_DOMAIN_TRANSITION; - -} - - -void DomainCompressedStack::Destroy(void) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // Clear Domain info (handles etc.) if the AD has not been unloaded. - ClearDomainInfo(); - return; -} - -FCIMPL1(DWORD, DomainCompressedStack::GetDescCount, DomainCompressedStack* dcs) -{ - FCALL_CONTRACT; - - FCUnique(0x42); - - return dcs->m_EntryList.GetCount(); -} -FCIMPLEND - -FCIMPL3(void, DomainCompressedStack::GetDomainPermissionSets, DomainCompressedStack* dcs, OBJECTREF* ppGranted, OBJECTREF* ppDenied) -{ - FCALL_CONTRACT; - - HELPER_METHOD_FRAME_BEGIN_0(); - - *ppGranted = NULL; - *ppDenied = NULL; - - AppDomain* appDomain = SystemDomain::GetAppDomainFromId(dcs->GetMyDomain(),ADV_RUNNINGIN); - if (appDomain == NULL) - { - // this might be the unloading AD - AppDomain *pUnloadingDomain = SystemDomain::System()->AppDomainBeingUnloaded(); - if (pUnloadingDomain && pUnloadingDomain->GetId() == dcs->m_DomainID) - { -#ifdef _DEBUG - CheckADValidity(pUnloadingDomain, ADV_RUNNINGIN); -#endif - appDomain = pUnloadingDomain; - } - } - _ASSERTE(appDomain != NULL); - if (appDomain != NULL) - { - IApplicationSecurityDescriptor * pAppSecDesc = appDomain->GetSecurityDescriptor(); - _ASSERTE(pAppSecDesc != NULL); - if (pAppSecDesc != NULL) - { - *ppGranted = pAppSecDesc->GetGrantedPermissionSet(ppDenied); - } - } - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - -FCIMPL6(FC_BOOL_RET, DomainCompressedStack::GetDescriptorInfo, DomainCompressedStack* dcs, DWORD index, OBJECTREF* ppGranted, OBJECTREF* ppDenied, OBJECTREF* ppAssembly, OBJECTREF* ppFSD) -{ - FCALL_CONTRACT; - - _ASSERTE(dcs != NULL); - AppDomain* pCurrentDomain = GetAppDomain(); - BOOL bRetVal = FALSE; - - HELPER_METHOD_FRAME_BEGIN_RET_0() - *ppGranted = NULL; - *ppDenied = NULL; - *ppAssembly = NULL; - *ppFSD = NULL; - void* pEntry = dcs->m_EntryList.Get(index); - _ASSERTE(pEntry != NULL); - if (IS_LOW_BIT_SET(pEntry)) - { - // Assembly found - SharedSecurityDescriptor* pSharedSecDesc = (SharedSecurityDescriptor* )UNSET_LOW_BIT(pEntry); - Assembly* pAssembly = pSharedSecDesc->GetAssembly(); - IAssemblySecurityDescriptor* pAsmSecDesc = pAssembly->GetSecurityDescriptor( pCurrentDomain ); - *ppGranted = pAsmSecDesc->GetGrantedPermissionSet(ppDenied); - *ppAssembly = pAssembly->GetExposedObject(); - } - else - { - //FSD - OBJECTHANDLE objHnd = (OBJECTHANDLE)pEntry; - if (objHnd == NULL) - { - // throw an ADUnloaded exception which we will catch and then look at the serializedBlob - COMPlusThrow(kAppDomainUnloadedException); - } - *ppFSD = ObjectFromHandle(objHnd); - bRetVal = TRUE; - } - HELPER_METHOD_FRAME_END(); - - FC_RETURN_BOOL(bRetVal); -} -FCIMPLEND - -FCIMPL1(FC_BOOL_RET, DomainCompressedStack::IgnoreDomain, DomainCompressedStack* dcs) -{ - FCALL_CONTRACT; - - _ASSERTE(dcs != NULL); - - FC_RETURN_BOOL(dcs->IgnoreDomainInternal()); -} -FCIMPLEND - -BOOL DomainCompressedStack::IgnoreDomainInternal() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - SO_TOLERANT; - } - CONTRACTL_END; - - if (m_ignoreAD) - return TRUE; - - AppDomainFromIDHolder appDomain(GetMyDomain(), TRUE); - if (!appDomain.IsUnloaded()) - { - IApplicationSecurityDescriptor *pAppSecDesc = appDomain->GetSecurityDescriptor(); - _ASSERTE(pAppSecDesc != NULL); - if (pAppSecDesc != NULL) - { - return pAppSecDesc->IsDefaultAppDomain() || pAppSecDesc->IsInitializationInProgress(); - } - } - - return FALSE; -} - - -/* - Note that this function is called only once: when the managed PLS is being created. - It's possible that 2 threads could race at that point: only downside of that is that they will both do the work. No races. - Also, we'll never be operating on a DCS whose domain is not on the current callstack. This eliminates all kinds of ADU/demand eval races. -*/ -OBJECTREF DomainCompressedStack::GetDomainCompressedStackInternal(AppDomain *pDomain) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // If we are going to skip this AppDomain, and there is nothing to compress, then we can skip building the DCS. - if (m_EntryList.GetCount() == 0 && IgnoreDomainInternal()) - return NULL; - - AppDomain* pCurrentDomain = GetAppDomain(); - - NewArrayHolder<BYTE> pbtmpSerializedObject(NULL); -#ifndef FEATURE_CORECLR - DWORD cbtmpSerializedObject = 0; -#endif - - struct gc - { - OBJECTREF refRetVal; - } gc; - ZeroMemory( &gc, sizeof( gc ) ); - - GCPROTECT_BEGIN( gc ); - - // Create object - ENTER_DOMAIN_ID (GetMyDomain()) //on the stack - { - - // Go ahead and create the object -#ifdef FEATURE_CORECLR // ignore other appdomains - if (GetAppDomain() == pCurrentDomain) -#endif - { - MethodDescCallSite createManagedObject(METHOD__DOMAIN_COMPRESSED_STACK__CREATE_MANAGED_OBJECT); - ARG_SLOT args[] = {PtrToArgSlot(this)}; - gc.refRetVal = createManagedObject.Call_RetOBJECTREF(args); - } - -#ifndef FEATURE_CORECLR - // Do we want to marshal this object also? - if (GetAppDomain() != pCurrentDomain) - { - // Serialize to a blob; - AppDomainHelper::MarshalObject(GetAppDomain(), &gc.refRetVal, &pbtmpSerializedObject, &cbtmpSerializedObject); - if (pbtmpSerializedObject == NULL) - { - // this is an error: possibly an OOM prevented the blob from getting created. - // We could return null and let the managed code use a fully restricted object or throw here. - // Let's throw here... - COMPlusThrow(kSecurityException); - } - } -#endif - - } - END_DOMAIN_TRANSITION - -#ifndef FEATURE_CORECLR // should never happen for core clr - if (GetMyDomain() != pCurrentDomain->GetId()) - { - AppDomainHelper::UnmarshalObject(pCurrentDomain,pbtmpSerializedObject, cbtmpSerializedObject, &gc.refRetVal); - } -#endif - - GCPROTECT_END(); - - return gc.refRetVal; -} - - -void DomainCompressedStack::ClearDomainInfo(void) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - - // So, assume mutual exclusion holds and no races occur here - - - // Now it is time to go NULL out any ObjectHandle we're using in the list of entries - ArrayList::Iterator iter = m_EntryList.Iterate(); - - while (iter.Next()) - { - void* pEntry = iter.GetElement(); - if (!IS_LOW_BIT_SET(pEntry)) - { - DestroyHandle((OBJECTHANDLE)pEntry); - } - pEntry = NULL; - } - - - // Always clear the index into the domain object list and the domainID. - m_DomainID = ADID(INVALID_APPDOMAIN_ID); - return; -} - -NewCompressedStack::NewCompressedStack() -: m_DCSListCount(0), - m_currentDCS(NULL), - m_pCtxTxFrame(NULL), - m_CSAD(ADID(INVALID_APPDOMAIN_ID)), - m_ADStack(GetThread()->GetAppDomainStack()), - m_dwOverridesCount(0), - m_dwAssertCount(0) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - _ASSERTE(m_ADStack.GetNumDomains() > 0); - m_ADStack.InitDomainIteration(&adStackIndex); - m_DCSList = new DomainCompressedStack*[m_ADStack.GetNumDomains()]; - memset(m_DCSList, 0, (m_ADStack.GetNumDomains()*sizeof(DomainCompressedStack*))); - -} - - -void NewCompressedStack::Destroy( CLR_BOOL bEntriesOnly ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (m_DCSList != NULL) - { - m_currentDCS = NULL; - m_pCtxTxFrame = NULL; - for (DWORD i=0; i< m_ADStack.GetNumDomains(); i++) - { - DomainCompressedStack* dcs = m_DCSList[i]; - if (dcs != NULL) - { - dcs->Destroy(); - delete dcs; - } - } - delete[] m_DCSList; - m_DCSList = NULL; - } - if (!bEntriesOnly) - delete this; - -} - - -void NewCompressedStack::ProcessAppDomainTransition(void) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } CONTRACTL_END; - - // Get the current adstack entry. Note that the first time we enter this function, adStackIndex will - // equal the size of the adstack array (similar to what happens in IEnumerator). - // So the initial pEntry will be NULL - AppDomainStackEntry *pEntry = - (adStackIndex == m_ADStack.GetNumDomains() ? NULL : m_ADStack.GetCurrentDomainEntryOnStack(adStackIndex)); - - // Updated the value on the ADStack for current domain - if (pEntry != NULL) - { - DWORD domainOverrides_measured = (m_currentDCS == NULL?0:m_currentDCS->GetOverridesCount()); - DWORD domainAsserts_measured = (m_currentDCS == NULL?0:m_currentDCS->GetAssertCount()); - if (pEntry->m_dwOverridesCount != domainOverrides_measured || pEntry->m_dwAsserts != domainAsserts_measured) - { - m_ADStack.UpdateDomainOnStack(adStackIndex, domainAsserts_measured, domainOverrides_measured); - GetThread()->UpdateDomainOnStack(adStackIndex, domainAsserts_measured, domainOverrides_measured); - } - } - - // Move the domain index forward if this is not the last entry - if (adStackIndex > 0) - m_ADStack.GetNextDomainEntryOnStack(&adStackIndex); - m_currentDCS = NULL; - - return; - -} -DWORD NewCompressedStack::ProcessFrame(AppDomain* pAppDomain, Assembly* pAssembly, MethodDesc* pFunc, ISharedSecurityDescriptor* pSsd, FRAMESECDESCREF* pFsdRef) -{ - // This function will be called each time we hit a new stack frame in a stack walk. - - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pAppDomain)); - PRECONDITION(CheckPointer(pSsd)); - } CONTRACTL_END; - - // Get the current adstack entry. Note that the first time we enter this function, adStackIndex will - // equal the size of the adstack array (similar to what happens in IEnumerator). - // So the initial pEntry will be NULL - AppDomainStackEntry *pEntry = - (adStackIndex == m_ADStack.GetNumDomains() ? NULL : m_ADStack.GetCurrentDomainEntryOnStack(adStackIndex)); - - - _ASSERTE(pEntry != NULL); - PREFIX_ASSUME(pEntry != NULL); - FRAMESECDESCREF FsdRef = (pFsdRef!=NULL?*pFsdRef:NULL); - DWORD dwFlags = 0; - if (FsdRef != NULL) - { - - if (FsdRef->HasAssertFT()) - dwFlags |= CORSEC_FT_ASSERT; - } - - BOOL bIsAHDMFrame = FALSE; - - if((pFunc != NULL) && !CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Security_DisableAnonymouslyHostedDynamicMethodCreatorSecurityCheck)) - { - ENTER_DOMAIN_PTR(pAppDomain, ADV_RUNNINGIN) - { - bIsAHDMFrame = SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pFunc); - } - END_DOMAIN_TRANSITION; - } - - if (!bIsAHDMFrame && ((pEntry->IsFullyTrustedWithNoStackModifiers()) || - (m_currentDCS != NULL && m_currentDCS->m_Homogeneous))) - { - // Nothing to do in this entire AD. - return dwFlags; - } - - ADID dNewDomainID = pAppDomain->GetId(); - BOOL bAddSSD = (!pSsd->IsSystem() && !IsAssemblyPresent(dNewDomainID, pSsd)); - BOOL bHasStackModifiers = FALSE; - DWORD overridesCount = 0; - DWORD assertCount = 0; - - - if (FsdRef != NULL) - { - overridesCount += FsdRef->GetOverridesCount(); - assertCount += FsdRef->GetAssertCount(); - } - - // If this is an AHDM frame with a CS to evaluate, it may have overrides or asserts, - // so treat it as if it does - if(bIsAHDMFrame) - { - overridesCount++; - assertCount++; - } - - bHasStackModifiers = ( (assertCount + overridesCount) > 0); - - // - // We need to add a new DCS if we don't already have one for this AppDomain. If we've reached this - // point, either: - // * the AppDomain is partially trusted - // * the AppDomain is fully trusted, but may have stack modifiers in play - // * we're running in legacy mode where FullTrust doesn't mean FullTrust - // - // If the domain is partially trusted, we'll always need to capture it. If we got this far due to a - // fully trusted domain that might have stack modifiers, we only have to capture if there really were - // stack walk modifiers. In the legacy mode case, we need to capture the domain if we had stack - // modifiers or we needed to add the shared security descriptor. - // - - BOOL bCreateDCS = (m_currentDCS == NULL || m_currentDCS->m_DomainID != dNewDomainID); - if (pAppDomain->GetSecurityDescriptor()->IsFullyTrusted()) - { - bCreateDCS &= (bAddSSD || bHasStackModifiers); - } - - if (bCreateDCS) - { - CreateDCS(dNewDomainID); - } - - // Add the ISharedSecurityDescriptor (Assembly) to the list if it is not already present in the list - if (bAddSSD) - { - m_currentDCS->AddEntry((void*)SET_LOW_BIT(pSsd)); - if (pEntry->IsHomogeneousWithNoStackModifiers()) - m_currentDCS->m_Homogeneous = TRUE; - } - if (bHasStackModifiers) - { - OBJECTREF dynamicResolverRef = NULL; - if(bIsAHDMFrame) - { - _ASSERTE(pFunc->IsLCGMethod()); - dynamicResolverRef = pFunc->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver(); - } - - // We need to add the FSD entry here - m_currentDCS->AddFrameEntry(pAppDomain, FsdRef, bIsAHDMFrame, dynamicResolverRef); - m_currentDCS->m_dwOverridesCount += overridesCount; - m_currentDCS->m_dwAssertCount += assertCount; - m_dwOverridesCount += overridesCount; - m_dwAssertCount += assertCount; - } - return dwFlags; -} - -// Build a CompressedStack given that all domains on the stack are homogeneous with no stack modifiers -FCIMPL1(void, NewCompressedStack::FCallGetHomogeneousPLS, Object* hgPLSUnsafe) -{ - FCALL_CONTRACT; - - OBJECTREF refHomogeneousPLS = (OBJECTREF)hgPLSUnsafe; - - HELPER_METHOD_FRAME_BEGIN_1(refHomogeneousPLS); - - - // Walk the adstack and update the grantSetUnion - AppDomainStack* pADStack = GetThread()->GetAppDomainStackPointer(); - DWORD dwAppDomainIndex; - pADStack->InitDomainIteration(&dwAppDomainIndex); - -#ifdef FEATURE_REMOTING // without remoting we need only current appdomain - while (dwAppDomainIndex != 0) -#endif - { - AppDomainStackEntry* pEntry = pADStack->GetNextDomainEntryOnStack(&dwAppDomainIndex); - _ASSERTE(pEntry != NULL); - - pEntry->UpdateHomogeneousPLS(&refHomogeneousPLS); - } - - - HELPER_METHOD_FRAME_END(); - return ; -} -FCIMPLEND; - -// Special case of ProcessFrame called with the CS at the base of the thread -void NewCompressedStack::ProcessCS(AppDomain* pAppDomain, COMPRESSEDSTACKREF csRef, Frame *pFrame) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pAppDomain)); - } CONTRACTL_END; - - _ASSERTE(csRef != NULL && "Shouldn't call this function if CS is NULL"); - ADID dNewDomainID = pAppDomain->GetId(); - NewCompressedStack* pCS = (NewCompressedStack* )csRef->GetUnmanagedCompressedStack(); - if (csRef->IsEmptyPLS() && (pCS == NULL || pCS->GetDCSListCount() == 0)) - { - // Do nothing - empty inner CS - return; - } - - // Let's special case the 1-domain CS that has no inner CSs here - // Check for: - // 1. == 1 DCS - // 2. DCS is in correct AD (it's possible that pCS is AD-X and it has only one DCS in AD-Y, because AD-X has only mscorlib frames - // 3. No inner CS - if ( pCS != NULL && - pCS->GetDCSListCount() == 1 && - pCS->m_DCSList != NULL && - pCS->m_currentDCS != NULL && - pCS->m_currentDCS->m_DomainID == dNewDomainID && - pCS->m_CSAD == ADID(INVALID_APPDOMAIN_ID)) - { - ProcessSingleDomainNCS(pCS, pAppDomain); - } - else - { - - // set flag to ignore Domain grant set if the current DCS is the same as the one with the CS - if (m_currentDCS != NULL && m_currentDCS->m_DomainID == dNewDomainID) - { - m_currentDCS->m_ignoreAD = TRUE; - } - - // Update overrides/asserts - if (pCS != NULL) - { - m_dwOverridesCount += pCS->GetOverridesCount(); - m_dwAssertCount += pCS->GetAssertCount(); - } - - - // Do we need to store the CtxTransitionFrame or did we get the CS from the thread? - if (pFrame != NULL) - { - _ASSERTE(csRef == SecurityStackWalk::GetCSFromContextTransitionFrame(pFrame)); - // Use data from the CtxTxFrame - m_pCtxTxFrame = pFrame; - } - m_CSAD = dNewDomainID; - } - -} -void NewCompressedStack::ProcessSingleDomainNCS(NewCompressedStack *pCS, AppDomain* pAppDomain) -{ - - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pAppDomain)); - } CONTRACTL_END; - - _ASSERTE(pCS->GetDCSListCount() <= 1 && pCS->m_CSAD == ADID(INVALID_APPDOMAIN_ID)); - ADID newDomainID = pAppDomain->GetId(); - DomainCompressedStack* otherDCS = pCS->m_currentDCS; - - if (otherDCS == NULL) - return; - if (m_currentDCS == NULL) - CreateDCS(newDomainID); - - - // Iterate thru the entryList in the current DCS - ArrayList::Iterator iter = otherDCS->m_EntryList.Iterate(); - while (iter.Next()) - { - void* pEntry = iter.GetElement(); - if (IS_LOW_BIT_SET(pEntry)) - { - if (!IsAssemblyPresent(newDomainID, (ISharedSecurityDescriptor*)UNSET_LOW_BIT(pEntry))) - { - //Add the assembly - m_currentDCS->AddEntry(pEntry); - } - } - else - { - // FrameSecurityDescriptor - OBJECTHANDLE objHnd = (OBJECTHANDLE)pEntry; - OBJECTREF fsdRef = ObjectFromHandle(objHnd); - OBJECTHANDLEHolder tmpHnd(pAppDomain->CreateHandle(fsdRef)); - - m_currentDCS->AddEntry((void*)tmpHnd); - tmpHnd.SuppressRelease(); - - } - - } - - m_currentDCS->m_dwOverridesCount += pCS->m_dwOverridesCount; - m_currentDCS->m_dwAssertCount += pCS->m_dwAssertCount; - m_dwOverridesCount += pCS->m_dwOverridesCount; - m_dwAssertCount += pCS->m_dwAssertCount; -} -void NewCompressedStack::CreateDCS(ADID domainID) -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - _ASSERTE(adStackIndex < m_ADStack.GetNumDomains()); - _ASSERTE (m_DCSList != NULL); - m_DCSList[adStackIndex] = new DomainCompressedStack(domainID); - m_currentDCS = m_DCSList[adStackIndex]; - m_DCSListCount++; - - return; -} - - -BOOL NewCompressedStack::IsAssemblyPresent(ADID domainID, ISharedSecurityDescriptor* pSsd) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - _ASSERTE(domainID != ADID(INVALID_APPDOMAIN_ID) && "Don't pass invalid domain"); - - BOOL bEntryPresent = FALSE; - - for(DWORD i=0; i < m_ADStack.GetNumDomains(); i++) - { - - DomainCompressedStack* pTmpDCS = m_DCSList[i]; - - if (pTmpDCS != NULL && pTmpDCS->m_DomainID == domainID && pTmpDCS->IsAssemblyPresent(pSsd)) - { - bEntryPresent = TRUE; - break; - } - } - return bEntryPresent; -} - - -BOOL NewCompressedStack::IsDCSContained(DomainCompressedStack *pDCS) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // return FALSE if no DCS or DCS is for a domain that has been unloaded - if (pDCS == NULL || pDCS->m_DomainID == ADID(INVALID_APPDOMAIN_ID)) - return FALSE; - - - - // Iterate thru the entryList in the current DCS - ArrayList::Iterator iter = pDCS->m_EntryList.Iterate(); - while (iter.Next()) - { - void* pEntry = iter.GetElement(); - if (IS_LOW_BIT_SET(pEntry)) - { - // We only check Assemblies. - if (!IsAssemblyPresent(pDCS->m_DomainID, (ISharedSecurityDescriptor*)UNSET_LOW_BIT(pEntry))) - return FALSE; - } - } - return TRUE; -} - -BOOL NewCompressedStack::IsNCSContained(NewCompressedStack *pCS) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // Check if the first level of pCS is contained in this. - if (pCS == NULL) - return TRUE; - - // Return FALSE if there are any overrides or asserts - if (pCS->GetOverridesCount() > 0) - return FALSE; - // Return FALSE if there is an inner CS - if (pCS->m_CSAD != ADID(INVALID_APPDOMAIN_ID)) - return FALSE; - - for(DWORD i=0; i < m_ADStack.GetNumDomains(); i++) - { - DomainCompressedStack *pDCS = (DomainCompressedStack *) m_DCSList[i]; - if (!IsDCSContained(pDCS)) - return FALSE; - } - return TRUE; - -} - - -// If there is a compressed stack present in the captured CompressedStack, return that CS in the current domain -OBJECTREF NewCompressedStack::GetCompressedStackInner() -{ - _ASSERTE(m_CSAD != ADID(INVALID_APPDOMAIN_ID)); - - AppDomain* pCurrentDomain = GetAppDomain(); - NewArrayHolder<BYTE> pbtmpSerializedObject(NULL); - - - OBJECTREF refRetVal = NULL; - - if (pCurrentDomain->GetId()== m_CSAD) - { - // we're in the right domain already - if (m_pCtxTxFrame == NULL) - { - // Get CS from the thread - refRetVal = GetThread()->GetCompressedStack(); - } - else - { - // Get CS from a Ctx transition frame - refRetVal = (OBJECTREF)SecurityStackWalk::GetCSFromContextTransitionFrame(m_pCtxTxFrame); - _ASSERTE(refRetVal != NULL); //otherwise we would not have saved the frame in the CB data - } - } - else -#ifndef FEATURE_CORECLR // should never happen for core clr - { - DWORD cbtmpSerializedObject = 0; - GCPROTECT_BEGIN (refRetVal); - // need to marshal the CS over into the current AD - ENTER_DOMAIN_ID(m_CSAD); - { - if (m_pCtxTxFrame == NULL) - { - - // Get CS from the thread - refRetVal = GetThread()->GetCompressedStack(); - } - else - { - // Get CS from a Ctx transition frame - refRetVal = (OBJECTREF)SecurityStackWalk::GetCSFromContextTransitionFrame(m_pCtxTxFrame); - _ASSERTE(refRetVal != NULL); //otherwise we would not have saved the frame in the CB data - } - AppDomainHelper::MarshalObject(GetAppDomain(), &refRetVal, &pbtmpSerializedObject, &cbtmpSerializedObject); - } - END_DOMAIN_TRANSITION - refRetVal = NULL; - AppDomainHelper::UnmarshalObject(pCurrentDomain,pbtmpSerializedObject, cbtmpSerializedObject, &refRetVal); - GCPROTECT_END (); - _ASSERTE(refRetVal != NULL); //otherwise we would not have saved the frame in the CB data - } -#else - { - UNREACHABLE(); - } -#endif // !FEATURE_CORECLR - - return refRetVal; - -} - -// == Now begin the functions used in building Demand evaluation of a compressed stack -FCIMPL1(DWORD, NewCompressedStack::FCallGetDCSCount, SafeHandle* hcsUNSAFE) -{ - FCALL_CONTRACT; - - DWORD dwRet = 0; - if (hcsUNSAFE != NULL) - { - SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_1(hcsSAFE); - - NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle(); - - dwRet = ncs->m_ADStack.GetNumDomains(); - HELPER_METHOD_FRAME_END(); - } - - return dwRet; - -} -FCIMPLEND - - -FCIMPL2(FC_BOOL_RET, NewCompressedStack::FCallIsImmediateCompletionCandidate, SafeHandle* hcsUNSAFE, OBJECTREF *innerCS) -{ - FCALL_CONTRACT; - - BOOL bRet = FALSE; - if (hcsUNSAFE != NULL) - { - SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_1(hcsSAFE); - - *innerCS = NULL; - - NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle(); - - if (ncs != NULL) - { - // Non-FT case - - // Is there an inner CS? - BOOL bHasCS = (ncs->m_CSAD != ADID(INVALID_APPDOMAIN_ID)); - - // Is there is a DCS not in the current AD - BOOL bHasOtherAppDomain = FALSE; - if (ncs->m_DCSList != NULL) - { - for(DWORD i=0; i < ncs->m_ADStack.GetNumDomains(); i++) - { - DomainCompressedStack* dcs = ncs->m_DCSList[i]; - if (dcs != NULL && dcs->GetMyDomain() != GetAppDomain()->GetId()) - { - bHasOtherAppDomain = TRUE; - break; - } - } - } - if (bHasCS) - { - - - *innerCS = ncs->GetCompressedStackInner(); - ncs->m_pCtxTxFrame = NULL; // Clear the CtxTxFrame ASAP - - } - bRet = bHasOtherAppDomain||bHasCS; - } - - HELPER_METHOD_FRAME_END(); - } - - FC_RETURN_BOOL(bRet); -} -FCIMPLEND - - -FCIMPL2(Object*, NewCompressedStack::GetDomainCompressedStack, SafeHandle* hcsUNSAFE, DWORD index) -{ - FCALL_CONTRACT; - - OBJECTREF refRetVal = NULL; - if (hcsUNSAFE != NULL) - { - SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, hcsSAFE); - - - - NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle(); - - // First we check to see if the DCS at index i has a blob. If so, deserialize it into the current AD and return it. Else try create it - DomainCompressedStack* dcs = ncs->m_DCSList[index]; - if (dcs != NULL) - { - refRetVal = dcs->GetDomainCompressedStackInternal(NULL); - } - - HELPER_METHOD_FRAME_END(); - } - - return OBJECTREFToObject(refRetVal); - -} -FCIMPLEND - -FCIMPL1(void, NewCompressedStack::DestroyDCSList, SafeHandle* hcsUNSAFE) -{ - FCALL_CONTRACT; - - SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_1(hcsSAFE); - - NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle(); - - ncs->Destroy(TRUE); - - HELPER_METHOD_FRAME_END(); - -} -FCIMPLEND -#endif // #ifdef FEATURE_COMPRESSEDSTACK |