Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<MicrosoftExtensionsLoggingConsoleVersion>6.0.0</MicrosoftExtensionsLoggingConsoleVersion>
<!-- Need version that understands UseAppFilters sentinel. -->
<MicrosoftExtensionsLoggingEventSourceVersion>5.0.1</MicrosoftExtensionsLoggingEventSourceVersion>
<SystemCommandLineVersion>2.0.0-beta4.25072.1</SystemCommandLineVersion>
<SystemCommandLineVersion>2.0.0-beta4.25153.1</SystemCommandLineVersion>
<SystemComponentModelAnnotationsVersion>5.0.0</SystemComponentModelAnnotationsVersion>
<SystemBuffersVersion>4.5.1</SystemBuffersVersion>
<SystemDiagnosticsDiagnosticSourceVersion>8.0.1</SystemDiagnosticsDiagnosticSourceVersion>
Expand Down
31 changes: 5 additions & 26 deletions eng/pipelines/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ stages:
jobs:
- job: PrepareReleaseJob
displayName: Prepare Release
${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')) }}:
${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'))) }}:
templateContext:
outputs:
- output: pipelineArtifact
Expand All @@ -13,15 +13,15 @@ stages:
displayName: 'Publish Release Drop'
condition: succeeded()
variables:
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')) }}:
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'))) }}:
- group: DotNet-Diagnostics-Storage
- group: Release-Pipeline
steps:
- ${{ if in(variables['Build.Reason'], 'PullRequest') }}:
- script: '$(Build.Repository.LocalPath)\dotnet.cmd build $(Build.Repository.LocalPath)\eng\release\DiagnosticsReleaseTool\DiagnosticsReleaseTool.csproj -c Release /bl'
workingDirectory: '$(System.ArtifactsDirectory)'
displayName: 'Build Manifest generation and asset publishing tool'
- ${{ elseif and(ne(variables['System.TeamProject'], 'public'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')) }}:
- ${{ elseif and(ne(variables['System.TeamProject'], 'public'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'))) }}:
- task: UseDotNet@2
displayName: 'Use .NET Core runtime 8.x'
inputs:
Expand All @@ -30,40 +30,19 @@ stages:
installationPath: '$(Build.Repository.LocalPath)\.dotnet'
- template: /eng/common/templates/post-build/setup-maestro-vars.yml

# Populate dotnetbuilds-internal-container-read-token
- template: /eng/common/templates-official/steps/get-delegation-sas.yml
parameters:
federatedServiceConnection: 'dotnetbuilds-internal-read'
outputVariableName: 'dotnetbuilds-internal-checksums-container-read-token'
expiryInHours: 1
base64Encode: false
storageAccount: dotnetbuilds
container: internal-checksums
permissions: rl

# Populate dotnetbuilds-internal-container-read-token
- template: /eng/common/templates-official/steps/get-delegation-sas.yml
parameters:
federatedServiceConnection: 'dotnetbuilds-internal-read'
outputVariableName: 'dotnetbuilds-internal-container-read-token'
expiryInHours: 1
base64Encode: false
storageAccount: dotnetbuilds
container: internal
permissions: rl
- task: NuGetAuthenticate@1

- task: AzureCLI@2
displayName: 'DARC Gather build'
inputs:
azureSubscription: "Darc: Maestro Production"
azureSubscription: 'DotNetStaging'
scriptType: ps
scriptPath: '$(Build.Repository.LocalPath)/eng/release/Scripts/AcquireBuild.ps1'
arguments: >-
-BarBuildId "$(BARBuildId)"
-ReleaseVersion "$(Build.BuildNumber)"
-DownloadTargetPath "$(System.ArtifactsDirectory)\ReleaseTarget"
-AzdoToken "$(dn-bot-all-drop-rw-code-rw-release-all)"
-SasSuffixes "$(dotnetbuilds-internal-checksums-container-read-token),$(dotnetbuilds-internal-container-read-token)"
workingDirectory: '$(Build.Repository.LocalPath)'
- task: AzureCLI@2
displayName: 'Manifest generation and asset publishing'
Expand Down
8 changes: 3 additions & 5 deletions eng/release/Scripts/AcquireBuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ param(
[Parameter(Mandatory=$true)][int] $BarBuildId,
[Parameter(Mandatory=$true)][string] $ReleaseVersion,
[Parameter(Mandatory=$true)][string] $DownloadTargetPath,
[Parameter(Mandatory=$true)][string] $SasSuffixes,
[Parameter(Mandatory=$true)][string] $AzdoToken,
[Parameter(Mandatory=$false)][string] $DarcVersion = $null,
[switch] $help,
Expand All @@ -13,7 +12,6 @@ function Write-Help() {
Write-Host " -BarBuildId <value> BAR Build ID of the diagnostics build to publish."
Write-Host " -ReleaseVersion <value> Name to give the diagnostics release."
Write-Host " -DownloadTargetPath <value> Path to download the build to."
Write-Host " -SasSuffixes <value> Comma separated list of potential uri suffixes that can be used if anonymous access to a blob uri fails. Appended directly to the end of the URI. Use full SAS syntax with ?."
Write-Host " -AzdoToken <value> Azure DevOps token to use for builds queries"
Write-Host ""
}
Expand Down Expand Up @@ -48,11 +46,11 @@ try {
--release-name $ReleaseVersion `
--output-dir $DownloadTargetPath `
--overwrite `
--sas-suffixes $SasSuffixes `
--use-azure-credential-for-blobs `
--azdev-pat $AzdoToken `
--separated `
--ci `
--verbose
--continue-on-error `
--ci

if ($LastExitCode -ne 0) {
Write-Host "Error: unable to gather the assets from build $BarBuildId to $DownloadTargetPath using darc."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ public RuntimeProvider(IServiceProvider services)
/// <param name="flags">Enumeration control flags</param>
public IEnumerable<IRuntime> EnumerateRuntimes(int startingRuntimeId, RuntimeEnumerationFlags flags)
{
ISettingsService settingsService = _services.GetService<ISettingsService>();
// The ClrInfo and DataTarget instances are disposed when Runtime instance is disposed. Runtime instances are
// not flushed when the Target/RuntimeService is flushed; they are all disposed and the list cleared. They are
// all re-created the next time the IRuntime or ClrRuntime instance is queried.
DataTarget dataTarget = new(new CustomDataTarget(_services.GetService<IDataReader>())
{
ForceCompleteRuntimeEnumeration = (flags & RuntimeEnumerationFlags.All) != 0,
DacSignatureVerificationEnabled = settingsService is null || settingsService.DacSignatureVerificationEnabled,
FileLocator = null
});
for (int i = 0; i < dataTarget.ClrVersions.Length; i++)
Expand Down
19 changes: 19 additions & 0 deletions src/Microsoft.Diagnostics.DebugServices/ISettingsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;

namespace Microsoft.Diagnostics.DebugServices
{
/// <summary>
/// Settings service
/// </summary>
public interface ISettingsService
{
/// <summary>
/// If true, enforces the proper DAC certificate signing when loaded
/// </summary>
bool DacSignatureVerificationEnabled { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Microsoft.Diagnostics.DebugServices;
using Microsoft.Diagnostics.Runtime;

namespace Microsoft.Diagnostics.ExtensionCommands
{
public abstract class ClrRuntimeCommandBase : CommandBase
{
public const string RuntimeNotFoundMessage = "No CLR runtime found. This means that a .NET runtime module or the DAC for the runtime can not be found or downloaded.";
public const string RuntimeNotFoundMessage = $"No CLR runtime found.\nThis means that a .NET runtime module or the DAC for the runtime can not be found, loaded or downloaded.\nFor more information see https://go.microsoft.com/fwlink/?linkid=2135652";

[ServiceImport(Optional = true)]
public ClrRuntime Runtime { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public class RuntimesCommand : CommandBase
[ServiceImport]
public IContextService ContextService { get; set; }

[ServiceImport(Optional = true)]
public ISettingsService SettingsService { get; set; }

[ServiceImport]
public ITarget Target { get; set; }

Expand All @@ -33,14 +36,27 @@ public class RuntimesCommand : CommandBase
[Option(Name = "--all", Aliases = new string[] { "-a" }, Help = "Forces all runtimes to be enumerated.")]
public bool All { get; set; }

[Option(Name = "--DacSignatureVerification", Aliases = new string[] { "-v" }, Help = "Enforce the proper DAC certificate signing when loaded (true/false).")]
public bool? DacSignatureVerification { get; set; }

public override void Invoke()
{
if (NetFx && NetCore)
{
throw new DiagnosticsException("Cannot specify both -netfx and -netcore options");
}
RuntimeEnumerationFlags flags = RuntimeEnumerationFlags.Default;

if (DacSignatureVerification.HasValue)
{
if (SettingsService is null)
{
throw new DiagnosticsException("Changing the DAC signature verification setting not supported");
}
SettingsService.DacSignatureVerificationEnabled = DacSignatureVerification.Value;
Target.Flush();
}

RuntimeEnumerationFlags flags = RuntimeEnumerationFlags.Default;
if (All)
{
// Force all runtimes to be enumerated. This requires a target flush.
Expand Down Expand Up @@ -91,6 +107,7 @@ public override void Invoke()
}
this.DisplayResources(runtime.RuntimeModule, all: false, indent: " ");
this.DisplayRuntimeExports(runtime.RuntimeModule, error: true, indent: " ");
WriteLine($"DAC signature verification check enabled: {SettingsService.DacSignatureVerificationEnabled}");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ private static Task<Task> WriteStreamToOutput(StreamReader reader, ITestOutputHe
return Task.Factory.StartNew(async () => {
try
{
while (!reader.EndOfStream)
string line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) is not null)
{
string line = await reader.ReadLineAsync().ConfigureAwait(false);
output.WriteLine(line);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Microsoft.Diagnostics.TestHelpers
{
public class TestDump : TestHost
public class TestDump : TestHost, ISettingsService
{
private readonly Host _host;
private readonly ContextService _contextService;
Expand All @@ -26,6 +26,7 @@ public TestDump(TestConfiguration config)

_contextService = new(_host);
serviceContainer.AddService<IContextService>(_contextService);
serviceContainer.AddService<ISettingsService>(this);

_commandService = new();
serviceContainer.AddService<ICommandService>(_commandService);
Expand All @@ -52,5 +53,11 @@ protected override ITarget GetTarget()
_symbolService.AddDirectoryPath(Path.GetDirectoryName(DumpFile));
return _dumpTargetFactory.OpenDump(DumpFile);
}

#region ISettingsService

public bool DacSignatureVerificationEnabled { get; set; }

#endregion
}
}
14 changes: 14 additions & 0 deletions src/SOS/SOS.Extensions/DebuggerServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,19 @@ public void ExecuteHostCommand(string commandLine, ExecuteHostCommandCallback ou
}
}

public HResult GetDacSignatureVerificationSettings(out bool value)
{
value = false;
int dacSignatureVerificationEnabled = 0;
HResult hr = VTable.GetDacSignatureVerificationSettings(Self, &dacSignatureVerificationEnabled);
if (!hr.IsOK)
{
return hr;
}
value = dacSignatureVerificationEnabled != 0;
return HResult.S_OK;
}

[StructLayout(LayoutKind.Sequential)]
private readonly unsafe struct IDebuggerServicesVTable
{
Expand Down Expand Up @@ -553,6 +566,7 @@ private readonly unsafe struct IDebuggerServicesVTable
public readonly delegate* unmanaged[Stdcall]<IntPtr, out uint, out uint, out int, void*, int, uint*, byte*, int, uint*, int> GetLastEventInformation;
public readonly delegate* unmanaged[Stdcall]<IntPtr, void> FlushCheck;
public readonly delegate* unmanaged[Stdcall]<IntPtr, byte*, IntPtr, int> ExecuteHostCommand;
public readonly delegate* unmanaged[Stdcall]<IntPtr, int*, int> GetDacSignatureVerificationSettings;
}
}
}
25 changes: 24 additions & 1 deletion src/SOS/SOS.Extensions/HostServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace SOS.Extensions
/// <summary>
/// The extension services Wrapper the native hosts are given
/// </summary>
public sealed unsafe class HostServices : COMCallableIUnknown, SOSLibrary.ISOSModule
public sealed unsafe class HostServices : COMCallableIUnknown, SOSLibrary.ISOSModule, ISettingsService
{
private static readonly Guid IID_IHostServices = new("27B2CB8D-BDEE-4CBD-B6EF-75880D76D46F");

Expand Down Expand Up @@ -228,6 +228,7 @@ private int RegisterDebuggerServices(

// Add all the global services to the global service container
serviceContainer.AddService<SOSLibrary.ISOSModule>(this);
serviceContainer.AddService<ISettingsService>(this);
serviceContainer.AddService<SOSHost.INativeDebugger>(DebuggerServices);
serviceContainer.AddService<ICommandService>(_commandService);
serviceContainer.AddService<ISymbolService>(_symbolService);
Expand Down Expand Up @@ -413,6 +414,28 @@ private void Uninitialize(

#endregion

#region ISettingsService

public bool DacSignatureVerificationEnabled
{
get
{
HResult hr = DebuggerServices.GetDacSignatureVerificationSettings(out bool value);
if (hr.IsOK)
{
return value;
}
// Return true (verify DAC signature) if any errors. Secure by default.
return true;
}
set
{
throw new NotSupportedException("Changing the DacSignatureVerificationEnabled setting is not supported.");
}
}

#endregion

#region SOSLibrary.ISOSModule

public string SOSPath { get; }
Expand Down
28 changes: 24 additions & 4 deletions src/SOS/SOS.Hosting/RuntimeWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -471,14 +471,34 @@ private IntPtr GetDacHandle()
Trace.TraceError($"Could not find matching DAC {dacFilePath ?? ""} for this runtime: {_runtime.RuntimeModule.FileName}");
return IntPtr.Zero;
}
ISettingsService settingsService = _services.GetService<ISettingsService>();
IDisposable fileLock = null;
try
{
_dacHandle = DataTarget.PlatformFunctions.LoadLibrary(dacFilePath);
if (settingsService is null || settingsService.DacSignatureVerificationEnabled)
{
Trace.TraceInformation($"Verifying DAC signing and cert {dacFilePath}");

// Check if the DAC cert is valid before loading
if (!AuthenticodeUtil.VerifyDacDll(dacFilePath, out fileLock))
{
return IntPtr.Zero;
}
}
try
{
_dacHandle = DataTarget.PlatformFunctions.LoadLibrary(dacFilePath);
}
catch (Exception ex) when (ex is DllNotFoundException or BadImageFormatException)
{
Trace.TraceError($"LoadLibrary({dacFilePath}) FAILED {ex}");
return IntPtr.Zero;
}
}
catch (Exception ex) when (ex is DllNotFoundException or BadImageFormatException)
finally
{
Trace.TraceError($"LoadLibrary({dacFilePath}) FAILED {ex}");
return IntPtr.Zero;
// Keep DAC file locked until it loaded
fileLock?.Dispose();
}
Debug.Assert(_dacHandle != IntPtr.Zero);
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@
<RuntimeSymbolsPath>$(DotNetRoot)/shared/Microsoft.NETCore.App/$(RuntimeFrameworkVersion)</RuntimeSymbolsPath>
<LLDBHelperScript>$(ScriptRootDir)/lldbhelper.py</LLDBHelperScript>

<BuildType>servicing</BuildType>
<BuildType Condition="'$(RuntimeVersionLatest)' == '$(RuntimeFrameworkVersion)'">nightly</BuildType>
<BuildType Condition="'$(PrivateBuildTesting)' == 'true'">private</BuildType>

<!-- Single-file debuggees don't need the host -->
<SetHostExe Condition="'$(PublishSingleFile)' == 'true'">false</SetHostExe>
<SetFxVersion Condition="'$(PublishSingleFile)' == 'true'">false</SetFxVersion>
Expand Down
Loading
Loading