public void AugmentedAccessHasTheRightManifestPath() { var fam = new FileAccessManifest( Context.PathTable, childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName }) { FailUnexpectedFileAccesses = false, ReportUnexpectedFileAccesses = true, ReportFileAccesses = true }; var basePath = TestBinRootPath.Combine(Context.PathTable, "foo"); var output = CreateOutputFileArtifact(basePath); fam.AddScope(basePath, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess); var info = ToProcessInfo( ToProcess( Operation.AugmentedWrite(output)), fileAccessManifest: fam); var result = RunProcess(info).GetAwaiter().GetResult(); XAssert.AreEqual(0, result.ExitCode); var fileAccess = result.ExplicitlyReportedFileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool); XAssert.AreEqual(basePath, fileAccess.ManifestPath); }
public void MaskedReportAugmentedAccessIsNotReported() { var fam = new FileAccessManifest( Context.PathTable, childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName }) { FailUnexpectedFileAccesses = false, ReportUnexpectedFileAccesses = true, ReportFileAccesses = true }; var basePath = TestBinRootPath.Combine(Context.PathTable, "foo"); var output1 = CreateOutputFileArtifact(basePath); var output2 = CreateOutputFileArtifact(basePath); // We mask reporting accesses for output1 and enable it for output2 fam.AddScope(output1.Path, ~FileAccessPolicy.ReportAccess, FileAccessPolicy.AllowAll); fam.AddScope(output2.Path, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess); var info = ToProcessInfo( ToProcess( Operation.AugmentedWrite(output1), Operation.AugmentedWrite(output2)), fileAccessManifest: fam); var result = RunProcess(info).GetAwaiter().GetResult(); XAssert.AreEqual(0, result.ExitCode); // We should get a single access with output2, since output1 should be ignored var accessPath = result.FileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).ManifestPath; XAssert.AreEqual(output2.Path, accessPath); }
public void MaskedReportAugmentedAccessIsNotReported(bool reportFileAccesses) { var fam = new FileAccessManifest( Context.PathTable, childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName }) { FailUnexpectedFileAccesses = false, ReportUnexpectedFileAccesses = true, ReportFileAccesses = reportFileAccesses }; var basePath = TestBinRootPath.Combine(Context.PathTable, "foo"); var output1 = CreateOutputFileArtifact(basePath); var output2 = CreateOutputFileArtifact(basePath); // We mask reporting accesses for output1 and enable it for output2 fam.AddScope(output1.Path, ~FileAccessPolicy.ReportAccess, FileAccessPolicy.AllowAll); fam.AddScope(output2.Path, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess); var collector = new FileAccessCollector(Context.PathTable); var info = ToProcessInfo( ToProcess( Operation.AugmentedWrite(output1), Operation.AugmentedWrite(output2)), fileAccessManifest: fam, detoursListener: collector); var result = RunProcess(info).GetAwaiter().GetResult(); XAssert.AreEqual(0, result.ExitCode); // We should get a single explicit access with output2, since output1 shouldn't be reported var accessPath = result.ExplicitlyReportedFileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).ManifestPath; XAssert.AreEqual(output2.Path, accessPath); // We should get both accesses as part of the (optional) FileAccess on request if (reportFileAccesses) { var allTrustedAcceses = result.FileAccesses.Where(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).Select(rfa => rfa.ManifestPath); XAssert.Contains(allTrustedAcceses, output1.Path, output2.Path); } else { // Make sure the access related to output1 is not actually reported, and the only one the listener got is output2 XAssert.Contains(collector.FileAccessPaths, output2.Path); XAssert.ContainsNot(collector.FileAccessPaths, output1.Path); } }
public void AugmentedAccessPathsAreCanonicalized() { var fam = new FileAccessManifest( Context.PathTable, childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName }) { FailUnexpectedFileAccesses = false, ReportUnexpectedFileAccesses = true, ReportFileAccesses = true }; var basePath = TestBinRootPath.Combine(Context.PathTable, "foo").Combine(Context.PathTable, "bar"); // Let's create a path that is equivalent to base path but it is constructed with '..' string nonCanonicalBasePath = Path.Combine(basePath.ToString(Context.PathTable), "..", "bar"); var source = CreateSourceFile(basePath); var output = CreateOutputFileArtifact(basePath); // Now create non-canonical paths for source and output string nonCanonicalSource = Path.Combine(nonCanonicalBasePath, source.Path.GetName(Context.PathTable).ToString(Context.StringTable)); string nonCanonicalOutput = Path.Combine(nonCanonicalBasePath, output.Path.GetName(Context.PathTable).ToString(Context.StringTable)); var collector = new FileAccessDetoursListenerCollector(Context.PathTable); var info = ToProcessInfo( ToProcess( Operation.AugmentedRead(nonCanonicalSource), Operation.AugmentedWrite(nonCanonicalOutput)), fileAccessManifest: fam, detoursListener: collector); var result = RunProcess(info).GetAwaiter().GetResult(); XAssert.AreEqual(0, result.ExitCode); // Let's check the raw paths reported by detours to make sure they are canonicalized var allRawPaths = collector.GetAllFileAccessPaths().Select(path => path.ToUpperInvariant()); XAssert.Contains(allRawPaths, source.Path.ToString(Context.PathTable).ToUpperInvariant(), output.Path.ToString(Context.PathTable).ToUpperInvariant()); }