diff options
Diffstat (limited to 'src/vm/clsload.cpp')
-rw-r--r-- | src/vm/clsload.cpp | 456 |
1 files changed, 17 insertions, 439 deletions
diff --git a/src/vm/clsload.cpp b/src/vm/clsload.cpp index da48549e7b..22b030caa0 100644 --- a/src/vm/clsload.cpp +++ b/src/vm/clsload.cpp @@ -23,7 +23,6 @@ #include "comsynchronizable.h" #include "threads.h" #include "dllimport.h" -#include "security.h" #include "dbginterface.h" #include "log.h" #include "eeconfig.h" @@ -4869,27 +4868,6 @@ StaticAccessCheckContext::StaticAccessCheckContext(MethodDesc* pCallerMethod, Me m_pCallerAssembly = pCallerType->GetAssembly(); } -// Critical callers do not need the extra access checks -bool StaticAccessCheckContext::IsCallerCritical() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - if (m_pCallerMethod == NULL || !Security::IsMethodTransparent(m_pCallerMethod)) - { - return true; - } - - return false; -} - - - //****************************************************************************** // static @@ -4911,8 +4889,7 @@ void AccessCheckOptions::Startup() //****************************************************************************** AccessCheckOptions::AccessCheckOptions( const AccessCheckOptions & templateOptions, - BOOL throwIfTargetIsInaccessible, - BOOL skipCheckForCriticalCode /*=FALSE*/) : + BOOL throwIfTargetIsInaccessible) : m_pAccessContext(templateOptions.m_pAccessContext) { WRAPPER_NO_CONTRACT; @@ -4922,8 +4899,7 @@ AccessCheckOptions::AccessCheckOptions( throwIfTargetIsInaccessible, templateOptions.m_pTargetMT, templateOptions.m_pTargetMethod, - templateOptions.m_pTargetField, - skipCheckForCriticalCode); + templateOptions.m_pTargetField); } //****************************************************************************** @@ -4978,36 +4954,15 @@ BOOL AccessCheckOptions::DemandMemberAccess(AccessCheckContext *pContext, Method // classes/members in app code. if (m_accessCheckType != kMemberAccess && pTargetMT) { - if (visibilityCheck && Security::IsTransparencyEnforcementEnabled()) - { - // In CoreCLR RMA means visibility checks always succeed if the target is user code. - if (m_accessCheckType == kRestrictedMemberAccess || m_accessCheckType == kRestrictedMemberAccessNoTransparency) - return TRUE; - - // Accessing private types/members in platform code. - fAccessingFrameworkCode = TRUE; - } - else - { - // We allow all transparency checks to succeed in LCG methods and reflection invocation. - if (m_accessCheckType == kNormalAccessNoTransparency || m_accessCheckType == kRestrictedMemberAccessNoTransparency) - return TRUE; - } + // We allow all transparency checks to succeed in LCG methods and reflection invocation. + if (m_accessCheckType == kNormalAccessNoTransparency || m_accessCheckType == kRestrictedMemberAccessNoTransparency) + return TRUE; } // Always allow interop (NULL) callers full access. if (pContext->IsCalledFromInterop()) return TRUE; - MethodDesc* pCallerMD = pContext->GetCallerMethod(); - - // critical code is exempted from all accessibility rules, regardless of the AccessCheckType. - if (pCallerMD != NULL && - !Security::IsMethodTransparent(pCallerMD)) - { - return TRUE; - } - // No Access if (m_fThrowIfTargetIsInaccessible) { @@ -5090,15 +5045,6 @@ BOOL AccessCheckOptions::DemandMemberAccessOrFail(AccessCheckContext *pContext, } CONTRACTL_END; - // m_fSkipCheckForCriticalCode is only ever set to true for CanAccessMemberForExtraChecks. - // For legacy compat we allow the access check to succeed for all AccessCheckType if the caller is critical. - if (m_fSkipCheckForCriticalCode) - { - if (pContext->IsCalledFromInterop() || - !Security::IsMethodTransparent(pContext->GetCallerMethod())) - return TRUE; - } - if (DoNormalAccessibilityChecks()) { if (pContext->GetCallerAssembly()->IgnoresAccessChecksTo(pTargetMT->GetAssembly())) @@ -5131,15 +5077,6 @@ BOOL AccessCheckOptions::FailOrThrow(AccessCheckContext *pContext) const } CONTRACTL_END; - // m_fSkipCheckForCriticalCode is only ever set to true for CanAccessMemberForExtraChecks. - // For legacy compat we allow the access check to succeed for all AccessCheckType if the caller is critical. - if (m_fSkipCheckForCriticalCode) - { - if (pContext->IsCalledFromInterop() || - !Security::IsMethodTransparent(pContext->GetCallerMethod())) - return TRUE; - } - if (m_fThrowIfTargetIsInaccessible) { ThrowAccessException(pContext); @@ -5151,7 +5088,6 @@ BOOL AccessCheckOptions::FailOrThrow(AccessCheckContext *pContext) const // Generate access exception context strings that are due to potential security misconfiguration void GetAccessExceptionAdditionalContextForSecurity(Assembly *pAccessingAssembly, Assembly *pTargetAssembly, - BOOL isTransparencyError, BOOL fAccessingFrameworkCode, StringArrayList *pContextInformation) { @@ -5182,7 +5118,6 @@ void GetAccessExceptionAdditionalContextForSecurity(Assembly *pAccessingAssembly // context is available, then this returns SString.Empty. SString GetAdditionalAccessExceptionContext(Assembly *pAccessingAssembly, Assembly *pTargetAssembly, - BOOL isTransparencyError, BOOL fAccessingFrameworkCode) { CONTRACTL @@ -5200,7 +5135,6 @@ SString GetAdditionalAccessExceptionContext(Assembly *pAccessingAssembly, // See if the exception may have been caused by security GetAccessExceptionAdditionalContextForSecurity(pAccessingAssembly, pTargetAssembly, - isTransparencyError, fAccessingFrameworkCode, &contextComponents); @@ -5236,15 +5170,10 @@ void DECLSPEC_NORETURN ThrowFieldAccessException(AccessCheckContext* pContext, } CONTRACTL_END; - BOOL isTransparencyError = FALSE; - MethodDesc* pCallerMD = pContext->GetCallerMethod(); - if (pCallerMD != NULL) - isTransparencyError = !Security::CheckCriticalAccess(pContext, NULL, pFD, NULL); ThrowFieldAccessException(pCallerMD, pFD, - isTransparencyError, messageID, pInnerException, fAccessingFrameworkCode); @@ -5252,7 +5181,6 @@ void DECLSPEC_NORETURN ThrowFieldAccessException(AccessCheckContext* pContext, void DECLSPEC_NORETURN ThrowFieldAccessException(MethodDesc* pCallerMD, FieldDesc *pFD, - BOOL isTransparencyError, UINT messageID /* = 0 */, Exception *pInnerException /* = NULL */, BOOL fAccessingFrameworkCode /* = FALSE */) @@ -5271,22 +5199,11 @@ void DECLSPEC_NORETURN ThrowFieldAccessException(MethodDesc* pCallerMD, { if (messageID == 0) { - // Figure out if we can give a specific reason why this field access was rejected - for instance, if - // we see that the caller is transparent and accessing a critical field, then we can put that - // information into the exception message. - if (isTransparencyError) - { - messageID = IDS_E_CRITICAL_FIELD_ACCESS_DENIED; - } - else - { - messageID = IDS_E_FIELDACCESS; - } + messageID = IDS_E_FIELDACCESS; } SString strAdditionalContext = GetAdditionalAccessExceptionContext(pCallerMD->GetAssembly(), pFD->GetApproxEnclosingMethodTable()->GetAssembly(), - isTransparencyError, fAccessingFrameworkCode); EX_THROW_WITH_INNER(EEFieldException, (pFD, pCallerMD, strAdditionalContext, messageID), pInnerException); @@ -5313,15 +5230,10 @@ void DECLSPEC_NORETURN ThrowMethodAccessException(AccessCheckContext* pContext, } CONTRACTL_END; - BOOL isTransparencyError = FALSE; - MethodDesc* pCallerMD = pContext->GetCallerMethod(); - if (pCallerMD != NULL) - isTransparencyError = !Security::CheckCriticalAccess(pContext, pCalleeMD, NULL, NULL); ThrowMethodAccessException(pCallerMD, pCalleeMD, - isTransparencyError, messageID, pInnerException, fAccessingFrameworkCode); @@ -5329,7 +5241,6 @@ void DECLSPEC_NORETURN ThrowMethodAccessException(AccessCheckContext* pContext, void DECLSPEC_NORETURN ThrowMethodAccessException(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, - BOOL isTransparencyError, UINT messageID /* = 0 */, Exception *pInnerException /* = NULL */, BOOL fAccessingFrameworkCode /* = FALSE */) @@ -5348,22 +5259,11 @@ void DECLSPEC_NORETURN ThrowMethodAccessException(MethodDesc* pCallerMD, { if (messageID == 0) { - // Figure out if we can give a specific reason why this method access was rejected - for instance, if - // we see that the caller is transparent and the callee is critical, then we can put that - // information into the exception message. - if (isTransparencyError) - { - messageID = IDS_E_CRITICAL_METHOD_ACCESS_DENIED; - } - else - { - messageID = IDS_E_METHODACCESS; - } + messageID = IDS_E_METHODACCESS; } SString strAdditionalContext = GetAdditionalAccessExceptionContext(pCallerMD->GetAssembly(), pCalleeMD->GetAssembly(), - isTransparencyError, fAccessingFrameworkCode); EX_THROW_WITH_INNER(EEMethodException, (pCalleeMD, pCallerMD, strAdditionalContext, messageID), pInnerException); @@ -5390,15 +5290,10 @@ void DECLSPEC_NORETURN ThrowTypeAccessException(AccessCheckContext* pContext, } CONTRACTL_END; - BOOL isTransparencyError = FALSE; - MethodDesc* pCallerMD = pContext->GetCallerMethod(); - if (pCallerMD != NULL) - isTransparencyError = !Security::CheckCriticalAccess(pContext, NULL, NULL, pMT); ThrowTypeAccessException(pCallerMD, pMT, - isTransparencyError, messageID, pInnerException, fAccessingFrameworkCode); @@ -5406,7 +5301,6 @@ void DECLSPEC_NORETURN ThrowTypeAccessException(AccessCheckContext* pContext, void DECLSPEC_NORETURN ThrowTypeAccessException(MethodDesc* pCallerMD, MethodTable *pMT, - BOOL isTransparencyError, UINT messageID /* = 0 */, Exception *pInnerException /* = NULL */, BOOL fAccessingFrameworkCode /* = FALSE */) @@ -5425,22 +5319,11 @@ void DECLSPEC_NORETURN ThrowTypeAccessException(MethodDesc* pCallerMD, { if (messageID == 0) { - // Figure out if we can give a specific reason why this type access was rejected - for instance, if - // we see that the caller is transparent and is accessing a critical type, then we can put that - // information into the exception message. - if (isTransparencyError) - { - messageID = IDS_E_CRITICAL_TYPE_ACCESS_DENIED; - } - else - { - messageID = IDS_E_TYPEACCESS; - } + messageID = IDS_E_TYPEACCESS; } SString strAdditionalContext = GetAdditionalAccessExceptionContext(pCallerMD->GetAssembly(), pMT->GetAssembly(), - isTransparencyError, fAccessingFrameworkCode); EX_THROW_WITH_INNER(EETypeAccessException, (pMT, pCallerMD, strAdditionalContext, messageID), pInnerException); @@ -5451,51 +5334,6 @@ void DECLSPEC_NORETURN ThrowTypeAccessException(MethodDesc* pCallerMD, } } -//****************************************************************************** -// This function determines whether a method [if transparent] -// can access a specified target (e.g. Type, Method, Field) -static BOOL CheckTransparentAccessToCriticalCode( - AccessCheckContext* pContext, - DWORD dwMemberAccess, - MethodTable* pTargetMT, - MethodDesc* pOptionalTargetMethod, - FieldDesc* pOptionalTargetField, - MethodTable* pOptionalTargetType, - const AccessCheckOptions & accessCheckOptions) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pContext)); - PRECONDITION(accessCheckOptions.TransparencyCheckNeeded()); - } - CONTRACTL_END; - - if (!Security::IsTransparencyEnforcementEnabled()) - return TRUE; - - // At most one of these should be non-NULL - _ASSERTE(1 >= ((pOptionalTargetMethod ? 1 : 0) + - (pOptionalTargetField ? 1 : 0) + - (pOptionalTargetType ? 1 : 0))); - - - // if the caller [Method] is transparent, do special security checks - // check if security disallows access to target member - if (!Security::CheckCriticalAccess( - pContext, - pOptionalTargetMethod, - pOptionalTargetField, - pOptionalTargetType)) - { - return accessCheckOptions.DemandMemberAccessOrFail(pContext, pTargetMT, FALSE /*visibilityCheck*/); - } - - return TRUE; -} // static BOOL CheckTransparentAccessToCriticalCode - //--------------------------------------------------------------------------------------- // // Checks to see if access to a member with assembly visiblity is allowed. @@ -5620,8 +5458,7 @@ BOOL ClassLoader::CanAccessClass( // True if access is legal, AccessCheckContext* pContext, // The caller context MethodTable* pTargetClass, // The desired target class. Assembly* pTargetAssembly, // Assembly containing the target class. - const AccessCheckOptions & accessCheckOptions, - BOOL checkTargetTypeTransparency)// = TRUE + const AccessCheckOptions & accessCheckOptions)// = TRUE { CONTRACTL { @@ -5639,26 +5476,6 @@ BOOL ClassLoader::CanAccessClass( // True if access is legal, //if (!pTargetClass) // return TRUE; - // check transparent/critical on type - // Note that dwMemberAccess is of no use here since we don't have a target method yet. It really should be made an optional arg. - // For now, we pass in mdPublic. - if (checkTargetTypeTransparency && accessCheckOptions.TransparencyCheckNeeded()) - { - if (!CheckTransparentAccessToCriticalCode( - pContext, - mdPublic, - pTargetClass, - NULL, - NULL, - pTargetClass, - accessCheckOptions)) - { - // no need to call accessCheckOptions.DemandMemberAccessOrFail here because - // CheckTransparentAccessToCriticalCode does that already - return FALSE; - } - } - // Step 2: Recursively call CanAccessClass on the generic type arguments // Is the desired target a generic instantiation? if (pTargetClass->HasInstantiation()) @@ -5679,8 +5496,7 @@ BOOL ClassLoader::CanAccessClass( // True if access is legal, pContext, pMT, th.GetAssembly(), - accessCheckOptions, - checkTargetTypeTransparency)) + accessCheckOptions)) { // no need to call accessCheckOptions.DemandMemberAccessOrFail here because the base case in // CanAccessClass does that already @@ -5780,23 +5596,14 @@ BOOL ClassLoader::CanAccessClass( // True if access is legal, dwProtection, NULL, NULL, - accessCheckOptions, - FALSE, - FALSE); + accessCheckOptions); } // BOOL ClassLoader::CanAccessClass() //****************************************************************************** // This is a front-end to CheckAccessMember that handles the nested class scope. If can't access // from the current point and are a nested class, then try from the enclosing class. -// It does two things in addition to CanAccessMember: -// 1. If the caller class doesn't have access to the caller, see if the enclosing class does. -// 2. CanAccessMemberForExtraChecks which checks whether the caller class has access to -// the signature of the target method or field. +// In addition to CanAccessMember, if the caller class doesn't have access to the caller, see if the enclosing class does. // -// checkTargetMethodTransparency is set to FALSE only when the check is for JIT-compilation -// because the JIT has a mechanism to insert a callout for the case where -// we need to perform the currentMD <-> TargetMD check at runtime. - /* static */ BOOL ClassLoader::CanAccess( // TRUE if access is allowed, FALSE otherwise. AccessCheckContext* pContext, // The caller context @@ -5806,9 +5613,7 @@ BOOL ClassLoader::CanAccess( // TRUE if access is all MethodDesc* pOptionalTargetMethod, // The target method; NULL if the target is a not a method or // there is no need to check the method's instantiation. FieldDesc* pOptionalTargetField, // or The desired field; if NULL, return TRUE - const AccessCheckOptions & accessCheckOptions, // = s_NormalAccessChecks - BOOL checkTargetMethodTransparency, // = TRUE - BOOL checkTargetTypeTransparency) // = TRUE + const AccessCheckOptions & accessCheckOptions) // = s_NormalAccessChecks { CONTRACT(BOOL) { @@ -5833,9 +5638,7 @@ BOOL ClassLoader::CanAccess( // TRUE if access is all pOptionalTargetField, // Suppress exceptions for nested classes since this is not a hard-failure, // and we can do additional checks - accessCheckOptionsNoThrow, - checkTargetMethodTransparency, - checkTargetTypeTransparency)) + accessCheckOptionsNoThrow)) { // If we're here, CheckAccessMember didn't allow access. BOOL canAccess = FALSE; @@ -5869,9 +5672,7 @@ BOOL ClassLoader::CanAccess( // TRUE if access is all dwMemberAccess, pOptionalTargetMethod, pOptionalTargetField, - accessCheckOptionsNoThrow, - checkTargetMethodTransparency, - checkTargetTypeTransparency); + accessCheckOptionsNoThrow); } if (!canAccess) @@ -5881,212 +5682,12 @@ BOOL ClassLoader::CanAccess( // TRUE if access is all } } - // For member access, we do additional checks to ensure that the specific member can - // be accessed - - if (!CanAccessMemberForExtraChecks( - pContext, - pTargetMT, - pOptionalTargetMethod, - pOptionalTargetField, - accessCheckOptions, - checkTargetMethodTransparency)) - { - RETURN_FROM_INTERIOR_PROBE(FALSE); - } - RETURN_FROM_INTERIOR_PROBE(TRUE); END_INTERIOR_STACK_PROBE; } // BOOL ClassLoader::CanAccess() //****************************************************************************** -// Performs additional checks for member access - -BOOL ClassLoader::CanAccessMemberForExtraChecks( - AccessCheckContext* pContext, - MethodTable* pTargetExactMT, - MethodDesc* pOptionalTargetMethod, - FieldDesc* pOptionalTargetField, - const AccessCheckOptions & accessCheckOptions, - BOOL checkTargetMethodTransparency) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pContext)); - } - CONTRACTL_END; - - // Critical callers do not need the extra checks - // This early-out saves the cost of all the subsequent work - if (pContext->IsCallerCritical()) - { - return TRUE; - } - - if (pOptionalTargetMethod == NULL && pOptionalTargetField == NULL) - return TRUE; - - _ASSERTE((pOptionalTargetMethod == NULL) != (pOptionalTargetField == NULL)); - - // We should always do checks on member signatures. But for backward compatibility we skip this check - // for critical callers. And since we don't want to look for the caller here which might incur a stack walk, - // we delay the check to DemandMemberAccessOrFail time. - AccessCheckOptions legacyAccessCheckOptions(accessCheckOptions, accessCheckOptions.Throws(), TRUE); - - if (pOptionalTargetMethod) - { - // A method is accessible only if all the types in the signature - // are also accessible. - if (!CanAccessSigForExtraChecks(pContext, - pOptionalTargetMethod, - pTargetExactMT, - legacyAccessCheckOptions, - checkTargetMethodTransparency)) - { - return FALSE; - } - } - else - { - _ASSERTE(pOptionalTargetField != NULL); - - // A field is accessible only if the field type is also accessible - - TypeHandle fieldType = pOptionalTargetField->GetExactFieldType(TypeHandle(pTargetExactMT)); - CorElementType fieldCorType = fieldType.GetSignatureCorElementType(); - - MethodTable * pFieldTypeMT = fieldType.GetMethodTableOfElementType(); - - // No access check needed on a generic variable or a function pointer - if (pFieldTypeMT != NULL) - { - if (!CanAccessClassForExtraChecks(pContext, - pFieldTypeMT, - pFieldTypeMT->GetAssembly(), - legacyAccessCheckOptions, - TRUE)) - { - return FALSE; - } - } - } - - return TRUE; -} - -//****************************************************************************** -// Can all the types in the signature of the pTargetMethodSig be accessed? -// -// "ForExtraChecks" means that we only do extra checks (security and transparency) -// instead of the usual loader visibility checks. Post V2, we can enable all checks. - -BOOL ClassLoader::CanAccessSigForExtraChecks( // TRUE if access is allowed, FALSE otherwise. - AccessCheckContext* pContext, - MethodDesc* pTargetMethodSig, // The target method. If this is a shared method, pTargetExactMT gives - // additional information about the exact type - MethodTable* pTargetExactMT, // or The desired field; if NULL, return TRUE - const AccessCheckOptions & accessCheckOptions, - BOOL checkTargetTransparency) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pContext)); - } - CONTRACTL_END; - - MetaSig sig(pTargetMethodSig, TypeHandle(pTargetExactMT)); - - // First, check the return type - - TypeHandle retType = sig.GetRetTypeHandleThrowing(); - MethodTable * pRetMT = retType.GetMethodTableOfElementType(); - - // No access check needed on a generic variable or a function pointer - if (pRetMT != NULL) - { - if (!CanAccessClassForExtraChecks(pContext, - pRetMT, - retType.GetAssembly(), - accessCheckOptions, - checkTargetTransparency)) - { - return FALSE; - } - } - - // - // Now walk all the arguments in the signature - // - - for (CorElementType argType = sig.NextArg(); argType != ELEMENT_TYPE_END; argType = sig.NextArg()) - { - TypeHandle thArg = sig.GetLastTypeHandleThrowing(); - - MethodTable * pArgMT = thArg.GetMethodTableOfElementType(); - - // Either a TypeVarTypeDesc or a FnPtrTypeDesc. No access check needed. - if (pArgMT == NULL) - continue; - - BOOL canAcesssElement = CanAccessClassForExtraChecks( - pContext, - pArgMT, - thArg.GetAssembly(), - accessCheckOptions, - checkTargetTransparency); - if (!canAcesssElement) - { - return FALSE; - } - } - - return TRUE; -} - -//****************************************************************************** -// Can the type be accessed? -// -// "ForExtraChecks" means that we only do extra checks (security and transparency) -// instead of the usual loader visibility checks. Post V2, we can enable all checks. - -BOOL ClassLoader::CanAccessClassForExtraChecks( // True if access is legal, false otherwise. - AccessCheckContext* pContext, - MethodTable* pTargetClass, // The desired target class. - Assembly* pTargetAssembly, // Assembly containing that class. - const AccessCheckOptions & accessCheckOptions, - BOOL checkTargetTypeTransparency) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pContext)); - } - CONTRACTL_END; - - // ------------- Old comments begins ------------ - // Critical callers do not need the extra checks - // TODO: can we enable full access checks now? - // ------------- Old comments ends ------------ - - // We shouldn't bypass accessibility check on member signature for FT/Critical callers - - return CanAccessClass(pContext, - pTargetClass, - pTargetAssembly, - accessCheckOptions, - checkTargetTypeTransparency); -} - -//****************************************************************************** // This is the helper function for the corresponding CanAccess() // It does the following checks: // 1. CanAccessClass on pTargetMT @@ -6103,9 +5704,7 @@ BOOL ClassLoader::CheckAccessMember( // TRUE if access is allowed MethodDesc* pOptionalTargetMethod, // The target method; NULL if the target is a not a method or // there is no need to check the method's instantiation. FieldDesc* pOptionalTargetField, // target field, NULL if there is no Target field - const AccessCheckOptions & accessCheckOptions, - BOOL checkTargetMethodTransparency, - BOOL checkTargetTypeTransparency + const AccessCheckOptions & accessCheckOptions ) { CONTRACTL @@ -6124,17 +5723,13 @@ BOOL ClassLoader::CheckAccessMember( // TRUE if access is allowed if (!CanAccessClass(pContext, pTargetMT, pTargetAssembly, - accessCheckOptions, - checkTargetTypeTransparency)) + accessCheckOptions)) { return FALSE; } // If we are trying to access a generic method, we have to ensure its instantiation is accessible. // Note that we need to perform transparency checks on the instantiation even if we have - // checkTargetMethodTransparency set to false, since generic type parameters by design do not effect - // the transparency of the generic method that is closing over them. This means standard transparency - // checks between caller and closed callee may succeed even if the callee's closure includes a critical type. if (!CanAccessMethodInstantiation( pContext, pOptionalTargetMethod, @@ -6150,23 +5745,6 @@ BOOL ClassLoader::CheckAccessMember( // TRUE if access is allowed // We don't need to do transparency check against pTargetMT here because // it was already done in CanAccessClass above. - if (accessCheckOptions.TransparencyCheckNeeded() && - ((checkTargetMethodTransparency && pOptionalTargetMethod) || - pOptionalTargetField)) - { - if (!CheckTransparentAccessToCriticalCode( - pContext, - dwMemberAccess, - pTargetMT, - pOptionalTargetMethod, - pOptionalTargetField, - NULL, - accessCheckOptions)) - { - return FALSE; - } - } - if (IsMdPublic(dwMemberAccess)) { return TRUE; |