diff options
Diffstat (limited to 'src/vm/securitytransparentassembly.h')
-rw-r--r-- | src/vm/securitytransparentassembly.h | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/vm/securitytransparentassembly.h b/src/vm/securitytransparentassembly.h new file mode 100644 index 0000000000..9f0d38f7ca --- /dev/null +++ b/src/vm/securitytransparentassembly.h @@ -0,0 +1,249 @@ +// 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. +//-------------------------------------------------------------------------- +// securityTransparentAssembly.h +// +// Implementation for transparent code feature +// + + +//-------------------------------------------------------------------------- + + +#ifndef __SECURITYTRANSPARENT_H__ +#define __SECURITYTRANSPARENT_H__ + +#include "securitymeta.h" + +// Reason that a transparency error was flagged +enum SecurityTransparencyError +{ + SecurityTransparencyError_None, + SecurityTransparencyError_CallCriticalMethod, // A transparent method tried to call a critical method + SecurityTransparencyError_CallLinkDemand // A transparent method tried to call a method with a LinkDemand +}; + +namespace SecurityTransparent +{ +//private: + BOOL IsMethodTransparent(MethodDesc *pMD); + BOOL IsMethodCritical(MethodDesc *pMD); + BOOL IsMethodSafeCritical(MethodDesc *pMD); + BOOL IsTypeCritical(MethodTable *pMT); + BOOL IsTypeSafeCritical(MethodTable *pMT); + BOOL IsTypeTransparent(MethodTable *pMT); + BOOL IsTypeAllTransparent(MethodTable *pMT); + BOOL IsTypeAllCritical(MethodTable *pMT); + BOOL IsFieldTransparent(FieldDesc *pFD); + BOOL IsFieldCritical(FieldDesc *pFD); + BOOL IsFieldSafeCritical(FieldDesc *pFD); + BOOL IsTokenTransparent(Module *pModule, mdToken tkToken); + +//public: + bool SecurityCalloutQuickCheck(MethodDesc *pCallerMD); + + CorInfoIsAccessAllowedResult RequiresTransparentCodeChecks(MethodDesc* pCaller, + MethodDesc* pCallee, + SecurityTransparencyError *pError); + CorInfoIsAccessAllowedResult RequiresTransparentAssemblyChecks(MethodDesc* pCaller, + MethodDesc* pCallee, + SecurityTransparencyError *pError); + void EnforceTransparentAssemblyChecks(MethodDesc* pCaller, MethodDesc* pCallee); + void EnforceTransparentDelegateChecks(MethodTable* pDelegateMT, MethodDesc* pCallee); + CorInfoCanSkipVerificationResult JITCanSkipVerification(DomainAssembly * pAssembly); + CorInfoCanSkipVerificationResult JITCanSkipVerification(MethodDesc * pMD); + VOID PerformTransparencyChecksForLoadByteArray(MethodDesc* pCallersMD, AssemblySecurityDescriptor* pLoadedSecDesc); + BOOL CheckCriticalAccess(AccessCheckContext* pContext, + MethodDesc* pOptionalTargetMethod, + FieldDesc* pOptionalTargetField, + MethodTable * pOptionalTargetType); + BOOL IsAllowedToAssert(MethodDesc *pMD); + + bool TypeRequiresTransparencyCheck(TypeHandle type, bool checkForLinkDemands); + + void DECLSPEC_NORETURN ThrowMethodAccessException(MethodDesc* pMD, DWORD dwMessageId = IDS_CRITICAL_METHOD_ACCESS_DENIED); + + void DECLSPEC_NORETURN ThrowTypeLoadException(MethodDesc* pMD, DWORD dwMessageId = IDS_METHOD_INHERITANCE_RULES_VIOLATED); + void DECLSPEC_NORETURN ThrowTypeLoadException(MethodTable* pMT); + + void DoSecurityClassAccessChecks(MethodDesc *pCallerMD, + const TypeHandle &calleeTH, + CorInfoSecurityRuntimeChecks checks); +#ifdef _DEBUG + void LogTransparencyError(Assembly *pAssembly, const LPCSTR szError); + void LogTransparencyError(MethodTable *pMT, const LPCSTR szError); + void LogTransparencyError(MethodDesc *pMD, const LPCSTR szError, MethodDesc *pTargetMD = NULL); +#endif // _DEBUG +}; + +// +// Transparency is implemented slightly differently between v2 desktop, v4 desktop, and CoreCLR. In order to +// support running v2 desktop assemblies on the v4 CLR without modifying their expected transparency behavior, +// we indirect all questions about what transparency means through a SecurityTransparencyBehavior object. +// +// The SecurityTransparencyBehavior object uses implementations of ISecurityTransparencyImpl to query about +// specific behavior differences. +// + +enum SecurityTransparencyBehaviorFlags +{ + SecurityTransparencyBehaviorFlags_None = 0x0000, + + // Custom attributes require transparency checks in order to be used by transparent code + SecurityTransparencyBehaviorFlags_AttributesRequireTransparencyCheck = 0x0001, + + // Public critical members of an assembly can behave as if they were safe critical with a LinkDemand + // for FullTrust + SecurityTransparencyBehaviorFlags_CriticalMembersConvertToLinkDemand = 0x0002, + + // Types and methods must obey the transparency inheritance rules + SecurityTransparencyBehaviorFlags_InheritanceRulesEnforced = 0x0004, + + // Members contained within a scope that introduces members as critical may add their own treat as safe + SecurityTransparencyBehaviorFlags_IntroducedCriticalsMayAddTreatAsSafe = 0x0008, + + // Opportunistically critical assemblies consist of entirely transparent types with entirely safe + // critical methods. + SecurityTransparencyBehaviorFlags_OpportunisticIsSafeCriticalMethods = 0x0010, + + // Assemblies loaded in partial trust are implicitly all transparent + SecurityTransparencyBehaviorFlags_PartialTrustImpliesAllTransparent = 0x0020, + + // All public critical types and methods get an implicit treat as safe marking + SecurityTransparencyBehaviorFlags_PublicImpliesTreatAsSafe = 0x0040, + + // Security critical or safe critical at a larger than method scope applies only to methods introduced + // within that scope, rather than all methods contained in the scope + SecurityTransparencyBehaviorFlags_ScopeAppliesOnlyToIntroducedMethods = 0x0080, + + // Security transparent code can call methods protected with a LinkDemand + SecurityTransparencyBehaviorFlags_TransparentCodeCanCallLinkDemand = 0x0100, + + // Security transparent code can call native code via P/Invoke or COM Interop + SecurityTransaprencyBehaviorFlags_TransparentCodeCanCallUnmanagedCode = 0x0200, + + // Security transparent code can skip verification with a runtime check + SecurityTransparencyBehaviorFlags_TransparentCodeCanSkipVerification = 0x0400, + + // Unsigned assemblies implicitly are APTCA + SecurityTransparencyBehaviorFlags_UnsignedImpliesAPTCA = 0x0800, +}; + +inline SecurityTransparencyBehaviorFlags operator|(SecurityTransparencyBehaviorFlags lhs, + SecurityTransparencyBehaviorFlags rhs); + +inline SecurityTransparencyBehaviorFlags operator|=(SecurityTransparencyBehaviorFlags& lhs, + SecurityTransparencyBehaviorFlags rhs); + +inline SecurityTransparencyBehaviorFlags operator&(SecurityTransparencyBehaviorFlags lhs, + SecurityTransparencyBehaviorFlags rhs); + +inline SecurityTransparencyBehaviorFlags operator&=(SecurityTransparencyBehaviorFlags &lhs, + SecurityTransparencyBehaviorFlags rhs); + +// Base interface for transparency behavior implementations +class ISecurityTransparencyImpl +{ +public: + virtual ~ISecurityTransparencyImpl() + { + LIMITED_METHOD_CONTRACT; + } + + // Get flags that indicate specific on/off behaviors of transparency + virtual SecurityTransparencyBehaviorFlags GetBehaviorFlags() const = 0; + + // Map security attributes that a field contains to the set of behaviors it supports + virtual FieldSecurityDescriptorFlags MapFieldAttributes(TokenSecurityDescriptorFlags tokenFlags) const = 0; + + // Map security attributes that a method contains to the set of behaviors it supports + virtual MethodSecurityDescriptorFlags MapMethodAttributes(TokenSecurityDescriptorFlags tokenFlags) const = 0; + + // Map security attributes that a module contains to the set of behaviors it supports + virtual ModuleSecurityDescriptorFlags MapModuleAttributes(TokenSecurityDescriptorFlags tokenFlags) const = 0; + + // Map security attributes that a type contains to the set of behaviors it supports + virtual TypeSecurityDescriptorFlags MapTypeAttributes(TokenSecurityDescriptorFlags tokenFlags) const = 0; +}; + +class SecurityTransparencyBehavior +{ +public: + // Get a transparency behavior for a module with the given attributes applied to it + static + const SecurityTransparencyBehavior *GetTransparencyBehavior(SecurityRuleSet ruleSet); + +public: + // Are types and methods required to obey the transparency inheritance rules + inline bool AreInheritanceRulesEnforced() const; + + // Can public critical members of an assembly behave as if they were safe critical with a LinkDemand + // for FullTrust + inline bool CanCriticalMembersBeConvertedToLinkDemand() const; + + // Can members contained within a scope that introduces members as critical add their own TreatAsSafe + // attribute + inline bool CanIntroducedCriticalMembersAddTreatAsSafe() const; + + // Can transparent methods call methods protected with a LinkDemand + inline bool CanTransparentCodeCallLinkDemandMethods() const; + + // Can transparent methods call native code + inline bool CanTransparentCodeCallUnmanagedCode() const; + + // Can transparent members skip verification if the callstack passes a runtime check + inline bool CanTransparentCodeSkipVerification() const; + + // Custom attributes require transparency checks in order to be used by transparent code + inline bool DoAttributesRequireTransparencyChecks() const; + + // Opportunistically critical assemblies consist of entirely transparent types with entirely safe + // critical methods. + inline bool DoesOpportunisticRequireOnlySafeCriticalMethods() const; + + // Does being loaded in partial trust imply that the assembly is implicitly all transparent + inline bool DoesPartialTrustImplyAllTransparent() const; + + // Do all public members of the assembly get an implicit treat as safe marking + inline bool DoesPublicImplyTreatAsSafe() const; + + // Do security critical or safe critical at a larger than method scope apply only to methods introduced + // within that scope, or to all methods conateind within the scope. + inline bool DoesScopeApplyOnlyToIntroducedMethods() const; + + // Do unsigned assemblies implicitly become APTCA + inline bool DoesUnsignedImplyAPTCA() const; + + // Get flags that indicate specific on/off behaviors of transparency + inline FieldSecurityDescriptorFlags MapFieldAttributes(TokenSecurityDescriptorFlags tokenFlags) const; + + // Map security attributes that a method contains to the set of behaviors it supports + inline MethodSecurityDescriptorFlags MapMethodAttributes(TokenSecurityDescriptorFlags tokenFlags) const; + + // Map security attributes that a module contains to the set of behaviors it supports + inline ModuleSecurityDescriptorFlags MapModuleAttributes(TokenSecurityDescriptorFlags tokenFlags) const; + + // Map security attributes that a type contains to the set of behaviors it supports + inline TypeSecurityDescriptorFlags MapTypeAttributes(TokenSecurityDescriptorFlags tokenFlags) const; + +private: + explicit inline SecurityTransparencyBehavior(ISecurityTransparencyImpl *pTransparencyImpl); + SecurityTransparencyBehavior(const SecurityTransparencyBehavior &); // not implemented + SecurityTransparencyBehavior &operator=(const SecurityTransparencyBehavior &); // not implemented + +private: + template <class T> + friend const SecurityTransparencyBehavior *GetOrCreateTransparencyBehavior(SecurityTransparencyBehavior **ppBehavior); + +private: + static SecurityTransparencyBehavior *s_pStandardTransparencyBehavior; + static SecurityTransparencyBehavior *s_pLegacyTransparencyBehavior; + + ISecurityTransparencyImpl *m_pTransparencyImpl; + SecurityTransparencyBehaviorFlags m_flags; +}; + +#include "securitytransparentassembly.inl" + +#endif // __SECURITYTRANSPARENT_H__ |