Exemple #1
0
        /// <nodoc />
        public SandboxedProcessMacKext(SandboxedProcessInfo info, bool ignoreReportedAccesses = false, bool?overrideMeasureTime = null)
            : base(info)
        {
            Contract.Requires(info.FileAccessManifest != null);
            Contract.Requires(info.SandboxedKextConnection != null);

            IgnoreReportedAccesses = ignoreReportedAccesses;

            MeasureCpuTime = overrideMeasureTime.HasValue
                ? overrideMeasureTime.Value
                : info.SandboxedKextConnection.MeasureCpuTimes;

            m_reports = new SandboxedProcessReports(
                info.FileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener);

            m_pendingReports = new ActionBlock <AccessReport>(
                HandleKextReport,
                new ExecutionDataflowBlockOptions
            {
#if FEATURE_CORECLR
                EnsureOrdered = true,
#endif
                BoundedCapacity        = DataflowBlockOptions.Unbounded,
                MaxDegreeOfParallelism = 1,     // Must be one, otherwise SandboxedPipExecutor will fail asserting valid reports
            });
        }
Exemple #2
0
        public void Dispose()
        {
            using (m_queryJobDataLock.AcquireWriteLock())
            {
                // Prevent further data queries
                m_disposeStarted = true;
            }

            if (m_processStarted)
            {
                InternalKill();
                m_resultTaskCompletionSource.Task.Wait();
            }

            m_detouredProcess?.Dispose();
            m_detouredProcess = null;

            m_output?.Dispose();
            m_output = null;

            m_error?.Dispose();
            m_error = null;

            m_reports = null;

            m_fileAccessManifestStreamWrapper.Dispose();
        }
        /// <nodoc />
        public SandboxedProcessMacKext(SandboxedProcessInfo info, bool ignoreReportedAccesses = false, bool?overrideMeasureTime = null)
            : base(info)
        {
            Contract.Requires(info.FileAccessManifest != null);
            Contract.Requires(info.SandboxedKextConnection != null);

            IgnoreReportedAccesses = ignoreReportedAccesses;

            MeasureCpuTime = overrideMeasureTime.HasValue
                ? overrideMeasureTime.Value
                : info.SandboxedKextConnection.MeasureCpuTimes;

            m_reports = new SandboxedProcessReports(
                info.FileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener);

            m_pendingReports = new ActionBlock <AccessReport>(
                HandleKextReport,
                new ExecutionDataflowBlockOptions
            {
                EnsureOrdered          = true,
                BoundedCapacity        = DataflowBlockOptions.Unbounded,
                MaxDegreeOfParallelism = 1,     // Must be one, otherwise SandboxedPipExecutor will fail asserting valid reports
            });

            // install a 'ProcessStarted' handler that informs the kext of the newly started process
            ProcessStarted += () => OnProcessStartedAsync().GetAwaiter().GetResult();
        }
        /// <nodoc />
        public SandboxedProcessMacKext(SandboxedProcessInfo info)
            : base(info)
        {
            Contract.Requires(info.FileAccessManifest != null);
            Contract.Requires(info.SandboxedKextConnection != null);

            m_processInfo = info;

            m_reports = new SandboxedProcessReports(
                info.FileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener);

            m_pendingReports = new ActionBlock <Sandbox.AccessReport>(
                (Action <Sandbox.AccessReport>)HandleKextReport,
                new ExecutionDataflowBlockOptions
            {
#if FEATURE_CORECLR
                EnsureOrdered = true,
#endif
                BoundedCapacity        = ExecutionDataflowBlockOptions.Unbounded,
                MaxDegreeOfParallelism = 1,     // Must be one, otherwise SandboxedPipExecutor will fail asserting valid reports
            });
        }
        /// <nodoc />
        public SandboxedProcessUnix(SandboxedProcessInfo info, bool ignoreReportedAccesses = false, bool?overrideMeasureTime = null)
            : base(info)
        {
            Contract.Requires(info.FileAccessManifest != null);
            Contract.Requires(info.SandboxConnection != null);

            PipId = info.FileAccessManifest.PipId;

            SandboxConnection   = info.SandboxConnection;
            ChildProcessTimeout = info.NestedProcessTerminationTimeout;
            AllowedSurvivingChildProcessNames = info.AllowedSurvivingChildProcessNames;
            ReportQueueProcessTimeoutForTests = info.ReportQueueProcessTimeoutForTests;
            IgnoreReportedAccesses            = ignoreReportedAccesses;
            RootJailInfo = info.RootJailInfo;

            MeasureCpuTime = overrideMeasureTime.HasValue
                ? overrideMeasureTime.Value
                : info.SandboxConnection.MeasureCpuTimes;

            m_perfAggregator = new PerfAggregator();

            m_perfCollector = new CancellableTimedAction(
                callback: UpdatePerfCounters,
                intervalMs: (int)PerfProbeInternal.TotalMilliseconds);

            m_reports = new SandboxedProcessReports(
                info.FileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener,
                info.SidebandWriter,
                info.FileSystemView);

            var useSingleProducer = !(SandboxConnection.Kind == SandboxKind.MacOsHybrid || SandboxConnection.Kind == SandboxKind.MacOsDetours);

            var executionOptions = new ExecutionDataflowBlockOptions
            {
                EnsureOrdered             = true,
                SingleProducerConstrained = useSingleProducer,
                BoundedCapacity           = DataflowBlockOptions.Unbounded,
                MaxDegreeOfParallelism    = 1 // Must be one, otherwise SandboxedPipExecutor will fail asserting valid reports
            };

            m_pendingReports = new ActionBlock <AccessReport>(HandleAccessReport, executionOptions);

            // install a 'ProcessStarted' handler that informs the sandbox of the newly started process
            ProcessStarted += (pid) => OnProcessStartedAsync(info).GetAwaiter().GetResult();
        }
