From b1750b727eacd022599b7f7a1a96267cc8a4bb86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 23 Mar 2022 22:28:59 +0900 Subject: [PATCH] Reject mismatched symbol files (#67027) `UnmanagedPdbSymbolReader` will already perform a GUID check that rejects mismatched symbol files. Do the same for the portable symbol reader. --- .../Compiler/CompilerTypeSystemContext.cs | 42 +++++++++---------- .../SymbolReader/PortablePdbSymbolReader.cs | 9 +++- .../dotnet-pgo/TraceTypeSystemContext.cs | 36 ++++++++-------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs index 029949cda38..e903005084b 100644 --- a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs +++ b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs @@ -315,39 +315,39 @@ public MetadataStringDecoder GetMetadataStringDecoder() private PdbSymbolReader OpenAssociatedSymbolFile(string peFilePath, PEReader peReader) { - // Assume that the .pdb file is next to the binary - var pdbFilename = Path.ChangeExtension(peFilePath, ".pdb"); - string searchPath = ""; + string pdbFileName = null; + BlobContentId pdbContentId = default; - if (!File.Exists(pdbFilename)) + foreach (DebugDirectoryEntry debugEntry in peReader.ReadDebugDirectory()) { - pdbFilename = null; + if (debugEntry.Type != DebugDirectoryEntryType.CodeView) + continue; - // If the file doesn't exist, try the path specified in the CodeView section of the image - foreach (DebugDirectoryEntry debugEntry in peReader.ReadDebugDirectory()) + CodeViewDebugDirectoryData debugDirectoryData = peReader.ReadCodeViewDebugDirectoryData(debugEntry); + + string candidatePath = debugDirectoryData.Path; + if (!Path.IsPathRooted(candidatePath) || !File.Exists(candidatePath)) { - if (debugEntry.Type != DebugDirectoryEntryType.CodeView) + // Also check next to the PE file + candidatePath = Path.Combine(Path.GetDirectoryName(peFilePath), Path.GetFileName(candidatePath)); + if (!File.Exists(candidatePath)) continue; - - string candidateFileName = peReader.ReadCodeViewDebugDirectoryData(debugEntry).Path; - if (Path.IsPathRooted(candidateFileName) && File.Exists(candidateFileName)) - { - pdbFilename = candidateFileName; - searchPath = Path.GetDirectoryName(pdbFilename); - break; - } } - - if (pdbFilename == null) - return null; + + pdbFileName = candidatePath; + pdbContentId = new BlobContentId(debugDirectoryData.Guid, debugEntry.Stamp); + break; } + if (pdbFileName == null) + return null; + // Try to open the symbol file as portable pdb first - PdbSymbolReader reader = PortablePdbSymbolReader.TryOpen(pdbFilename, GetMetadataStringDecoder()); + PdbSymbolReader reader = PortablePdbSymbolReader.TryOpen(pdbFileName, GetMetadataStringDecoder(), pdbContentId); if (reader == null) { // Fallback to the diasymreader for non-portable pdbs - reader = UnmanagedPdbSymbolReader.TryOpenSymbolReaderForMetadataFile(peFilePath, searchPath); + reader = UnmanagedPdbSymbolReader.TryOpenSymbolReaderForMetadataFile(peFilePath, Path.GetDirectoryName(pdbFileName)); } return reader; diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs index b270b73ab8d..553f5a94fed 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs @@ -62,13 +62,20 @@ private static unsafe MetadataReader TryOpenMetadataFile(string filePath, Metada } } - public static PdbSymbolReader TryOpen(string pdbFilename, MetadataStringDecoder stringDecoder) + public static PdbSymbolReader TryOpen(string pdbFilename, MetadataStringDecoder stringDecoder, BlobContentId expectedContentId) { MemoryMappedViewAccessor mappedViewAccessor; MetadataReader reader = TryOpenMetadataFile(pdbFilename, stringDecoder, out mappedViewAccessor); if (reader == null) return null; + var foundContentId = new BlobContentId(reader.DebugMetadataHeader.Id); + if (foundContentId != expectedContentId) + { + mappedViewAccessor.Dispose(); + return null; + } + return new PortablePdbSymbolReader(reader, mappedViewAccessor); } diff --git a/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs b/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs index afdb148089b..6377988bbb2 100644 --- a/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs +++ b/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs @@ -356,33 +356,35 @@ private EcmaModule AddModule(string filePath, string expectedSimpleName, byte[] private PdbSymbolReader OpenAssociatedSymbolFile(string peFilePath, PEReader peReader) { - // Assume that the .pdb file is next to the binary - var pdbFilename = Path.ChangeExtension(peFilePath, ".pdb"); + string pdbFileName = null; + BlobContentId pdbContentId = default; - if (!File.Exists(pdbFilename)) + foreach (DebugDirectoryEntry debugEntry in peReader.ReadDebugDirectory()) { - pdbFilename = null; + if (debugEntry.Type != DebugDirectoryEntryType.CodeView) + continue; - // If the file doesn't exist, try the path specified in the CodeView section of the image - foreach (DebugDirectoryEntry debugEntry in peReader.ReadDebugDirectory()) + CodeViewDebugDirectoryData debugDirectoryData = peReader.ReadCodeViewDebugDirectoryData(debugEntry); + + string candidatePath = debugDirectoryData.Path; + if (!Path.IsPathRooted(candidatePath) || !File.Exists(candidatePath)) { - if (debugEntry.Type != DebugDirectoryEntryType.CodeView) + // Also check next to the PE file + candidatePath = Path.Combine(Path.GetDirectoryName(peFilePath), Path.GetFileName(candidatePath)); + if (!File.Exists(candidatePath)) continue; - - string candidateFileName = peReader.ReadCodeViewDebugDirectoryData(debugEntry).Path; - if (Path.IsPathRooted(candidateFileName) && File.Exists(candidateFileName)) - { - pdbFilename = candidateFileName; - break; - } } - if (pdbFilename == null) - return null; + pdbFileName = candidatePath; + pdbContentId = new BlobContentId(debugDirectoryData.Guid, debugEntry.Stamp); + break; } + if (pdbFileName == null) + return null; + // Try to open the symbol file as portable pdb first - PdbSymbolReader reader = PortablePdbSymbolReader.TryOpen(pdbFilename, GetMetadataStringDecoder()); + PdbSymbolReader reader = PortablePdbSymbolReader.TryOpen(pdbFileName, GetMetadataStringDecoder(), pdbContentId); return reader; } -- GitLab