diff --git a/ReleaseHistory.md b/ReleaseHistory.md index fb7b47bb..ccbcec2f 100644 --- a/ReleaseHistory.md +++ b/ReleaseHistory.md @@ -16,6 +16,7 @@ - NEW => new feature ## UNRELEASED +* BUG: Fix `TryGetPortablePdbMetadataReader` unexpectedly causes `UnauthorizedAccessException` error when the PDB file is missing. [1001](https://github.com/microsoft/binskim/pull/1001). ## **v4.3.0** * DEP: Update `msdia140.dll` from 14.36.32532.0 to 14.40.33810.0. This update fixes the `System.AccessViolationException: Attempted to read or write protected memory` exception that occurs when reading certain PDB files. [996](https://github.com/microsoft/binskim/pull/996) diff --git a/src/BinaryParsers/PEBinary/PortableExecutable/PE.cs b/src/BinaryParsers/PEBinary/PortableExecutable/PE.cs index d02e7d78..a1aa5d68 100644 --- a/src/BinaryParsers/PEBinary/PortableExecutable/PE.cs +++ b/src/BinaryParsers/PEBinary/PortableExecutable/PE.cs @@ -868,7 +868,11 @@ private bool TryGetPortablePdbMetadataReader(Pdb pdb, out MetadataReader pdbMeta out MetadataReaderProvider pdbProvider, out _)) { - pdbProvider = MetadataReaderProvider.FromPortablePdbStream(File.OpenRead(pdb.PdbLocation)); + if (File.Exists(pdb.PdbLocation)) + { + pdbProvider = MetadataReaderProvider.FromPortablePdbStream(File.OpenRead(pdb.PdbLocation)); + } + if (pdbProvider == null) { pdbMetadataReader = null; diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Expected/Native_x86_VS2022_PdbRandomlyMissing.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Expected/Native_x86_VS2022_PdbRandomlyMissing.dll.sarif new file mode 100644 index 00000000..f040db6a --- /dev/null +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Expected/Native_x86_VS2022_PdbRandomlyMissing.dll.sarif @@ -0,0 +1,328 @@ +{ + "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.6.json", + "version": "2.1.0", + "runs": [ + { + "results": [ + { + "ruleId": "BA2004", + "ruleIndex": 0, + "message": { + "id": "Error_Managed", + "arguments": [ + "Native_x86_VS2022_PdbRandomlyMissing.dll", + "Unknown" + ] + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + } + } + } + ] + }, + { + "ruleId": "BA2005", + "ruleIndex": 1, + "kind": "pass", + "level": "none", + "message": { + "id": "Pass", + "arguments": [ + "Native_x86_VS2022_PdbRandomlyMissing.dll" + ] + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + } + } + } + ] + }, + { + "ruleId": "BA2009", + "ruleIndex": 2, + "kind": "pass", + "level": "none", + "message": { + "id": "Pass", + "arguments": [ + "Native_x86_VS2022_PdbRandomlyMissing.dll" + ] + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + } + } + } + ] + }, + { + "ruleId": "BA2019", + "ruleIndex": 3, + "kind": "pass", + "level": "none", + "message": { + "id": "Pass", + "arguments": [ + "Native_x86_VS2022_PdbRandomlyMissing.dll" + ] + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + } + } + } + ] + }, + { + "ruleId": "BA2021", + "ruleIndex": 4, + "kind": "pass", + "level": "none", + "message": { + "id": "Pass", + "arguments": [ + "Native_x86_VS2022_PdbRandomlyMissing.dll" + ] + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + } + } + } + ] + }, + { + "ruleId": "BA2027", + "ruleIndex": 5, + "message": { + "id": "Warning", + "arguments": [ + "Native_x86_VS2022_PdbRandomlyMissing.dll" + ] + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + } + } + } + ] + } + ], + "tool": { + "driver": { + "name": "testhost", + "version": "15.0.0.0", + "rules": [ + { + "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", + "fullDescription": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code.\r\nThis information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs.\r\nThis validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure.\r\nLegacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files).\r\nUsing a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler.\r\nFor managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing.\r\nFor native code - use to MSVC 17.0 (14.30.*) or later if possible. For VC projects use PlatformToolset property with 'v143' or later value.\r\nWhen using older MSVC versions add /ZH:SHA_256 on cl.exe command line." + }, + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code.\r\nThis information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs.\r\nThis validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure.\r\nLegacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files).\r\nUsing a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler.\r\nFor managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing.\r\nFor native code - use to MSVC 17.0 (14.30.*) or later if possible. For VC projects use PlatformToolset property with 'v143' or later value.\r\nWhen using older MSVC versions add /ZH:SHA_256 on cl.exe command line." + }, + "messageStrings": { + "Pass": { + "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." + }, + "Warning_NativeWithInsecureStaticLibraryCompilands": { + "text": "'{0}' is a native binary that links one or more static libraries that include object files which were hashed using an insecure checksum algorithm.\r\nInsecure checksum algorithms are subject to collision attacks and its use can compromise supply chain integrity.\r\nTo resolve this issue, use newer versions of libraries that are compiled with /ZH:SHA_256. MSVC: 17.0 (14.30.*) or later. Windows SDK: 10.0.18362.0 or later.\r\nThe following modules are out of policy:\r\n{1}" + }, + "Error_Managed": { + "text": "'{0}' is a managed binary compiled with an insecure ({1}) source code hashing algorithm. {1} is subject to collision attacks and its use can compromise supply chain integrity. Pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the project property with 'SHA256' to enable secure source code hashing." + }, + "Error_NativeWithInsecureDirectCompilands": { + "text": "'{0}' is a native binary that directly compiles and links one or more object files which were hashed using an insecure checksum algorithm.\r\nInsecure checksum algorithms are subject to collision attacks and its use can compromise supply chain integrity.\r\nUse MSVC 17.0 (14.30.*) or later if possible.\r\nWhen using older MSVC versions, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing.\r\nThe following modules are out of policy:\r\n{1}" + }, + "NotApplicable_InvalidMetadata": { + "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." + } + }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing" + }, + { + "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", + "fullDescription": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, + "messageStrings": { + "Pass": { + "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." + }, + "Error": { + "text": "'{0}' appears to be an obsolete library (version {1}) for which there are known security vulnerabilities. \r\nTo resolve this issue, obtain a version of {0} that is newer than version {2}. If this binary is not in fact {0}, ignore this warning." + }, + "Error_CouldNotParseVersion": { + "text": "Version information for '{0}' could not be parsed. The binary therefore could not be verified not to be an obsolete binary that is known to be vulnerable to one or more security problems." + }, + "NotApplicable_InvalidMetadata": { + "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." + } + }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "properties": { + "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" + } + }, + { + "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", + "fullDescription": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, + "messageStrings": { + "Pass": { + "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." + }, + "Error_NotDynamicBase": { + "text": "'{0}' is not marked as DYNAMICBASE. This means that the binary is not eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities.\r\nTo resolve this issue, configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line.\r\nFor VC projects use ItemDefinitionGroup - Link - RandomizedBaseAddress property with 'true' value.\r\nFor .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, + "Error_RelocsStripped": { + "text": "'{0}' is marked as DYNAMICBASE but relocation data has been stripped from the image, preventing address space layout randomization. " + }, + "Error_WinCENoRelocationSection": { + "text": "'{0}' is a Windows CE image but does not contain any relocation data, preventing Address Space Layout Randomization." + }, + "NotApplicable_InvalidMetadata": { + "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." + } + }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "properties": { + "equivalentBinScopeRuleReadableName": "DBCheck" + } + }, + { + "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", + "fullDescription": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process.\r\nIf you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.).\r\nIf you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process.\r\nIf you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.).\r\nIf you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, + "messageStrings": { + "Pass": { + "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." + }, + "Error": { + "text": "'{0}' contains one or more code or data sections ({1}) which are marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process.\r\nIf you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.).\r\nIf you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, + "NotApplicable_InvalidMetadata": { + "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." + } + }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "properties": { + "equivalentBinScopeRuleReadableName": "SharedSectionCheck" + } + }, + { + "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", + "fullDescription": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode.\r\nTo resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes.\r\nBe sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode.\r\nTo resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes.\r\nBe sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, + "messageStrings": { + "Pass": { + "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." + }, + "Error": { + "text": "'{0}' contains PE section(s) ({1}) that are both writable and executable. Writable and executable memory segments make it easier for an attacker to exploit memory corruption vulnerabilities, because it may provide an attacker executable location(s) to inject shellcode.\r\nTo resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes.\r\nEnabling incremental linking via the /INCREMENTAL argument (the default for Microsoft Visual Studio debug build) can also result in a writable and executable section named 'textbss'. For this case, disable incremental linking (or analyze an alternate build configuration that disables this feature) to resolve the problem.\r\nFor VC projects use ItemDefinitionGroup - Link - LinkIncremental property with 'false' value." + }, + "Error_UnexpectedSectionAligment": { + "text": "'{0}' has a section alignment ({1}) that is smaller than its page size ({2})." + }, + "NotApplicable_InvalidMetadata": { + "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." + } + }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "properties": { + "equivalentBinScopeRuleReadableName": "WXCheck" + } + }, + { + "id": "BA2027", + "name": "EnableSourceLink", + "fullDescription": { + "text": "SourceLink information should be present in the PDB. This applies to binaries built with the C# and MSVC compilers. When enabled, SourceLink information is added to the PDB. That information includes the repository URLs and commit IDs for all source files fed to the compiler.\r\nThe PDB should also be uploaded to a symbol server so that it can be discovered by a debugger such as Visual Studio. Developers can then step into the matching source code. Frictionless source-driven debugging provides a good user experience for consumers and also accelerates security response in the event of supply-chain compromise.\r\nSee https://aka.ms/sourcelink for more information." + }, + "help": { + "text": "SourceLink information should be present in the PDB. This applies to binaries built with the C# and MSVC compilers. When enabled, SourceLink information is added to the PDB. That information includes the repository URLs and commit IDs for all source files fed to the compiler.\r\nThe PDB should also be uploaded to a symbol server so that it can be discovered by a debugger such as Visual Studio. Developers can then step into the matching source code. Frictionless source-driven debugging provides a good user experience for consumers and also accelerates security response in the event of supply-chain compromise.\r\nSee https://aka.ms/sourcelink for more information." + }, + "messageStrings": { + "Pass": { + "text": "The PDB for '{0}' contains SourceLink information, maximizing engineering and security response efficiency when source code is required for debugging and other critical analysis." + }, + "Warning": { + "text": "The PDB for '{0}' does not contain SourceLink information, compromising frictionless source-driven debugging and increasing latency of security response.\r\nEnable SourceLink by configuring necessary project properties and adding a package reference for your source control provider.\r\nSee https://aka.ms/sourcelink for more information." + } + }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2027EnableSourceLink" + } + ], + "properties": { + "comments": "A security and correctness analyzer for portable executable and MSIL formats." + } + } + }, + "invocations": [ + { + "executionSuccessful": true + } + ], + "artifacts": [ + { + "location": { + "uri": "file:///Z:/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll", + "index": 0 + }, + "hashes": { + "md5": "68A19DE304E6450EB2D2B4B65C7C47E3", + "sha-1": "13F06A8BCA79D5385AB59F1A5816211C96A52FDB", + "sha-256": "E349466D4205C2E9D0E94A2A0FCEE000DC082137BF6075F4E484870CDBFADF7D" + } + } + ], + "columnKind": "utf16CodeUnits" + } + ] +} \ No newline at end of file diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll new file mode 100644 index 00000000..4bb6d723 Binary files /dev/null and b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData/Native_x86_VS2022_PdbRandomlyMissing.dll differ