Exemple #6
0
        /// <inheritdoc />
        public async Task <SandboxedProcessResult> GetResultAsync()
        {
            Contract.Requires(Started);

            SandboxedProcessReports reports = null;

            await m_processExecutor.WaitForExitAsync();

            if (m_processExecutor.Killed)
            {
                // call here this.KillAsync() because a subclass may override it
                // to do some extra processing when a process is killed
                await KillAsync();
            }

            LogProcessState("Waiting for reports to be received");
            reports = await GetReportsAsync();

            m_reportsReceivedTime = DateTime.UtcNow;
            reports?.Freeze();

            await m_processExecutor.WaitForStdOutAndStdErrAsync();

            var reportFileAccesses = ProcessInfo.FileAccessManifest?.ReportFileAccesses == true;
            var fileAccesses       = reportFileAccesses ? (reports?.FileAccesses ?? s_emptyFileAccessesSet) : null;

            return(new SandboxedProcessResult
            {
                ExitCode = m_processExecutor.TimedOut ? ExitCodes.Timeout : Process.ExitCode,
                Killed = Killed,
                TimedOut = m_processExecutor.TimedOut,
                HasDetoursInjectionFailures = HasSandboxFailures,
                JobAccountingInformation = GetJobAccountingInfo(),
                StandardOutput = m_output.Freeze(),
                StandardError = m_error.Freeze(),
                HasReadWriteToReadFileAccessRequest = reports?.HasReadWriteToReadFileAccessRequest ?? false,
                AllUnexpectedFileAccesses = reports?.FileUnexpectedAccesses ?? s_emptyFileAccessesSet,
                FileAccesses = fileAccesses,
                DetouringStatuses = reports?.ProcessDetoursStatuses,
                ExplicitlyReportedFileAccesses = reports?.ExplicitlyReportedFileAccesses,
                Processes = CoalesceProcesses(reports?.Processes),
                MessageProcessingFailure = reports?.MessageProcessingFailure,
                DumpCreationException = m_dumpCreationException,
                DumpFileDirectory = ProcessInfo.TimeoutDumpDirectory,
                PrimaryProcessTimes = GetProcessTimes(),
                SurvivingChildProcesses = CoalesceProcesses(GetSurvivingChildProcesses())
            });
        }
