Esempio n. 1
0
        private void NotifyKextPipTerminated(long pipId, IEnumerable <ReportedProcess> survivingChildProcesses)
        {
            // TODO: bundle this into a single message
            var distinctProcessIds = new HashSet <uint>(survivingChildProcesses.Select(p => p.ProcessId));

            foreach (var processId in distinctProcessIds)
            {
                KextConnection.NotifyKextPipProcessTerminated(pipId, (int)processId);
            }
        }
Esempio n. 2
0
        private async Task StartAsync()
        {
            base.CreateAndSetUpProcess();

            Process.StartInfo.FileName              = "/bin/sh";
            Process.StartInfo.Arguments             = string.Empty;
            Process.StartInfo.RedirectStandardInput = true;
            Process.Start();
            Process.BeginOutputReadLine();
            Process.BeginErrorReadLine();

            // Generate "Process Created" report because the rest of the system expects to see it before any other file access reports
            //
            // IMPORTANT: do this before notifying sandbox kernel extension, because otherwise it can happen that a report
            //            from the extension is received before the "process created" report is handled, causing
            //            a "Should see a process creation before its accesses" assertion exception.
            ReportProcessCreated();

            // Allow read access for /bin/sh
            ProcessInfo.FileAccessManifest.AddPath(
                AbsolutePath.Create(PathTable, Process.StartInfo.FileName),
                mask: FileAccessPolicy.MaskNothing,
                values: FileAccessPolicy.AllowReadAlways);

            if (MeasureCpuTime)
            {
                // Allow read access for /usr/bin/time
                ProcessInfo.FileAccessManifest.AddPath(
                    AbsolutePath.Create(PathTable, TimeUtil),
                    mask: FileAccessPolicy.MaskNothing,
                    values: FileAccessPolicy.AllowReadAlways);
            }

            if (!KextConnection.NotifyKextPipStarted(ProcessInfo.FileAccessManifest, this))
            {
                ThrowCouldNotStartProcess("Failed to notify kernel extension about process start, make sure the extension is loaded");
            }

            try
            {
                await FeedStdInAsync();

                SetProcessStartedExecuting();
                m_processTreeTimeoutTask = ProcessTreeTimeoutTask();
            }
            catch (IOException e)
            {
                // IOException can happen if the process is forcefully killed while we're feeding its std in.
                // When that happens, instead of crashing, just make sure the process is killed.
                LogProcessState($"IOException caught while feeding the standard input: {e.Message}");
                await KillAsync();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Waits for all child processes to finish within a timeout limit and then termiantes all still running children after that point.
        /// After all the children have been taken care of, the method waits for pending report processing to finish, then returns the
        /// collected reports.
        /// </summary>
        internal override async Task <SandboxedProcessReports> GetReportsAsync()
        {
            if (!Killed)
            {
                var awaitedTask = await Task.WhenAny(m_pendingReports.Completion, m_processTreeTimeoutTask);

                if (awaitedTask == m_processTreeTimeoutTask)
                {
                    LogProcessState("Waiting for reports timed out; any surviving processes will be forcefully killed.");
                    await KillAsync();
                }
            }

            // in any case must wait for pending reports to complete, because we must not freeze m_reports before that happens
            await m_pendingReports.Completion;

            // at this point this pip is done executing (it's only left to construct SandboxedProcessResult,
            // which is done by the base class) so notify the sandbox kernel extension connection manager about it.
            KextConnection.NotifyKextProcessFinished(PipId, this);

            return(IgnoreReportedAccesses ? null : m_reports);
        }