Skip to content

Restrict DAC/DBI download to verifiable cases#5922

Open
hoyosjs wants to merge 4 commits into
dotnet:mainfrom
hoyosjs:juhoyosa/dbi-check
Open

Restrict DAC/DBI download to verifiable cases#5922
hoyosjs wants to merge 4 commits into
dotnet:mainfrom
hoyosjs:juhoyosa/dbi-check

Conversation

@hoyosjs

@hoyosjs hoyosjs commented Jul 12, 2026

Copy link
Copy Markdown
Member

The policy for acquiring the debugging libraries (DAC and DBI) from a symbol server has changed to reflect SDL requirements. The governing rule is:

A tool never downloads a DAC/DBI binary that cannot be verified by a tool before that binary is loaded.

Because authenticode verification is a Windows-only capability, this means:

  • DAC/DBI are only downloaded from a symbol server on a Windows host and only when DAC signature verification is enabled (so every downloaded binary is verified before load).
  • On Linux/macOS, and on Windows when verification is disabled, DAC/DBI are not downloaded; they must be provided locally from the matching runtime (collocated) or via the SOS setclrpath <directory> command.
  • dotnet-symbol never downloads native ELF/Mach-O DAC/DBI; it only downloads the Windows DAC and the Windows-host cross-OS DAC/DBI which are verifiable by debuggers.

Defaults (unchanged)

  • dotnet-dump analyze: DAC signature verification defaults to on for Windows, off for non-Windows; it can be toggled with runtimes --DacSignatureVerification <true|false>.
  • SOS hosted in a native debugger (WinDbg/cdb/lldb): the setting comes from the debugger and is secure-by-default (on); it cannot be changed through the SOS runtimes command.
  • When verification is on, it applies to both local and downloaded DAC/DBI.

Behavior changes

SOS / dotnet-dump / SOS-in-debugger

  1. Linux/macOS no longer download DAC/DBI. Previously, a Linux/macOS dump analyzed on a machine that did not have the matching runtime installed (with a symbol server configured) would auto-download the native DAC/DBI. Now nothing is downloaded on non-Windows; the DAC/DBI must be collocated (matching runtime installed) or supplied with setclrpath.

  2. Windows with verification disabled no longer downloads. In dotnet-dump, running runtimes --DacSignatureVerification false and relying on symbol-server download previously downloaded and loaded the DAC/DBI unverified. Now disabling verification also disables download; the DAC/DBI must be supplied with setclrpath.

  3. DBI is now signature-verified by default.

  4. Downloaded implies verified. Any DAC/DBI obtained from a symbol server is now guaranteed to be verified before it is loaded, because download is only permitted when verification is on.

dotnet-symbol

  1. Native ELF/Mach-O DAC/DBI/SOS are never downloaded. Previously dotnet-symbol --debugging <Linux/macOS dump/libcoreclr> (and the implicit dump default) downloaded the native libmscordaccore.so/libmscordbi.so/libsos.so plus the cross-OS .dll. Now only PE images are downloaded as the only verifiable assets by the tools.

  2. Warning on non-Windows --debugging. dotnet-symbol --debugging on Linux/macOS now prints a warning that native DAC/DBI are not downloaded (obtain them from the runtime or setclrpath).

Workflows supported after this change

