private void HandleKextReport(Sandbox.AccessReport report)
        {
            // TODO: m_reports should be able to receive AccessReport object so that we don't have
            //       here render it to string only to be parsed again by SandboxedProcessReports
            string reportLine = AccessReportToString(report, out string operation, out _, out bool pathExists);

            // don't report MAC_LOOKUP probes for existent paths (because for those paths other reports will follow)
            if (operation == OpNames.OpMacLookup && pathExists)
            {
                return;
            }

            if (reportLine.Contains(OpNames.OpProcessTreeCompleted))
            {
                // We make sure that we get the ProcessTreeCompletedAckOperation as often as there are event queue workers,
                // this makes sure there are no more reports left in the queues for this process.
                Interlocked.Increment(ref m_processTreeCompletedAckOperationCount);
                if (Interlocked.Read(ref m_processTreeCompletedAckOperationCount) == m_processInfo.SandboxedKextConnection.NumberOfKextConnections)
                {
                    m_pendingReports.Complete();
                }
            }
            else
            {
                if (!Killed)
                {
                    m_reports.ReportLineReceived(reportLine);
                }
            }
        }
        private string AccessReportToString(Sandbox.AccessReport report, out string operation, out string path, out bool pathExists)
        {
            operation  = Encoding.UTF8.GetString(report.Operation).TrimEnd('\0');
            path       = Encoding.UTF8.GetString(report.Path).TrimEnd('\0');
            pathExists = File.Exists(path) || Directory.Exists(path);

            var type               = report.Type;
            var pid                = report.Pid.ToString("X");
            var requestedAccess    = report.RequestedAccess;
            var status             = report.Status;
            var explicitLogging    = report.ExplicitLogging != 0 ? 1 : 0;
            var error              = report.Error;
            var usn                = ReportedFileAccess.NoUsn.Value.ToString("X");
            var desiredAccess      = report.DesiredAccess.ToString("X");
            var shareMode          = report.ShareMode;
            var disposition        = report.Disposition;
            var flagsAndAttributes = report.FlagsAndAttributes.ToString("X");
            var pathId             = (AbsolutePath.TryCreate(PathTable, path, out var absPath) ? absPath.RawValue : 0).ToString("X");

            // our sandbox kernel extension currently doesn't detect file existence, so do it here instead
            if (error == 0 && !pathExists)
            {
                error = ReportedFileAccess.ERROR_PATH_NOT_FOUND;
            }

            return
                (I($"{type},{operation}:{pid}|{requestedAccess}|{status}|{explicitLogging}") +
                 I($"|{error}|{usn}|{desiredAccess}|{shareMode}|{disposition}|{flagsAndAttributes}|{pathId}|{path}|"));
        }
Esempio n. 3
0
        private void ReportProcessCreated()
        {
            var report = new Sandbox.AccessReport
            {
                Operation = FileOperation.OpProcessStart,
                Pid       = Process.Id,
                PipId     = PipId,
                Path      = Process.StartInfo.FileName,
                Status    = (uint)FileAccessStatus.Allowed
            };

            ReportFileAccess(ref report);
        }
Esempio n. 4
0
        private static Sandbox.AccessReport PostAccessReport(SandboxedProcessUnix proc, FileOperation operation, Sandbox.AccessReportStatistics stats,
                                                             int pid = 1234, string path = "/dummy/path", bool allowed = true)
        {
            var report = new Sandbox.AccessReport
            {
                Operation      = operation,
                Statistics     = stats,
                Pid            = pid,
                PathOrPipStats = Sandbox.AccessReport.EncodePath(path),
                Status         = allowed ? (uint)FileAccessStatus.Allowed : (uint)FileAccessStatus.Denied
            };

            proc.PostAccessReport(report);
            return(report);
        }
 /// <summary>
 /// Must not be blocking and should return as soon as possible
 /// </summary>
 internal void PostAccessReport(Sandbox.AccessReport report)
 {
     m_pendingReports.Post(report);
 }