Fix div-by-zero introduced in https://github.com/dotnet/runtime/pull/65926 (#66035)
authorEgor Bogatov <egorbo@gmail.com>
Wed, 2 Mar 2022 00:55:43 +0000 (03:55 +0300)
committerGitHub <noreply@github.com>
Wed, 2 Mar 2022 00:55:43 +0000 (16:55 -0800)
src/coreclr/vm/eehash.inl
src/coreclr/vm/util.hpp

index ba49b19..477df0d 100644 (file)
@@ -198,7 +198,7 @@ BOOL EEHashTableBase<KeyType, Helper, bDefaultCopyIsDeep>::Init(DWORD dwNumBucke
     m_pVolatileBucketTable->m_pBuckets++;
     m_pVolatileBucketTable->m_dwNumBuckets = dwNumBuckets;
 #ifdef TARGET_64BIT
-    m_pVolatileBucketTable->m_dwNumBucketsMul = GetFastModMultiplier(dwNumBuckets);
+    m_pVolatileBucketTable->m_dwNumBucketsMul = dwNumBuckets == 0 ? 0 : GetFastModMultiplier(dwNumBuckets);
 #endif
 
     m_Heap = pHeap;
@@ -786,7 +786,7 @@ BOOL EEHashTableBase<KeyType, Helper, bDefaultCopyIsDeep>::GrowHashTable()
     pNewBucketTable->m_pBuckets = pNewBuckets;
     pNewBucketTable->m_dwNumBuckets = dwNewNumBuckets;
 #ifdef TARGET_64BIT
-    pNewBucketTable->m_dwNumBucketsMul = GetFastModMultiplier(dwNewNumBuckets);
+    pNewBucketTable->m_dwNumBucketsMul = dwNewNumBuckets == 0 ? 0 : GetFastModMultiplier(dwNewNumBuckets);
 #endif
 
     // Add old table to the to free list. Note that the SyncClean thing will only
index a8aa775..9c08c52 100644 (file)
@@ -1017,7 +1017,10 @@ inline UINT64 GetFastModMultiplier(UINT32 divisor)
 
 inline UINT32 FastMod(UINT32 value, UINT32 divisor, UINT64 multiplier)
 {
-    return (UINT32)(((((multiplier * value) >> 32) + 1) * divisor) >> 32);
+    _ASSERTE(divisor <= INT_MAX);
+    UINT32 highbits = (UINT32)(((((multiplier * value) >> 32) + 1) * divisor) >> 32);
+    _ASSERTE(highbits == value % divisor);
+    return highbits;
 }
 #endif