Exemple #7
0
        public void Dispose()
        {
            if (m_processStarted)
            {
                InternalKill();
                m_resultTaskCompletionSource.Task.Wait();
            }

            m_detouredProcess?.Dispose();
            m_detouredProcess = null;

            m_output?.Dispose();
            m_output = null;

            m_error?.Dispose();
            m_error = null;

            m_reports = null;

            m_fileAccessManifestStreamWrapper.Dispose();
        }
Exemple #8
0
        /// <nodoc />
        public SandboxedProcessMac(SandboxedProcessInfo info, bool ignoreReportedAccesses = false, bool?overrideMeasureTime = null)
            : base(info)
        {
            Contract.Requires(info.FileAccessManifest != null);
            Contract.Requires(info.SandboxConnection != null);

            IgnoreReportedAccesses = ignoreReportedAccesses;

            MeasureCpuTime = overrideMeasureTime.HasValue
                ? overrideMeasureTime.Value
                : info.SandboxConnection.MeasureCpuTimes;

            m_perfAggregator = new PerfAggregator();

            m_perfCollector = new CancellableTimedAction(
                callback: UpdatePerfCounters,
                intervalMs: (int)PerfProbeInternal.TotalMilliseconds);

            m_reports = new SandboxedProcessReports(
                info.FileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener,
                info.SharedOpaqueOutputLogger);

            m_pendingReports = new ActionBlock <AccessReport>(
                HandleAccessReport,
                new ExecutionDataflowBlockOptions
            {
                EnsureOrdered          = true,
                BoundedCapacity        = DataflowBlockOptions.Unbounded,
                MaxDegreeOfParallelism = 1,     // Must be one, otherwise SandboxedPipExecutor will fail asserting valid reports
            });

            // install a 'ProcessStarted' handler that informs the sandbox of the newly started process
            ProcessStarted += () => OnProcessStartedAsync().GetAwaiter().GetResult();
        }
Exemple #9
0
        internal SandboxedProcess(SandboxedProcessInfo info)
        {
            Contract.Requires(info != null);
            Contract.Requires(!info.Timeout.HasValue || info.Timeout.Value <= Process.MaxTimeout);

            // there could be a race here, but it just doesn't matter
            if (s_binaryPaths == null)
            {
                s_binaryPaths = new BinaryPaths(); // this can take a while; performs I/O
            }

            // If unspecified make the injection timeout the DefaultProcessTimeoutInMinutes. Also, make it no less than DefaultProcessTimeoutInMinutes.
            m_timeoutMins = info.Timeout.HasValue ? ((uint)info.Timeout.Value.TotalMinutes) : SandboxConfiguration.DefaultProcessTimeoutInMinutes;
            if (m_timeoutMins < SandboxConfiguration.DefaultProcessTimeoutInMinutes)
            {
                m_timeoutMins = SandboxConfiguration.DefaultProcessTimeoutInMinutes;
            }

            m_fileAccessManifest = info.FileAccessManifest;
            m_fileAccessManifestStreamWrapper = Pools.MemoryStreamPool.GetInstance();
            m_bufferSize = SandboxedProcessInfo.BufferSize;
            m_allowedSurvivingChildProcessNames = info.AllowedSurvivingChildProcessNames;
            m_nestedProcessTerminationTimeout   = info.NestedProcessTerminationTimeout;
            m_loggingContext = info.LoggingContext;

            Encoding inputEncoding = info.StandardInputEncoding ?? Console.InputEncoding;

            m_standardInputReader = info.StandardInputReader;

            m_pathTable = info.PathTable;

            Encoding outputEncoding = info.StandardOutputEncoding ?? Console.OutputEncoding;

            m_output = new SandboxedProcessOutputBuilder(
                outputEncoding,
                info.MaxLengthInMemory,
                info.FileStorage,
                SandboxedProcessFile.StandardOutput,
                info.StandardOutputObserver);
            Encoding errorEncoding = info.StandardErrorEncoding ?? Console.OutputEncoding;

            m_error = new SandboxedProcessOutputBuilder(
                errorEncoding,
                info.MaxLengthInMemory,
                info.FileStorage,
                SandboxedProcessFile.StandardError,
                info.StandardErrorObserver);

            m_reports = m_fileAccessManifest != null ?
                        new SandboxedProcessReports(
                m_fileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener,
                info.SidebandWriter) : null;

            Contract.Assume(inputEncoding != null);
            Contract.Assert(errorEncoding != null);
            Contract.Assert(outputEncoding != null);

            m_detouredProcess =
                new DetouredProcess(
                    SandboxedProcessInfo.BufferSize,
                    info.GetCommandLine(),
                    info.WorkingDirectory,
                    info.GetUnicodeEnvironmentBlock(),
                    inputEncoding,
                    errorEncoding,
                    m_error.AppendLine,
                    outputEncoding,
                    m_output.AppendLine,
                    OnProcessExitingAsync,
                    OnProcessExited,
                    info.Timeout,
                    info.DisableConHostSharing,
                    info.LoggingContext,
                    info.TimeoutDumpDirectory,
                    info.ContainerConfiguration,
                    // If there is any process configured to breakway from the sandbox, then we need to allow
                    // this to happen at the job object level
                    setJobBreakawayOk: m_fileAccessManifest.ProcessesCanBreakaway,
                    info.CreateJobObjectForCurrentProcess);
        }
