private FileAccessManifest GenerateFileAccessManifest(AbsolutePath toolDirectory, AbsolutePath outputFile) { // We make no attempt at understanding what the graph generation process is going to do // We just configure the manifest to not fail on unexpected accesses, so they can be collected // later if needed var fileAccessManifest = new FileAccessManifest(m_context.PathTable) { FailUnexpectedFileAccesses = false, ReportFileAccesses = true, MonitorNtCreateFile = true, MonitorZwCreateOpenQueryFile = true, MonitorChildProcesses = true, }; fileAccessManifest.AddScope( AbsolutePath.Create(m_context.PathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.Windows)), FileAccessPolicy.MaskAll, FileAccessPolicy.AllowAllButSymlinkCreation); fileAccessManifest.AddScope( AbsolutePath.Create(m_context.PathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.InternetCache)), FileAccessPolicy.MaskAll, FileAccessPolicy.AllowAllButSymlinkCreation); fileAccessManifest.AddScope( AbsolutePath.Create(m_context.PathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.History)), FileAccessPolicy.MaskAll, FileAccessPolicy.AllowAllButSymlinkCreation); fileAccessManifest.AddScope(toolDirectory, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowReadAlways); fileAccessManifest.AddPath(outputFile, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowWrite); return(fileAccessManifest); }
/// <summary> /// The manifest is configured so all accesses under the provided collection of directories to block are blocked /// </summary> private FileAccessManifest CreateManifest(AbsolutePath pathToProcess, IEnumerable <AbsolutePath> directoriesToBlock) { var fileAccessManifest = new FileAccessManifest(m_pathTable) { FailUnexpectedFileAccesses = true, ReportFileAccesses = true, MonitorChildProcesses = true, }; // We allow all file accesses at the root level, so by default everything is allowed fileAccessManifest.AddScope(AbsolutePath.Invalid, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll); // We explicitly allow reading from the tool path fileAccessManifest.AddPath(pathToProcess, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowRead); // We block access on all provided directories foreach (var directoryToBlock in directoriesToBlock) { fileAccessManifest.AddScope( directoryToBlock, FileAccessPolicy.MaskAll, FileAccessPolicy.Deny & FileAccessPolicy.ReportAccess); } return(fileAccessManifest); }
/// <inheritdoc /> public bool NotifyPipStarted(LoggingContext loggingContext, FileAccessManifest fam, SandboxedProcessUnix process) { Contract.Requires(process.Started); Contract.Requires(process.PipId != 0); string rootDir = process.RootJail ?? Path.GetTempPath(); string fifoPath = Path.Combine(rootDir, $"bxl_Pip{process.PipSemiStableHash:X}.{process.ProcessId}.fifo"); string famPath = Path.ChangeExtension(fifoPath, ".fam"); string debugLogPath = null; if (IsInTestMode) { debugLogPath = process.ToPathInsideRootJail(Path.ChangeExtension(fifoPath, ".log")); fam.AddPath(toAbsPath(debugLogPath), mask: FileAccessPolicy.MaskAll, values: FileAccessPolicy.AllowAll); } // serialize FAM using (var wrapper = Pools.MemoryStreamPool.GetInstance()) { var debugFlags = true; ArraySegment <byte> manifestBytes = fam.GetPayloadBytes( loggingContext, new FileAccessSetup { DllNameX64 = string.Empty, DllNameX86 = string.Empty, ReportPath = process.ToPathInsideRootJail(fifoPath) }, wrapper.Instance, timeoutMins: 10, // don't care debugFlagsMatch: ref debugFlags); Contract.Assert(manifestBytes.Offset == 0); File.WriteAllBytes(famPath, manifestBytes.ToArray()); } process.LogDebug($"Saved FAM to '{famPath}'"); // create a FIFO (named pipe) if (IO.MkFifo(fifoPath, IO.FilePermissions.S_IRWXU) != 0) { m_failureCallback?.Invoke(1, $"Creating FIFO {fifoPath} failed"); return(false); } process.LogDebug($"Created FIFO at '{fifoPath}'"); // create and save info for this pip var info = new Info(m_failureCallback, process, fifoPath, famPath, debugLogPath); if (!m_pipProcesses.TryAdd(process.PipId, info)) { throw new BuildXLException($"Process with PidId {process.PipId} already exists"); } info.Start(); return(true); AbsolutePath toAbsPath(string path) => AbsolutePath.Create(process.PathTable, path); }