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}|")); }
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); }
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); }