Exemple #10
0
        internal SandboxedProcess(SandboxedProcessInfo info)
        {
            Contract.Requires(info != null);
            Contract.Requires(!info.Timeout.HasValue || info.Timeout.Value <= Process.MaxTimeout);

            // there could be a race here, but it just doesn't matter
            if (s_binaryPaths == null)
            {
                s_binaryPaths = new BinaryPaths(); // this can take a while; performs I/O
            }

            // If unspecified make the injection timeout 10 mins. Also, make it no less than 10 mins.
            m_timeoutMins = info.Timeout.HasValue ? ((uint)info.Timeout.Value.TotalMinutes) : 10;
            if (m_timeoutMins < 10)
            {
                m_timeoutMins = 10;
            }

            m_fileAccessManifest = info.FileAccessManifest;
            m_fileAccessManifestStreamWrapper = Pools.MemoryStreamPool.GetInstance();
            m_bufferSize = SandboxedProcessInfo.BufferSize;
            m_nestedProcessTerminationTimeout = info.NestedProcessTerminationTimeout;

            Encoding inputEncoding = info.StandardInputEncoding ?? Console.InputEncoding;

            m_standardInputReader = info.StandardInputReader;

            m_pathTable = info.PathTable;

            Encoding outputEncoding = info.StandardOutputEncoding ?? Console.OutputEncoding;

            m_output = new SandboxedProcessOutputBuilder(
                outputEncoding,
                info.MaxLengthInMemory,
                info.FileStorage,
                SandboxedProcessFile.StandardOutput,
                info.StandardOutputObserver);
            Encoding errorEncoding = info.StandardErrorEncoding ?? Console.OutputEncoding;

            m_error = new SandboxedProcessOutputBuilder(
                errorEncoding,
                info.MaxLengthInMemory,
                info.FileStorage,
                SandboxedProcessFile.StandardError,
                info.StandardErrorObserver);

            m_reports = m_fileAccessManifest != null ?
                        new SandboxedProcessReports(
                m_fileAccessManifest,
                info.PathTable,
                info.PipSemiStableHash,
                info.PipDescription,
                info.LoggingContext,
                info.DetoursEventListener) : null;

            Contract.Assume(inputEncoding != null);
            Contract.Assert(errorEncoding != null);
            Contract.Assert(outputEncoding != null);

            m_processIdListener = info.ProcessIdListener;
            m_detouredProcess   =
                new DetouredProcess(
                    SandboxedProcessInfo.BufferSize,
                    info.GetCommandLine(),
                    info.WorkingDirectory,
                    info.GetUnicodeEnvironmentBlock(),
                    inputEncoding,
                    errorEncoding,
                    m_error.AppendLine,
                    outputEncoding,
                    m_output.AppendLine,
                    OnProcessExitingAsync,
                    OnProcessExited,
                    info.Timeout,
                    info.DisableConHostSharing,
                    info.LoggingContext,
                    info.TimeoutDumpDirectory);
        }