From: Andy Ayers Date: Tue, 3 Aug 2021 16:06:47 +0000 (-0700) Subject: Ensure MetadataEnumResult is sufficiently updated by MetaDataImport::Enum (#56756) X-Git-Tag: accepted/tizen/unified/20220110.054933~685 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=394e24f7045d0e1921bd352bda9027e343cc6b7c;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Ensure MetadataEnumResult is sufficiently updated by MetaDataImport::Enum (#56756) `MetadataEnumResult` has a fixed inline buffer for returning small results and a pointer to allow it to return larger ones. The indexer for this checks the pointer and if non-null assumes that's the current set of values. But if a `MetadataEnumResult` is re-used within a loop, values written to it by `MetaDataImport::Enum` may bleed from one loop iteration to the next if the iterations first get a large result and then a small one. One case where this could happen was in libraries PGO tests, where PGO data encouraged the jit to inline `MemberInfoCache.PopulateProperties(Filter,...)` into `MemberInfoCache.PopulateProperties(Filter)`. Note this also is a conseqeunce of skipping zero init locals; without that the struct would have been zeroed each loop iteration. Fixes #56655. --- diff --git a/src/coreclr/vm/managedmdimport.cpp b/src/coreclr/vm/managedmdimport.cpp index 6bea537..ec2aef0 100644 --- a/src/coreclr/vm/managedmdimport.cpp +++ b/src/coreclr/vm/managedmdimport.cpp @@ -163,6 +163,7 @@ static int * EnsureResultSize(MetadataEnumResult * pResult, ULONG length) else { ZeroMemory(pResult->smallResult, sizeof(pResult->smallResult)); + pResult->largeResult = NULL; p = pResult->smallResult; }