/// <nodoc /> public SandboxExecRunner(Options options) { m_options = options; s_crashCollector = OperatingSystemHelper.IsUnixOS ? new CrashCollectorMacOS(new[] { CrashType.SandboxExec, CrashType.Kernel }) : null; m_sandboxConnection = OperatingSystemHelper.IsUnixOS ? #if PLATFORM_OSX m_options.UseEndpointSecuritySandbox ? (ISandboxConnection) new SandboxConnectionES() : #endif (ISandboxConnection) new SandboxConnectionKext( new SandboxConnectionKext.Config { FailureCallback = (int status, string description) => { m_sandboxConnection.Dispose(); throw new SystemException($"Received unrecoverable error from the sandbox (Code: {status.ToString("X")}, Description: {description}), please reload the extension and retry."); }, KextConfig = new Sandbox.KextConfig { ReportQueueSizeMB = m_options.ReportQueueSizeMB, EnableReportBatching = m_options.EnableReportBatching, #if PLATFORM_OSX EnableCatalinaDataPartitionFiltering = OperatingSystemHelper.IsMacOSCatalinaOrHigher #endif }, }) : null; }
/// <summary> /// Creates instance /// </summary> public SandboxedProcessInfo( PathTable pathTable, ISandboxedProcessFileStorage fileStorage, string fileName, FileAccessManifest fileAccessManifest, bool disableConHostSharing, ContainerConfiguration containerConfiguration, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null) { Contract.Requires(pathTable != null); Contract.Requires(fileStorage != null); Contract.Requires(fileName != null); PathTable = pathTable; FileAccessManifest = fileAccessManifest; FileStorage = fileStorage; FileName = fileName; DisableConHostSharing = disableConHostSharing; // This should be set for testing purposes only. TestRetries = testRetries; NestedProcessTerminationTimeout = DefaultNestedProcessTerminationTimeout; LoggingContext = loggingContext; DetoursEventListener = detoursEventListener; SandboxConnection = sandboxConnection; ContainerConfiguration = containerConfiguration; }
/// <summary> /// Creates instance for test /// </summary> public SandboxedProcessInfo( PathTable pathTable, ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, ContainerConfiguration containerConfiguration = null, FileAccessManifest fileAccessManifest = null) : this( pathTable, fileStorage, fileName, fileAccessManifest ?? new FileAccessManifest(pathTable), disableConHostSharing, containerConfiguration ?? ContainerConfiguration.DisabledIsolation, testRetries, loggingContext, detoursEventListener, sandboxConnection) { Contract.Requires(pathTable != null); Contract.Requires(fileStorage != null); Contract.Requires(fileName != null); }
/// <summary> /// Creates instance for test /// </summary> public SandboxedProcessInfo( PathTable pathTable, [CanBeNull] ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, LoggingContext loggingContext, bool testRetries = false, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, ContainerConfiguration containerConfiguration = null, FileAccessManifest fileAccessManifest = null, bool createJobObjectForCurrentProcess = true) : this( pathTable, fileStorage, fileName, fileAccessManifest ?? new FileAccessManifest(pathTable), disableConHostSharing, containerConfiguration ?? ContainerConfiguration.DisabledIsolation, loggingContext, testRetries, detoursEventListener, sandboxConnection, createJobObjectForCurrentProcess : createJobObjectForCurrentProcess) { Contract.RequiresNotNull(pathTable); Contract.RequiresNotNull(fileName); }
/// <summary> /// Creates instance /// </summary> public SandboxedProcessInfo( PathTable pathTable, [CanBeNull] ISandboxedProcessFileStorage fileStorage, string fileName, FileAccessManifest fileAccessManifest, bool disableConHostSharing, ContainerConfiguration containerConfiguration, LoggingContext loggingContext, bool testRetries = false, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, SidebandWriter sidebandWriter = null, bool createJobObjectForCurrentProcess = true) { Contract.RequiresNotNull(pathTable); Contract.RequiresNotNull(fileName); PathTable = pathTable; FileAccessManifest = fileAccessManifest; FileStorage = fileStorage; FileName = fileName; DisableConHostSharing = disableConHostSharing; // This should be set for testing purposes only. TestRetries = testRetries; NestedProcessTerminationTimeout = DefaultNestedProcessTerminationTimeout; LoggingContext = loggingContext; DetoursEventListener = detoursEventListener; SandboxConnection = sandboxConnection; ContainerConfiguration = containerConfiguration; SidebandWriter = sidebandWriter; CreateJobObjectForCurrentProcess = createJobObjectForCurrentProcess; }
/// <remarks> /// Sets <see cref="FileAccessManifest.FailUnexpectedFileAccesses"/> to false if not explicitly set /// </remarks> protected SandboxedProcessInfo ToProcessInfo( Process process, string pipDescription = null, FileAccessManifest fileAccessManifest = null, IDetoursEventListener detoursListener = null, bool disableConHostSharing = false, Dictionary <string, string> overrideEnvVars = null, ISandboxConnection sandboxConnection = null) { var envVars = Override( BuildParameters.GetFactory().PopulateFromEnvironment().ToDictionary(), overrideEnvVars); var methodName = DiscoverCurrentlyExecutingXunitTestMethodFQN(); pipDescription = pipDescription != null ? methodName + " - " + pipDescription : methodName; var info = new SandboxedProcessInfo( Context.PathTable, this, process.Executable.Path.ToString(Context.PathTable), detoursEventListener: detoursListener, sandboxConnection: sandboxConnection ?? GetSandboxConnection(), disableConHostSharing: disableConHostSharing, fileAccessManifest: fileAccessManifest, loggingContext: LoggingContext) { PipSemiStableHash = 0x1234, PipDescription = pipDescription, WorkingDirectory = TemporaryDirectory, Arguments = process.Arguments.ToString(Context.PathTable), Timeout = TimeSpan.FromMinutes(15), EnvironmentVariables = BuildParameters.GetFactory().PopulateFromDictionary(envVars) }; if (fileAccessManifest == null) { info.FileAccessManifest.FailUnexpectedFileAccesses = false; } foreach (var path in process.UntrackedPaths) { info.FileAccessManifest.AddPath(path, values: FileAccessPolicy.AllowAll, mask: FileAccessPolicy.MaskNothing); } foreach (var dir in process.UntrackedScopes) { info.FileAccessManifest.AddScope(dir, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll); } info.FileAccessManifest.PipId = GetNextPipId(); return(info); }
/// <summary> /// Creates instance /// </summary> public SandboxedProcessInfo( ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null) : this(new PathTable(), fileStorage, fileName, disableConHostSharing, testRetries, loggingContext, detoursEventListener, sandboxConnection) { }
public PipQueueTestExecutionEnvironment(BuildXLContext context, IConfiguration configuration, PipTable pipTable, string tempDirectory, ISandboxConnection SandboxConnection = null) { Contract.Requires(context != null); Contract.Requires(configuration != null); Context = context; LoggingContext = CreateLoggingContextForTest(); Configuration = configuration; FileContentTable = FileContentTable.CreateNew(); ContentFingerprinter = new PipContentFingerprinter( context.PathTable, artifact => State.FileContentManager.GetInputContent(artifact).FileContentInfo, ExtraFingerprintSalts.Default(), pathExpander: PathExpander); PipTable = pipTable; PipFragmentRenderer = this.CreatePipFragmentRenderer(); IpcProvider = IpcFactory.GetProvider(); var tracker = FileChangeTracker.CreateDisabledTracker(LoggingContext); Cache = InMemoryCacheFactory.Create(); LocalDiskContentStore = new LocalDiskContentStore(LoggingContext, context.PathTable, FileContentTable, tracker); m_sandboxConnectionKext = SandboxConnection; m_expectedWrittenContent = new ConcurrentDictionary <FileArtifact, ContentHash>(); m_wellKnownFiles = new ConcurrentDictionary <FileArtifact, ContentHash>(); m_producers = new ConcurrentDictionary <FileArtifact, Pip>(); m_filesystemView = new TestPipGraphFilesystemView(Context.PathTable); var fileSystemView = new FileSystemView(Context.PathTable, m_filesystemView, LocalDiskContentStore); TempCleaner = new TestMoveDeleteCleaner(tempDirectory); State = new PipExecutionState( configuration, cache: new PipTwoPhaseCache(LoggingContext, Cache, context, PathExpander), unsafeConfiguration: configuration.Sandbox.UnsafeSandboxConfiguration, preserveOutputsSalt: ContentHashingUtilities.CreateRandom(), fileAccessWhitelist: FileAccessWhitelist, directoryMembershipFingerprinter: this, pathExpander: PathExpander, executionLog: null, fileSystemView: fileSystemView, fileContentManager: new FileContentManager(this, new NullOperationTracker()), directoryMembershipFinterprinterRuleSet: null); m_sealContentsById = new ConcurrentBigMap <DirectoryArtifact, int[]>(); ProcessInContainerManager = new ProcessInContainerManager(LoggingContext, context.PathTable); }
/// <nodoc /> public SandboxExecRunner(Options options) { m_options = options; s_crashCollector = OperatingSystemHelper.IsMacOS ? new CrashCollectorMacOS(new[] { CrashType.SandboxExec, CrashType.Kernel }) : null; if (!OperatingSystemHelper.IsMacOSCatalinaOrHigher && (m_options.SandboxKindUsed == SandboxKind.MacOsEndpointSecurity || m_options.SandboxKindUsed == SandboxKind.MacOsHybrid)) { throw new NotSupportedException("EndpointSecurity and Hybrid sandbox types can't be run on system older than macOS Catalina (10.15+)."); } // m_sandboxConnection if (OperatingSystemHelper.IsLinuxOS) { m_sandboxConnection = new SandboxConnectionLinuxDetours(FailureCallback); } else if (OperatingSystemHelper.IsMacOS) { if (m_options.SandboxKindUsed == SandboxKind.MacOsKext) { m_sandboxConnection = new SandboxConnectionKext(new SandboxConnectionKext.Config { FailureCallback = FailureCallback, KextConfig = new Sandbox.KextConfig { ReportQueueSizeMB = m_options.ReportQueueSizeMB, EnableReportBatching = m_options.EnableReportBatching, #if PLATFORM_OSX EnableCatalinaDataPartitionFiltering = OperatingSystemHelper.IsMacOSCatalinaOrHigher #endif } }); } else { m_sandboxConnection = new SandboxConnection(m_options.SandboxKindUsed, isInTestMode: false, measureCpuTimes: true); } } else { m_sandboxConnection = null; } }
/// <remarks> /// This constructor is never used in this project, but there exist external projects that /// compile against this assembly and already depend on this constructor. /// </remarks> public SandboxedProcessInfo( [CanBeNull] ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, bool createJobObjectForCurrentProcess = true) : this( new PathTable(), fileStorage, fileName, disableConHostSharing, loggingContext ?? new LoggingContext("ExternalComponent"), testRetries, detoursEventListener, sandboxConnection, createJobObjectForCurrentProcess : createJobObjectForCurrentProcess) { }
private void SetSandboxConnectionIfNeeded(SandboxedProcessInfo info) { if (OperatingSystemHelper.IsLinuxOS) { m_sandboxConnection = new SandboxConnectionLinuxDetours(SandboxConnectionFailureCallback); } else if (OperatingSystemHelper.IsMacOS) { m_sandboxConnection = new SandboxConnectionKext( new SandboxConnectionKext.Config { FailureCallback = SandboxConnectionFailureCallback, KextConfig = new Interop.Unix.Sandbox.KextConfig { ReportQueueSizeMB = ReportQueueSizeForKextMB, #if PLATFORM_OSX EnableCatalinaDataPartitionFiltering = OperatingSystemHelper.IsMacWithoutKernelExtensionSupport #endif } }); } info.SandboxConnection = m_sandboxConnection; }
/// <summary> /// For unit tests only. /// </summary> public SandboxExecRunner(ISandboxConnection connection) { m_options = Options.Defaults; m_sandboxConnection = connection; }
protected override bool InitSandboxConnectionKext(LoggingContext loggingContext, ISandboxConnection SandboxConnectionKext = null) { if (SandboxingWithKextEnabled) { SandboxConnection = SandboxConnectionKext ?? XunitBuildXLTest.GetSandboxConnection(); } return(false); }
/// <summary> /// Creates an execution environment for a single pip. To run pips incrementally, the <paramref name="fileContentTable"/> and <paramref name="pipCache"/> should be specified. /// </summary> public DummyPipExecutionEnvironment( LoggingContext loggingContext, PipExecutionContext context, IConfiguration config, FileContentTable fileContentTable = null, EngineCache pipCache = null, SemanticPathExpander semanticPathExpander = null, PipContentFingerprinter.PipDataLookup pipDataLookup = null, FileAccessWhitelist fileAccessWhitelist = null, bool allowUnspecifiedSealedDirectories = false, PipTable pipTable = null, IIpcProvider ipcProvider = null, ISandboxConnection sandboxConnection = null) { Contract.Requires(context != null); Contract.Requires(config != null); LoggingContext = loggingContext; Context = context; // Ensure paths visible when debugging PathTable.DebugPathTable = Context.PathTable; Configuration = config; PipTable = pipTable; PathExpander = semanticPathExpander ?? SemanticPathExpander.Default; ContentFingerprinter = new PipContentFingerprinter( Context.PathTable, artifact => State.FileContentManager.GetInputContent(artifact).FileContentInfo, new ExtraFingerprintSalts(config, PipFingerprintingVersion.TwoPhaseV2, fingerprintSalt: null, searchPathToolsHash: null), pathExpander: PathExpander, pipDataLookup: pipDataLookup); PipFragmentRenderer = this.CreatePipFragmentRenderer(); IpcProvider = ipcProvider ?? IpcFactory.GetProvider(); FileContentTable = fileContentTable ?? FileContentTable.CreateNew(); Cache = pipCache; FileAccessWhitelist = fileAccessWhitelist; m_allowUnspecifiedSealedDirectories = allowUnspecifiedSealedDirectories; m_sandboxConnectionKext = sandboxConnection; if (Cache == null) { Cache = InMemoryCacheFactory.Create(); } var tracker = FileChangeTracker.CreateDisabledTracker(LoggingContext); LocalDiskContentStore = new LocalDiskContentStore(loggingContext, context.PathTable, FileContentTable, tracker); PipGraphView = new TestPipGraphFilesystemView(Context.PathTable); m_operationTracker = new OperationTracker(loggingContext); var fileSystemView = new FileSystemView(Context.PathTable, PipGraphView, LocalDiskContentStore); var preserveOutputsSalt = UnsafeOptions.PreserveOutputsNotUsed; if (config.Sandbox.UnsafeSandboxConfiguration.PreserveOutputs != PreserveOutputsMode.Disabled) { preserveOutputsSalt = ContentHashingUtilities.HashString(Guid.NewGuid().ToString()); } State = new PipExecutionState( config, cache: new PipTwoPhaseCache(loggingContext, Cache, context, PathExpander), fileAccessWhitelist: FileAccessWhitelist, directoryMembershipFingerprinter: this, pathExpander: PathExpander, executionLog: ExecutionLogRecorder, fileSystemView: fileSystemView, fileContentManager: GetFileContentManager(), directoryMembershipFinterprinterRuleSet: null, unsafeConfiguration: config.Sandbox.UnsafeSandboxConfiguration, preserveOutputsSalt: preserveOutputsSalt, serviceManager: new DummyServiceManager()); m_sealContentsById = new ConcurrentBigMap <DirectoryArtifact, int[]>(); ProcessInContainerManager = new ProcessInContainerManager(LoggingContext, context.PathTable); }