To debug a dump on a machine without the matching runtime (any OS), obtain the matching runtime from the relevant official source and run setclrpath <directory> pointing at a directory that contains the matching DAC/DBI (for example the runtime's shared framework directory), then retry. Alternatively, copy them from the matching runtime install when eggressing the dump. To load a locally-provided, non-trusted-signed DAC (for example a preview/daily build), use setclrpath together with runtimes --DacSignatureVerification false (this disables verification for the local DAC and, by design, also prevents any download).

- SOS: only download the DAC/DBI from a symbol server on a Windows host
  when DAC signature verification is enabled. Otherwise the matching
  DAC/DBI must be provided locally (collocated runtime or 'setclrpath').
  GetLibraryPath now takes an allowDownload argument; the cDAC continues
  to never download.
- SOS: verify the DBI signature on load like the DAC. DAC, DBI and cDAC
  now load through a shared VerifyAndLoadLibrary helper; DAC/DBI
  verification is driven by the single DacSignatureVerificationEnabled
  setting, and the cDAC loads without verification.
- IRuntime.GetDbiFilePath now returns whether the DBI requires signature
  verification, matching GetDacFilePath.
- dotnet-symbol: add KeyTypeFlags.WindowsDebuggingLibrariesOnly and apply
  it whenever DAC/DBI keys are requested, so only the Windows and
  Windows-hosted cross-OS (PE) debugging libraries are staged and native
  ELF/Mach-O DAC/DBI are not. Warn on non-Windows --debugging.
Copilot AI review requested due to automatic review settings July 12, 2026 10:12
@hoyosjs hoyosjs requested a review from a team as a code owner July 12, 2026 10:12
@hoyosjs hoyosjs force-pushed the juhoyosa/dbi-check branch from 5961ccf to b9a5ed6 Compare July 12, 2026 10:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates debugging-library acquisition to satisfy SDL requirements by ensuring symbol-server downloads only occur when the resulting DAC/DBI can be verified before load (Windows + signature verification enabled), and by preventing enumeration/download of non-verifiable native (ELF/Mach-O) DAC/DBI via dotnet-symbol.

Changes:

  • dotnet-symbol: warns on non-Windows --debugging and restricts generated DAC/DBI/SOS special-file keys to PE (.dll) images only.
  • DebugServices/SOS hosting: DBI now participates in the same signature-verification + load flow as DAC (including file-locking across verify/load).
  • DebugServices runtime library resolution: download is gated behind “Windows host + signature verification enabled”, with user guidance when libraries can’t be found/downloaded.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Tools/dotnet-symbol/Program.cs Adds non-Windows --debugging warning; forces PE-only debugging-library key enumeration.
src/Microsoft.SymbolStore/KeyGenerators/KeyGenerator.cs Introduces WindowsDebuggingLibrariesOnly flag (PE-only special-file key filtering).
src/Microsoft.SymbolStore/KeyGenerators/ELFFileKeyGenerator.cs Filters ELF special-file DAC/DBI enumeration to PE-only when requested.
src/Microsoft.SymbolStore/KeyGenerators/MachOKeyGenerator.cs Filters Mach-O special-file DAC/DBI enumeration to PE-only when requested.
src/tests/Microsoft.SymbolStore.UnitTests/KeyGeneratorTests.cs Adds coverage for PE-only DAC/DBI key generation (but currently not for the active Mach-O test path).
src/Microsoft.Diagnostics.DebugServices/IRuntime.cs Changes DBI path API to return whether signature verification is required.
src/Microsoft.Diagnostics.DebugServices.Implementation/Runtime.cs Gates download by “Windows + verification enabled”; adds user-facing guidance when download isn’t permitted; includes DBI verification state in ToString().
src/SOS/SOS.Hosting/RuntimeWrapper.cs Adds signature verification + TOCTOU-safe load path for DBI (similar to DAC).
src/tests/DbgShim.UnitTests/DbgShimTests.cs Updates call sites for new DBI API signature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +268 to +272
// There is no Windows-hosted cross-OS DAC/DBI for macOS, so WindowsDebuggingLibrariesOnly
// excludes the native Mach-O DAC/DBI images and produces no DAC/DBI keys.
Dictionary<string, SymbolStoreKey> peDacDbiKeys = generator.GetKeys(KeyTypeFlags.DacDbiKeys | KeyTypeFlags.WindowsDebuggingLibrariesOnly).ToDictionary((key) => key.Index);
Assert.False(peDacDbiKeys.ContainsKey("libmscordaccore.dylib/mach-uuid-coreclr-3e0f66c5527338b18141e9d63b8ab415/libmscordaccore.dylib"));
Assert.False(peDacDbiKeys.ContainsKey("libmscordbi.dylib/mach-uuid-coreclr-3e0f66c5527338b18141e9d63b8ab415/libmscordbi.dylib"));
Comment on lines +70 to +75
/// <summary>
/// When combined with <see cref="ClrKeys"/> or <see cref="DacDbiKeys"/>, restricts the
/// generated DAC/DBI/SOS special-file keys to Windows (PE) images only: the native Windows
/// DAC/DBI and the Windows-hosted cross-OS DAC/DBI. This is a defense in depth measure
/// to ensure we only enumerate files we can authenticate when that are intended to run.
/// </summary>
@hoyosjs hoyosjs added DO NOT MERGE do not merge this PR breaking change labels Jul 12, 2026
hoyosjs added 2 commits July 12, 2026 19:38
Downloading a DAC/DBI from the symbol server is gated only on the host
being Windows, not on DacSignatureVerificationEnabled. Whether the
resulting DAC is verified before load is governed separately by that
setting (ClrMD's VerifyDacOnWindows and the SOS-hosting load path).

This decouples acquisition from verification so a DAC can be downloaded
and then loaded with verification disabled, matching the prior behavior
on Windows. Non-Windows hosts still do not download (they cannot verify
or load a foreign-format DAC); local symbol stores remain always allowed.

Also revert the test host enabling DAC signature verification, so the
DebugServices dump tests continue to load downloaded DACs without the
ClrMD DAC-EKU signature check.
… DACs locally

Restrict remote symbol-server download of the DAC/DBI to the case where the
downloaded binary will be authenticode-verified before it is loaded and run:
RemoteDownloadAllowed requires a Windows host and DacSignatureVerificationEnabled.
When download is not allowed the matching DAC/DBI must be provided from a trusted
local source (setclrpath / collocated runtime); local symbol stores remain allowed.

Adjust the tests to supply DACs locally where the policy no longer downloads them:
- SOS single-file tests: point SOS at the runtime directory (setclrpath) so the
  DAC/DBI resolve locally instead of downloading from the symbol server. Re-enables
  the block previously disabled by dotnet#3265.
- DebugServices RuntimeTests: these analyze 5.0/6.0 dumps whose DAC is not installed
  locally and whose downloaded DAC fails ClrMD's DAC-EKU signature check, so skip when
  the runtime cannot be created rather than failing.

This isolates the strict download policy so it can be reviewed and reverted
independently if the team prefers a different acquisition policy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants