/// <summary> /// Class constructor /// </summary> public PipExecutionState( IRootModuleConfiguration rootModuleConfiguration, PipTwoPhaseCache cache, FileAccessWhitelist fileAccessWhitelist, IDirectoryMembershipFingerprinter directoryMembershipFingerprinter, SemanticPathExpander pathExpander, IExecutionLogTarget executionLog, DirectoryMembershipFingerprinterRuleSet directoryMembershipFinterprinterRuleSet, FileContentManager fileContentManager, IUnsafeSandboxConfiguration unsafeConfiguration, ContentHash preserveOutputsSalt, FileSystemView fileSystemView, bool lazyDeletionOfSharedOpaqueOutputsEnabled, ServiceManager serviceManager = null) { Contract.Requires(fileContentManager != null); Contract.Requires(directoryMembershipFingerprinter != null); Contract.Requires(pathExpander != null); Cache = cache; m_fileAccessWhitelist = fileAccessWhitelist; DirectoryMembershipFingerprinter = directoryMembershipFingerprinter; ResourceManager = new ProcessResourceManager(); m_pathExpander = new FileContentManagerSemanticPathExpander(fileContentManager, pathExpander); ExecutionLog = executionLog; m_rootModuleConfiguration = rootModuleConfiguration; m_directoryMembershipFingerprinterRuleSet = directoryMembershipFinterprinterRuleSet; PathExistenceCache = new ConcurrentBigMap <AbsolutePath, PathExistence>(); FileContentManager = fileContentManager; ServiceManager = serviceManager ?? ServiceManager.Default; PipEnvironment = new PipEnvironment(); FileSystemView = fileSystemView; m_unsafeConfiguration = unsafeConfiguration; m_preserveOutputsSalt = preserveOutputsSalt; LazyDeletionOfSharedOpaqueOutputsEnabled = lazyDeletionOfSharedOpaqueOutputsEnabled; if (fileSystemView != null) { fileContentManager.SetLocalDiskFileSystemExistenceView(fileSystemView); } }
/// <nodoc /> public UnsafeSandboxConfiguration(IUnsafeSandboxConfiguration template) { MonitorFileAccesses = template.MonitorFileAccesses; MonitorNtCreateFile = template.MonitorNtCreateFile; MonitorZwCreateOpenQueryFile = template.MonitorZwCreateOpenQueryFile; UnexpectedFileAccessesAreErrors = template.UnexpectedFileAccessesAreErrors; IgnoreZwRenameFileInformation = template.IgnoreZwRenameFileInformation; IgnoreZwOtherFileInformation = template.IgnoreZwOtherFileInformation; IgnoreNonCreateFileReparsePoints = template.IgnoreNonCreateFileReparsePoints; IgnoreSetFileInformationByHandle = template.IgnoreSetFileInformationByHandle; IgnoreReparsePoints = template.IgnoreReparsePoints; IgnorePreloadedDlls = template.IgnorePreloadedDlls; SandboxKind = template.SandboxKind; ExistingDirectoryProbesAsEnumerations = template.ExistingDirectoryProbesAsEnumerations; PreserveOutputs = template.PreserveOutputs; PreserveOutputsTrustLevel = template.PreserveOutputsTrustLevel; IgnoreGetFinalPathNameByHandle = template.IgnoreGetFinalPathNameByHandle; IgnoreDynamicWritesOnAbsentProbes = template.IgnoreDynamicWritesOnAbsentProbes; DoubleWritePolicy = template.DoubleWritePolicy; IgnoreUndeclaredAccessesUnderSharedOpaques = template.IgnoreUndeclaredAccessesUnderSharedOpaques; }
/// <summary> /// Returns <code>true</code> if <paramref name="lhs"/> does not contain a single unsafe value that is not present in <paramref name="rhs"/>. /// </summary> public static bool IsAsSafeOrSaferThan(this IUnsafeSandboxConfiguration lhs, IUnsafeSandboxConfiguration rhs) { return(IsAsSafeOrSafer(lhs.DisableDetours(), rhs.DisableDetours(), SafeDefaults.DisableDetours()) && IsAsSafeOrSafer(lhs.ExistingDirectoryProbesAsEnumerations, rhs.ExistingDirectoryProbesAsEnumerations, SafeDefaults.ExistingDirectoryProbesAsEnumerations) && IsAsSafeOrSafer(lhs.IgnoreGetFinalPathNameByHandle, rhs.IgnoreGetFinalPathNameByHandle, SafeDefaults.IgnoreGetFinalPathNameByHandle) && IsAsSafeOrSafer(lhs.IgnoreNonCreateFileReparsePoints, rhs.IgnoreNonCreateFileReparsePoints, SafeDefaults.IgnoreNonCreateFileReparsePoints) && IsAsSafeOrSafer(lhs.IgnoreReparsePoints, rhs.IgnoreReparsePoints, SafeDefaults.IgnoreReparsePoints) && IsAsSafeOrSafer(lhs.IgnoreSetFileInformationByHandle, rhs.IgnoreSetFileInformationByHandle, SafeDefaults.IgnoreSetFileInformationByHandle) && IsAsSafeOrSafer(lhs.IgnoreZwOtherFileInformation, rhs.IgnoreZwOtherFileInformation, SafeDefaults.IgnoreZwOtherFileInformation) && IsAsSafeOrSafer(lhs.IgnoreZwRenameFileInformation, rhs.IgnoreZwRenameFileInformation, SafeDefaults.IgnoreZwRenameFileInformation) && IsAsSafeOrSafer(lhs.MonitorFileAccesses, rhs.MonitorFileAccesses, SafeDefaults.MonitorFileAccesses) && IsAsSafeOrSafer(lhs.MonitorNtCreateFile, rhs.MonitorNtCreateFile, SafeDefaults.MonitorNtCreateFile) && IsAsSafeOrSafer(lhs.MonitorZwCreateOpenQueryFile, rhs.MonitorZwCreateOpenQueryFile, SafeDefaults.MonitorZwCreateOpenQueryFile) && IsAsSafeOrSafer(lhs.UnexpectedFileAccessesAreErrors, rhs.UnexpectedFileAccessesAreErrors, SafeDefaults.UnexpectedFileAccessesAreErrors) // Where's PreserveOutputs? The sandbox configuration setting globally decides whether preserve outputs. // Whether the current run is as safe or safer also depends on whether preserve outputs is allowed for // the pip in question. Because that requires pip specific details, that is determined in UnsafeOptions && IsAsSafeOrSafer(lhs.IgnorePreloadedDlls, rhs.IgnorePreloadedDlls, SafeDefaults.IgnorePreloadedDlls) && IsAsSafeOrSafer(lhs.IgnoreDynamicWritesOnAbsentProbes, rhs.IgnoreDynamicWritesOnAbsentProbes, SafeDefaults.IgnoreDynamicWritesOnAbsentProbes) && IsAsSafeOrSafer(lhs.DoubleWritePolicy(), rhs.DoubleWritePolicy(), SafeDefaults.DoubleWritePolicy())); }
/// <nodoc /> public SandboxConfiguration() { m_unsafeSandboxConfig = new UnsafeSandboxConfiguration(); FailUnexpectedFileAccesses = true; DefaultTimeout = ((int)DefaultProcessTimeoutInMinutes) * 60 * 1000; DefaultWarningTimeout = (int)(.85 * DefaultTimeout); TimeoutMultiplier = 1; WarningTimeoutMultiplier = 1; OutputReportingMode = OutputReportingMode.TruncatedOutputOnError; FileSystemMode = FileSystemMode.Unset; ForceReadOnlyForRequestedReadWrite = false; FlushPageCacheToFileSystemOnStoringOutputsToCache = true; NormalizeReadTimestamps = true; UseLargeNtClosePreallocatedList = false; UseExtraThreadToDrainNtClose = true; MaskUntrackedAccesses = true; LogProcessDetouringStatus = false; HardExitOnErrorInDetours = true; CheckDetoursMessageCount = true; AllowInternalDetoursErrorNotificationFile = true; EnforceAccessPoliciesOnDirectoryCreation = false; MeasureProcessCpuTimes = true; // always measure process times + ram consumption KextReportQueueSizeMb = 0; // let the sandbox kernel extension apply defaults KextEnableReportBatching = true; // use lock-free queue for batching access reports KextThrottleCpuUsageBlockThresholdPercent = 0; // no throttling by default KextThrottleCpuUsageWakeupThresholdPercent = 0; // no throttling by default KextThrottleMinAvailableRamMB = 0; // no throttling by default ContainerConfiguration = new SandboxContainerConfiguration(); AdminRequiredProcessExecutionMode = AdminRequiredProcessExecutionMode.Internal; RedirectedTempFolderRootForVmExecution = AbsolutePath.Invalid; RetryOnAzureWatsonExitCode = false; EnsureTempDirectoriesExistenceBeforePipExecution = false; GlobalUnsafeUntrackedScopes = new List <AbsolutePath>(); PreserveOutputsForIncrementalTool = false; GlobalUnsafePassthroughEnvironmentVariables = new List <string>(); VmConcurrencyLimit = 0; DirectoriesToEnableFullReparsePointParsing = new List <AbsolutePath>(); ExplicitlyReportDirectoryProbes = false; }
/// <nodoc /> public SandboxConfiguration(ISandboxConfiguration template, PathRemapper pathRemapper) { Contract.Assume(template != null); m_unsafeSandboxConfig = new UnsafeSandboxConfiguration(template.UnsafeSandboxConfiguration); DebugInstantPipOutputs = template.DebugInstantPipOutputs; BreakOnUnexpectedFileAccess = template.BreakOnUnexpectedFileAccess; FileAccessIgnoreCodeCoverage = template.FileAccessIgnoreCodeCoverage; FailUnexpectedFileAccesses = template.FailUnexpectedFileAccesses; DefaultTimeout = template.DefaultTimeout; DefaultWarningTimeout = template.DefaultWarningTimeout; TimeoutMultiplier = template.TimeoutMultiplier; WarningTimeoutMultiplier = template.WarningTimeoutMultiplier; TimeoutDumpDirectory = pathRemapper.Remap(template.TimeoutDumpDirectory); LogObservedFileAccesses = template.LogObservedFileAccesses; LogProcesses = template.LogProcesses; LogProcessData = template.LogProcessData; LogFileAccessTables = template.LogFileAccessTables; OutputReportingMode = template.OutputReportingMode; FileSystemMode = template.FileSystemMode; ForceReadOnlyForRequestedReadWrite = template.ForceReadOnlyForRequestedReadWrite; FlushPageCacheToFileSystemOnStoringOutputsToCache = template.FlushPageCacheToFileSystemOnStoringOutputsToCache; NormalizeReadTimestamps = template.NormalizeReadTimestamps; UseLargeNtClosePreallocatedList = template.UseLargeNtClosePreallocatedList; UseExtraThreadToDrainNtClose = template.UseExtraThreadToDrainNtClose; MaskUntrackedAccesses = template.MaskUntrackedAccesses; LogProcessDetouringStatus = template.LogProcessDetouringStatus; HardExitOnErrorInDetours = template.HardExitOnErrorInDetours; CheckDetoursMessageCount = template.CheckDetoursMessageCount; AllowInternalDetoursErrorNotificationFile = template.AllowInternalDetoursErrorNotificationFile; EnforceAccessPoliciesOnDirectoryCreation = template.EnforceAccessPoliciesOnDirectoryCreation; KextMeasureProcessCpuTimes = template.KextMeasureProcessCpuTimes; KextReportQueueSizeMb = template.KextReportQueueSizeMb; KextEnableReportBatching = template.KextEnableReportBatching; KextThrottleCpuUsageBlockThresholdPercent = template.KextThrottleCpuUsageBlockThresholdPercent; KextThrottleCpuUsageWakeupThresholdPercent = template.KextThrottleCpuUsageWakeupThresholdPercent; KextThrottleMinAvailableRamMB = template.KextThrottleMinAvailableRamMB; ContainerConfiguration = new SandboxContainerConfiguration(template.ContainerConfiguration); AdminRequiredProcessExecutionMode = template.AdminRequiredProcessExecutionMode; }
/// <nodoc/> public static void Serialize(this IUnsafeSandboxConfiguration @this, BuildXLWriter writer) { writer.Write((byte)@this.SandboxKind); writer.Write(@this.ExistingDirectoryProbesAsEnumerations); writer.Write(@this.IgnoreGetFinalPathNameByHandle); writer.Write(@this.IgnoreNonCreateFileReparsePoints); writer.Write(@this.IgnoreReparsePoints); writer.Write(@this.IgnoreSetFileInformationByHandle); writer.Write(@this.IgnoreZwOtherFileInformation); writer.Write(@this.IgnoreZwRenameFileInformation); writer.Write(@this.MonitorFileAccesses); writer.Write(@this.MonitorNtCreateFile); writer.Write(@this.MonitorZwCreateOpenQueryFile); writer.Write((byte)@this.PreserveOutputs); writer.Write(@this.PreserveOutputsTrustLevel); writer.Write(@this.IgnorePreserveOutputsPrivatization); writer.Write(@this.UnexpectedFileAccessesAreErrors); writer.Write(@this.IgnorePreloadedDlls); writer.WriteCompact((int)@this.IgnoreDynamicWritesOnAbsentProbes); writer.Write(@this.DoubleWritePolicy.HasValue); if (@this.DoubleWritePolicy.HasValue) { writer.Write((byte)@this.DoubleWritePolicy.Value); } writer.Write(@this.IgnoreUndeclaredAccessesUnderSharedOpaques); writer.Write(@this.IgnoreCreateProcessReport); writer.Write(@this.ProbeDirectorySymlinkAsDirectory); writer.Write(@this.IgnoreFullReparsePointResolving); writer.Write(@this.SkipFlaggingSharedOpaqueOutputs.HasValue); if (@this.SkipFlaggingSharedOpaqueOutputs.HasValue) { writer.Write(@this.SkipFlaggingSharedOpaqueOutputs.Value); } writer.Write(@this.EnableFullReparsePointResolving.HasValue); if (@this.EnableFullReparsePointResolving.HasValue) { writer.Write(@this.EnableFullReparsePointResolving.Value); } }
/// <nodoc/> public static void Serialize(this IUnsafeSandboxConfiguration @this, BuildXLWriter writer) { writer.Write((byte)@this.SandboxKind); writer.Write(@this.ExistingDirectoryProbesAsEnumerations); writer.Write(@this.IgnoreGetFinalPathNameByHandle); writer.Write(@this.IgnoreNonCreateFileReparsePoints); writer.Write(@this.IgnoreReparsePoints); writer.Write(@this.IgnoreSetFileInformationByHandle); writer.Write(@this.IgnoreZwOtherFileInformation); writer.Write(@this.IgnoreZwRenameFileInformation); writer.Write(@this.MonitorFileAccesses); writer.Write(@this.MonitorNtCreateFile); writer.Write(@this.MonitorZwCreateOpenQueryFile); writer.Write((byte)@this.PreserveOutputs); writer.Write(@this.UnexpectedFileAccessesAreErrors); writer.Write(@this.IgnorePreloadedDlls); writer.Write(@this.IgnoreDynamicWritesOnAbsentProbes); writer.Write(@this.DoubleWritePolicy.HasValue); if (@this.DoubleWritePolicy.HasValue) { writer.Write((byte)@this.DoubleWritePolicy.Value); } }
/// <summary> /// Creates an instance of <see cref="UnsafeOptions"/>. /// </summary> /// <param name="unsafeConfiguration">The IUnsafeSandboxConfiguration for the pip</param> /// <param name="preserveOutputInfo">The preserveOutputsSalt to use when running the pip. NOTE: this should have /// the pip specific <see cref="BuildXL.Pips.Operations.Process.AllowPreserveOutputs"/> setting already applied. /// So if preserve outputs is disallwed for the pip, it should be set to <see cref="PreserveOutputsNotUsed"/></param> public UnsafeOptions(IUnsafeSandboxConfiguration unsafeConfiguration, PreserveOutputsInfo preserveOutputInfo) : this(unsafeConfiguration, preserveOutputInfo != PreserveOutputsNotUsed ? preserveOutputInfo : (PreserveOutputsInfo?)null) { }
// Extension methods /// <nodoc/> public static DoubleWritePolicy DoubleWritePolicy(this IUnsafeSandboxConfiguration configuration) => configuration.DoubleWritePolicy ?? DefaultDoubleWritePolicy;
/// <summary> /// Returns whether sandboxing is disabled. /// </summary> public static bool DisableDetours(this IUnsafeSandboxConfiguration @this) { return(@this.SandboxKind == SandboxKind.None); }
/// <summary> /// Creates an instance of <see cref="UnsafeOptions"/>. /// </summary> /// <param name="unsafeConfiguration">The IUnsafeSandboxConfiguration for the pip</param> /// <param name="preserveOutputSalt">The preserveOutputsSalt to use when running the pip. NOTE: this should have /// the pip specific <see cref="BuildXL.Pips.Operations.Process.AllowPreserveOutputs"/> setting already applied. /// So if preserve outputs is disallwed for the pip, it should be set to <see cref="PreserveOutputsNotUsed"/></param> public UnsafeOptions(IUnsafeSandboxConfiguration unsafeConfiguration, ContentHash preserveOutputSalt) : this(unsafeConfiguration, preserveOutputSalt != PreserveOutputsNotUsed ? preserveOutputSalt : (ContentHash?)null) { }
/// <summary> /// Whether <see cref="IUnsafeSandboxConfiguration.ProcessSymlinkedAccesses"/> is enabled and we are in a Windows-based OS /// </summary> public static bool ProcessSymlinkedAccesses(this IUnsafeSandboxConfiguration configuration) => (configuration.ProcessSymlinkedAccesses ?? DefaultProcessSymlinkedAccesses) && !OperatingSystemHelper.IsMacOS;
/// <nodoc/> public static RewritePolicy SourceWritePolicy(this IUnsafeSandboxConfiguration configuration) => configuration.DoubleWritePolicy ?? DefaultSourceRewritePolicy;
/// <nodoc/> public static bool SkipFlaggingSharedOpaqueOutputs(this IUnsafeSandboxConfiguration configuration) => (configuration.SkipFlaggingSharedOpaqueOutputs ?? DefaultSkipFlaggingSharedOpaqueOutputs);
/// <summary> /// Whether <see cref="IUnsafeSandboxConfiguration.EnableFullReparsePointResolving"/> is enabled and we are in a Windows-based OS /// </summary> public static bool EnableFullReparsePointResolving(this IUnsafeSandboxConfiguration configuration) => ((configuration.EnableFullReparsePointResolving ?? DefaultEnableFullReparsePointResolving) || !configuration.IgnoreFullReparsePointResolving) && !OperatingSystemHelper.IsUnixOS;
/// <summary> /// Whether <see cref="IUnsafeSandboxConfiguration.EnableFullReparsePointResolving"/> is enabled and we are in a Windows-based OS /// </summary> /// <remarks> /// Mac already resolves all reparse point in its sandbox, and doesn't need post-processing since MacLookup operations are just ignored. /// </remarks> public static bool EnableFullReparsePointResolving(this IUnsafeSandboxConfiguration configuration) => ((configuration.EnableFullReparsePointResolving ?? DefaultEnableFullReparsePointResolving) || !configuration.IgnoreFullReparsePointResolving);