From 4925d41bd9c183520afca00e1b787a403e791e3a Mon Sep 17 00:00:00 2001 From: Paul Higinbotham Date: Mon, 5 Aug 2019 13:27:49 -0700 Subject: [PATCH] Fix debugger disable performance regression (#10269) # Conflicts: # src/System.Management.Automation/engine/debugger/debugger.cs --- .../engine/debugger/debugger.cs | 22 ++- .../ConstrainedLanguageDebugger.Tests.ps1 | 187 +++--------------- 2 files changed, 47 insertions(+), 162 deletions(-) diff --git a/src/System.Management.Automation/engine/debugger/debugger.cs b/src/System.Management.Automation/engine/debugger/debugger.cs index f16352a8851b..02c70507e76b 100644 --- a/src/System.Management.Automation/engine/debugger/debugger.cs +++ b/src/System.Management.Automation/engine/debugger/debugger.cs @@ -1668,6 +1668,9 @@ internal void Clear() private volatile int _processingRunspaceDebugQueue; private ManualResetEventSlim _runspaceDebugCompleteEvent; + // System is locked down when true. Used to disable debugger on lock down. + private bool? _isSystemLockedDown; + private static readonly string s_processDebugPromptMatch; #endregion private members @@ -2073,16 +2076,27 @@ private bool CanEnableDebugger } } - private static bool IsSystemLockedDown + private bool IsSystemLockedDown { get { - return (System.Management.Automation.Security.SystemPolicy.GetSystemLockdownPolicy() == - System.Management.Automation.Security.SystemEnforcementMode.Enforce); + if (_isSystemLockedDown == null) + { + lock (_syncObject) + { + if (_isSystemLockedDown == null) + { + _isSystemLockedDown = (System.Management.Automation.Security.SystemPolicy.GetSystemLockdownPolicy() == + System.Management.Automation.Security.SystemEnforcementMode.Enforce); + } + } + } + + return _isSystemLockedDown.Value; } } - private static void CheckForBreakpointSupport() + private void CheckForBreakpointSupport() { if (IsSystemLockedDown) { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 index 04aaa8b3869e..0f038c6e8906 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/ConstrainedLanguageDebugger.Tests.ps1 @@ -22,85 +22,6 @@ try BeforeAll { - # Invoke-LanguageModeTestingSupportCmdlet definition - $languageModeCmdletDef = @' - using System; - using System.Globalization; - using System.Reflection; - using System.Collections; - using System.Collections.Generic; - using System.IO; - using System.Security; - using System.Runtime.InteropServices; - using System.Threading; - using System.Management.Automation; - - /// Adds a new type to the Application Domain - [Cmdlet("Invoke", "LanguageModeTestingSupportCmdlet")] - public sealed class InvokeLanguageModeTestingSupportCmdlet : PSCmdlet - { - [Parameter()] - public SwitchParameter EnableFullLanguageMode - { - get { return enableFullLanguageMode; } - set { enableFullLanguageMode = value; } - } - private SwitchParameter enableFullLanguageMode; - - [Parameter()] - public SwitchParameter SetLockdownMode - { - get { return setLockdownMode; } - set { setLockdownMode = value; } - } - private SwitchParameter setLockdownMode; - - [Parameter()] - public SwitchParameter RevertLockdownMode - { - get { return revertLockdownMode; } - set { revertLockdownMode = value; } - } - private SwitchParameter revertLockdownMode; - - protected override void BeginProcessing() - { - if(enableFullLanguageMode) - { - SessionState.LanguageMode = PSLanguageMode.FullLanguage; - } - - if(setLockdownMode) - { - Environment.SetEnvironmentVariable("__PSLockdownPolicy", "0x80000007", EnvironmentVariableTarget.Machine); - } - - if(revertLockdownMode) - { - Environment.SetEnvironmentVariable("__PSLockdownPolicy", null, EnvironmentVariableTarget.Machine); - } - } - } -'@ - - if (-not (Get-Command Invoke-LanguageModeTestingSupportCmdlet -ea Ignore)) - { - $languageModeModuleName = "LanguageModeModule" - $modulePath = [System.IO.Path]::GetFileNameWithoutExtension([IO.Path]::GetRandomFileName()) - $script:moduleDirectory = join-path "$PSScriptRoot\$modulePath" $languageModeModuleName - if (-not (Test-Path $moduleDirectory)) - { - $null = New-Item -ItemType Directory $moduleDirectory -Force - } - - try - { - Add-Type -TypeDefinition $languageModeCmdletDef -OutputAssembly $moduleDirectory\TestCmdletForConstrainedLanguage.dll -ErrorAction Ignore - } catch {} - - Import-Module -Name $moduleDirectory\TestCmdletForConstrainedLanguage.dll - } - # Debugger test type definition $debuggerTestTypeDef = @' using System; @@ -146,6 +67,26 @@ try # Define debugger test type Add-Type -TypeDefinition $debuggerTestTypeDef + + # Test cases + $TestCasesDisableDebugger = @( + @{ + testName = 'Verifies that Set-PSBreakpoint Line is disabled on locked down system' + scriptText = 'Set-PSBreakpoint -Script {0} -Line 1' -f $scriptFilePath + }, + @{ + testName = 'Verifies that Set-PSBreakpoint Statement is disabled on locked down system' + scriptText = 'Set-PSBreakpoint -Script {0} -Line 1 -Column 1' -f $scriptFilePath + }, + @{ + testName = 'Verifies that Set-PSBreakpoint Command is disabled on locked down system' + scriptText = 'Set-PSBreakpoint -Command {0}' -f $scriptFilePath + }, + @{ + testName = 'Verifies that Set-PSBreakpoint Variable is disabled on locked down system' + scriptText = 'Set-PSBreakpoint -Variable HelloVar' + } + ) } AfterAll { @@ -156,93 +97,23 @@ try } } - It "Verifies that Set-PSBreakpoint Line is disabled on locked down system" { + It "" -TestCases $TestCasesDisableDebugger { - try - { - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" + param ($scriptText) - Set-PSBreakpoint -Script $scriptFilePath -Line 1 - throw "No Exception!" - } - catch - { - $expectedError = $_ - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode - Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode - } - - $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' - } - - It "Verifies that Set-PSBreakpoint Statement is disabled on locked down system" { - - try - { - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - - Set-PSBreakpoint -Script $scriptFilePath -Line 1 -Column 1 - throw "No Exception!" - } - catch - { - $expectedError = $_ - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode - Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode - } - - $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' - } - - It "Verifies that Set-PSBreakpoint Command is disabled on locked down system" { - - try + try { Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - Set-PSBreakpoint -Command $scriptFilePath - throw "No Exception!" - } - catch - { - $expectedError = $_ + # Run script in new runspace created within lock down mode. + [powershell] $ps = [powershell]::Create([System.Management.Automation.RunspaceMode]::NewRunspace); + $ps.AddScript($scriptText).Invoke() + $expectedError = $ps.Streams.Error[0] } finally { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode - Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode - } - - $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand' - } - - It "Verifies that Set-PSBreakpoint Variable is disabled on locked down system" { - - try - { - Invoke-LanguageModeTestingSupportCmdlet -SetLockdownMode - $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" - - Set-PSBreakpoint -Variable HelloVar - throw "No Exception!" - } - catch - { - $expectedError = $_ - } - finally - { - Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode - Invoke-LanguageModeTestingSupportCmdlet -EnableFullLanguageMode + Invoke-LanguageModeTestingSupportCmdlet -RevertLockdownMode -EnableFullLanguageMode + if ($ps -ne $null) { $ps.Dispose() } } $expectedError.FullyQualifiedErrorId | Should Be 'NotSupported,Microsoft.PowerShell.Commands.SetPSBreakpointCommand'