summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Mandaleeka <adityam@microsoft.com>2017-04-17 15:51:58 -0700
committerAditya Mandaleeka <adityam@microsoft.com>2017-04-17 15:51:58 -0700
commit0bd13a2f510848cbc1ded26638f6c91a4caa39ff (patch)
tree068ff3c094f728fa13e43b41a9cc191aa51ebac7
parent80ca6807369ff9fa468099a936072a121215d3dc (diff)
downloadcoreclr-0bd13a2f510848cbc1ded26638f6c91a4caa39ff.tar.gz
coreclr-0bd13a2f510848cbc1ded26638f6c91a4caa39ff.tar.bz2
coreclr-0bd13a2f510848cbc1ded26638f6c91a4caa39ff.zip
Add handle assignment validation to VM side.
-rw-r--r--src/vm/gchandleutilities.h14
-rw-r--r--src/vm/gcheaputilities.cpp31
2 files changed, 36 insertions, 9 deletions
diff --git a/src/vm/gchandleutilities.h b/src/vm/gchandleutilities.h
index f6d2d0c48d..41b6317084 100644
--- a/src/vm/gchandleutilities.h
+++ b/src/vm/gchandleutilities.h
@@ -30,7 +30,8 @@ private:
GCHandleUtilities() = delete;
};
-void ValidateHandleAndAppDomain(OBJECTHANDLE handle);
+void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex);
+void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef);
// Given a handle, returns an OBJECTREF for the object it refers to.
inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
@@ -38,7 +39,10 @@ inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
_ASSERTE(handle);
#ifdef _DEBUG_IMPL
- ValidateHandleAndAppDomain(handle);
+ DWORD context = (DWORD)GCHandleUtilities::GetGCHandleManager()->GetHandleContext(handle);
+ OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
+
+ ValidateObjectAndAppDomain(objRef, ADIndex(context));
#endif // _DEBUG_IMPL
// Wrap the raw OBJECTREF and return it
@@ -173,16 +177,22 @@ inline OBJECTHANDLE CreateVariableHandle(IGCHandleStore* store, OBJECTREF object
inline void StoreObjectInHandle(OBJECTHANDLE handle, OBJECTREF object)
{
+ ValidateHandleAssignment(handle, object);
+
GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandle(handle, OBJECTREFToObject(object));
}
inline bool StoreFirstObjectInHandle(OBJECTHANDLE handle, OBJECTREF object)
{
+ ValidateHandleAssignment(handle, object);
+
return GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandleIfNull(handle, OBJECTREFToObject(object));
}
inline void* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, OBJECTREF object, OBJECTREF comparandObject)
{
+ ValidateHandleAssignment(handle, object);
+
return GCHandleUtilities::GetGCHandleManager()->CompareAndSwapObjectInHandle(handle, OBJECTREFToObject(object), OBJECTREFToObject(comparandObject));
}
diff --git a/src/vm/gcheaputilities.cpp b/src/vm/gcheaputilities.cpp
index 4bce7f5592..cd7afede70 100644
--- a/src/vm/gcheaputilities.cpp
+++ b/src/vm/gcheaputilities.cpp
@@ -40,17 +40,12 @@ bool g_sw_ww_enabled_for_gc_heap = false;
gc_alloc_context g_global_alloc_context = {};
// Debug-only validation for handle.
-void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
+
+void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex)
{
#ifdef _DEBUG_IMPL
- OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
VALIDATEOBJECTREF(objRef);
- IGCHandleManager *pHandleManager = GCHandleUtilities::GetGCHandleManager();
-
- DWORD context = (DWORD)pHandleManager->GetHandleContext(handle);
-
- ADIndex appDomainIndex = ADIndex(context);
AppDomain *domain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
// Access to a handle in an unloaded domain is not allowed
@@ -72,3 +67,25 @@ void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
#endif // CHECK_APP_DOMAIN_LEAKS
#endif // _DEBUG_IMPL
}
+
+void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef)
+{
+#ifdef _DEBUG_IMPL
+ _ASSERTE(handle);
+
+#ifdef DEBUG_DestroyedHandleValue
+ // Verify that we are not trying to access a freed handle.
+ _ASSERTE("Attempt to access destroyed handle." && *(_UNCHECKED_OBJECTREF*)handle != DEBUG_DestroyedHandleValue);
+#endif
+
+ ADIndex appDomainIndex = HndGetHandleADIndex(handle);
+
+ AppDomain *unloadingDomain = SystemDomain::AppDomainBeingUnloaded();
+ if (unloadingDomain && unloadingDomain->GetIndex() == appDomainIndex && unloadingDomain->NoAccessToHandleTable())
+ {
+ _ASSERTE (!"Access to a handle in unloaded domain is not allowed");
+ }
+
+ ValidateObjectAndAppDomain(objRef, appDomainIndex);
+#endif // _DEBUG_IMPL
+} \ No newline at end of file