From 482eae052cb7f3542e637acd823373d67c372423 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Mon, 2 Aug 2021 17:29:58 -0700 Subject: [PATCH] Ensure MetadataEnumResult is sufficiently updated by MetaDataImport::Enum `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. --- src/coreclr/vm/managedmdimport.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/vm/managedmdimport.cpp b/src/coreclr/vm/managedmdimport.cpp index 6bea537f1c8e1..ec2aef0cc0398 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; }