Merge pull request #5482 from piotrpMSFT/piotrpMSFT/infra/outception

Prevent Stage0 Environment Variables from leaking into Stage2 during execution in MSBuild
This commit is contained in:
Piotr Puszkiewicz 2017-01-27 13:33:39 -08:00 committed by GitHub
commit e20fb33cb8
7 changed files with 152 additions and 1 deletions

View file

@ -11,7 +11,8 @@
<Target Name="Test"
Condition=" '$(CLIBUILD_SKIP_TESTS)' != 'true' "
DependsOnTargets="BuildTests;">
DependsOnTargets="EnsureStageSeparation;
BuildTests;">
<PropertyGroup>
<PathListSeparator>:</PathListSeparator>
@ -101,4 +102,9 @@
MsbuildArgs="%(TestPackageProject.MsbuildArgs) /p:SdkNuGetVersion=$(SdkNugetVersion)" />
</Target>
<Target Name="EnsureStageSeparation">
<DotNetMSBuild Arguments="/v:diag $(RepoRoot)/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage0.proj /p:Stage2Directory=&quot;$(Stage2Directory)&quot;"
ToolPath="$(Stage0Directory)" />
</Target>
</Project>

View file

@ -9,6 +9,7 @@
<UsingTask TaskName="Crossgen" AssemblyFile="$(CLIBuildDll)" />
<UsingTask TaskName="DotNetBuild" AssemblyFile="$(CLIBuildDll)" />
<UsingTask TaskName="DotNetBuildPJ" AssemblyFile="$(CLIBuildDll)" />
<UsingTask TaskName="DotNetMSBuild" AssemblyFile="$(CLIBuildDll)" />
<UsingTask TaskName="DotNetNew" AssemblyFile="$(CLIBuildDll)" />
<UsingTask TaskName="DotNetPack" AssemblyFile="$(CLIBuildDll)" />
<UsingTask TaskName="DotNetPublish" AssemblyFile="$(CLIBuildDll)" />

View file

@ -0,0 +1,9 @@
<Project DefaultTargets="RunValidation">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<Import Project="$(RepoRoot)/build/Microsoft.DotNet.Cli.tasks" />
<Target Name="RunValidation">
<DotNetMSBuild Arguments=" /v:diag $(MSBuildThisFileDirectory)/InvokeWithStage2.proj /p:ToolPath=&quot;$(Stage2Directory)&quot;"
ToolPath="$(Stage2Directory)" />
</Target>
</Project>

View file

@ -0,0 +1,29 @@
<Project DefaultTargets="RunValidation">
<PropertyGroup>
<NormalizedToolPath>$([System.IO.Path]::GetDirectoryName($(ToolPath)/))</NormalizedToolPath>
</PropertyGroup>
<PropertyGroup>
<MSBuildExtensionsPathInToolPath>false</MSBuildExtensionsPathInToolPath>
<MSBuildExtensionsPathInToolPath Condition="$(MSBuildExtensionsPath.StartsWith('$(NormalizedToolPath)'))">true</MSBuildExtensionsPathInToolPath>
<CscToolExeInToolPath>false</CscToolExeInToolPath>
<CscToolExeInToolPath Condition="$(CscToolExe.StartsWith('$(NormalizedToolPath)'))">true</CscToolExeInToolPath>
<MSBuildSDKsPathInToolPath>false</MSBuildSDKsPathInToolPath>
<MSBuildSDKsPathInToolPath Condition="$(MSBuildSDKsPath.StartsWith('$(NormalizedToolPath)'))">true</MSBuildSDKsPathInToolPath>
</PropertyGroup>
<Target Name="RunValidation">
<Error Condition=" '$(ToolPath)' == '' "
Text="ToolPath not set" />
<Error Condition=" '$(MSBuildExtensionsPathInToolPath)' == 'false' "
Text="MSBuildExtensionsPath '$(MSBuildExtensionsPath)' not in ToolPath '$(NormalizedToolPath)'" />
<Error Condition=" '$(CscToolExeInToolPath)' == 'false' "
Text="CscToolExe '$(CscToolExe)' not in ToolPath '$(NormalizedToolPath)'" />
<Error Condition=" '$(MSBuildSDKsPathInToolPath)' == 'false' "
Text="MSBuildSDKsPath '$(MSBuildSDKsPath)' not in ToolPath '$(NormalizedToolPath)'" />
</Target>
</Project>

View file

@ -0,0 +1,30 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.Cli.Build
{
public class DotNetMSBuild : DotNetTool
{
protected override string Command
{
get { return "msbuild"; }
}
protected override string Args
{
get { return $"{GetArguments()}"; }
}
public string Arguments { get; set; }
private string GetArguments()
{
if (!string.IsNullOrEmpty(Arguments))
{
return $"{Arguments}";
}
return null;
}
}
}

View file

@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Diagnostics;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
@ -18,6 +19,24 @@ namespace Microsoft.DotNet.Cli.Build
protected abstract string Args { get; }
protected override ProcessStartInfo GetProcessStartInfo(
string pathToTool,
string commandLineCommands,
string responseFileSwitch)
{
var psi = base.GetProcessStartInfo(
pathToTool,
commandLineCommands,
responseFileSwitch);
foreach (var environmentVariableName in new EnvironmentFilter().GetEnvironmentVariableNamesToRemove())
{
psi.Environment.Remove(environmentVariableName);
}
return psi;
}
public string WorkingDirectory { get; set; }
protected override string ToolName

View file

@ -0,0 +1,57 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.Cli.Build
{
public class EnvironmentFilter
{
private const string _MSBuildEnvironmentVariablePrefix = "MSBuild";
private const string _DotNetEnvironmentVariablePrefix = "DOTNET";
private const string _NugetEnvironmentVariablePrefix = "NUGET";
private IEnumerable<string> _prefixesOfEnvironmentVariablesToRemove = new string []
{
_MSBuildEnvironmentVariablePrefix,
_DotNetEnvironmentVariablePrefix,
_NugetEnvironmentVariablePrefix
};
private IEnumerable<string> _environmentVariablesToRemove = new string []
{
"CscToolExe"
};
private IEnumerable<string> _environmentVariablesToKeep = new string []
{
"DOTNET_CLI_TELEMETRY_SESSIONID",
"DOTNET_RUNTIME_ID",
"DOTNET_SKIP_FIRST_TIME_EXPERIENCE",
"NUGET_PACKAGES"
};
public IEnumerable<string> GetEnvironmentVariableNamesToRemove()
{
var allEnvironmentVariableNames = (IEnumerable<string>)Environment
.GetEnvironmentVariables()
.Keys
.Cast<string>();
var environmentVariablesToRemoveByPrefix = allEnvironmentVariableNames
.Where(e => _prefixesOfEnvironmentVariablesToRemove.Any(p => e.StartsWith(p)));
var environmentVariablesToRemoveByName = allEnvironmentVariableNames
.Where(e => _environmentVariablesToRemove.Contains(e));
var environmentVariablesToRemove = environmentVariablesToRemoveByName
.Concat(environmentVariablesToRemoveByPrefix)
.Distinct()
.Except(_environmentVariablesToKeep);
return environmentVariablesToRemove;
}
}
}