private bool TryPrepareSandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); FileAccessManifest fam = info.FileAccessManifest; if (!string.IsNullOrEmpty(fam.InternalDetoursErrorNotificationFile)) { Analysis.IgnoreResult(FileUtilities.TryDeleteFile(fam.InternalDetoursErrorNotificationFile)); } if (fam.CheckDetoursMessageCount && !OperatingSystemHelper.IsUnixOS) { string semaphoreName = fam.InternalDetoursErrorNotificationFile.Replace('\\', '_'); if (!fam.SetMessageCountSemaphore(semaphoreName)) { m_logger.LogError($"Semaphore '{semaphoreName}' for counting Detours messages is already opened"); return(false); } } if (info.GetCommandLine().Length > SandboxedProcessInfo.MaxCommandLineLength) { m_logger.LogError($"Process command line is longer than {SandboxedProcessInfo.MaxCommandLineLength} characters: {info.GetCommandLine().Length}"); return(false); } m_outputErrorObserver = OutputErrorObserver.Create(m_logger, info); info.StandardOutputObserver = m_outputErrorObserver.ObserveStandardOutputForWarning; info.StandardErrorObserver = m_outputErrorObserver.ObserveStandardErrorForWarning; return(true); }
private bool TryPrepareSandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); if (!string.IsNullOrEmpty(info.DetoursFailureFile) && FileUtilities.FileExistsNoFollow(info.DetoursFailureFile)) { Analysis.IgnoreResult(FileUtilities.TryDeleteFile(info.DetoursFailureFile)); } if (!string.IsNullOrEmpty(info.FileAccessManifest.InternalDetoursErrorNotificationFile) && FileUtilities.FileExistsNoFollow(info.FileAccessManifest.InternalDetoursErrorNotificationFile)) { Analysis.IgnoreResult(FileUtilities.TryDeleteFile(info.FileAccessManifest.InternalDetoursErrorNotificationFile)); } if (info.GetCommandLine().Length > SandboxedProcessInfo.MaxCommandLineLength) { m_logger.LogError($"Process command line is longer than {SandboxedProcessInfo.MaxCommandLineLength} characters: {info.GetCommandLine()}"); return(false); } m_outputErrorObserver = OutputErrorObserver.Create(m_logger, info); info.StandardOutputObserver = m_outputErrorObserver.ObserveStandardOutputForWarning; info.StandardErrorObserver = m_outputErrorObserver.ObserveStandardErrorForWarning; if (!TryPrepareWorkingDirectory(info) || !TryPrepareTemporaryFolders(info)) { return(false); } SetSandboxConnectionIfNeeded(info); return(true); }
private async Task <(ExitCode, SandboxedProcessResult)> ExecuteAsync(SandboxedProcessInfo info) { m_logger.LogInfo($"Start execution: {info.GetCommandLine()}"); FileAccessManifest fam = info.FileAccessManifest; try { if (fam.CheckDetoursMessageCount && !OperatingSystemHelper.IsUnixOS) { string semaphoreName = !string.IsNullOrEmpty(info.DetoursFailureFile) ? info.DetoursFailureFile.Replace('\\', '_') : "Detours_" + info.PipSemiStableHash.ToString("X16", CultureInfo.InvariantCulture) + "-" + Guid.NewGuid().ToString(); int maxRetry = 3; while (!fam.SetMessageCountSemaphore(semaphoreName)) { m_logger.LogInfo($"Semaphore '{semaphoreName}' for counting Detours messages is already opened"); fam.UnsetMessageCountSemaphore(); --maxRetry; if (maxRetry == 0) { break; } semaphoreName += $"_{maxRetry}"; } if (maxRetry == 0) { m_logger.LogError($"Semaphore for counting Detours messages cannot be newly created"); return(ExitCode.FailedSandboxPreparation, null); } } using (Stream standardInputStream = TryOpenStandardInputStream(info, out bool succeedInOpeningStdIn)) { if (!succeedInOpeningStdIn) { return(ExitCode.FailedSandboxPreparation, null); } using (StreamReader standardInputReader = standardInputStream == null ? null : new StreamReader(standardInputStream, CharUtilities.Utf8NoBomNoThrow)) { info.StandardInputReader = standardInputReader; ISandboxedProcess process = await StartProcessAsync(info); if (process == null) { return(ExitCode.FailedStartProcess, null); } SandboxedProcessResult result = await process.GetResultAsync(); // Patch result. result.WarningCount = m_outputErrorObserver.WarningCount; result.LastMessageCount = process.GetLastMessageCount(); result.DetoursMaxHeapSize = process.GetDetoursMaxHeapSize(); result.MessageCountSemaphoreCreated = info.FileAccessManifest.MessageCountSemaphore != null; return(ExitCode.Success, result); } } } finally { fam.UnsetMessageCountSemaphore(); } }
private async Task <(ExitCode, SandboxedProcessResult)> ExecuteAsync(SandboxedProcessInfo info) { m_logger.LogInfo($"Start execution: {info.GetCommandLine()}"); FileAccessManifest fam = info.FileAccessManifest; try { if (fam.CheckDetoursMessageCount && !OperatingSystemHelper.IsUnixOS) { string semaphoreName = !string.IsNullOrEmpty(info.DetoursFailureFile) ? info.DetoursFailureFile.Replace('\\', '_') : "Detours_" + info.PipSemiStableHash.ToString("X16", CultureInfo.InvariantCulture) + "-" + Guid.NewGuid().ToString(); int maxRetry = 3; // We check this first due to bug#1873910 when executing in a VM on Cloudbuild. // Creating this Semaphore may fail due to a semaphore with the same name already existing. // The reason for this is currently unknown, however since the name for the failures file is // created in SandboxedProcessPipExecutor.GetDetoursInternalErrorFilePath with a unique guid // along with the pip hash it should be safe to dispose because the name is unique to this pip. if (System.Threading.Semaphore.TryOpenExisting(semaphoreName, out var existingSemaphore)) { m_logger.LogInfo($"Disposing existing semaphore with name '{semaphoreName}'."); // Calling dispose on this will allow us to create a new semaphore with the same name existingSemaphore.Dispose(); } while (!fam.SetMessageCountSemaphore(semaphoreName)) { m_logger.LogInfo($"Semaphore '{semaphoreName}' for counting Detours messages is already opened"); fam.UnsetMessageCountSemaphore(); --maxRetry; if (maxRetry == 0) { break; } semaphoreName += $"_{maxRetry}"; } if (maxRetry == 0) { m_logger.LogError($"Semaphore for counting Detours messages cannot be newly created"); return(ExitCode.FailedSandboxPreparation, null); } } using (Stream standardInputStream = TryOpenStandardInputStream(info, out bool succeedInOpeningStdIn)) { if (!succeedInOpeningStdIn) { return(ExitCode.FailedSandboxPreparation, null); } using (StreamReader standardInputReader = standardInputStream == null ? null : new StreamReader(standardInputStream, CharUtilities.Utf8NoBomNoThrow)) { info.StandardInputReader = standardInputReader; ISandboxedProcess process = await StartProcessAsync(info); if (process == null) { return(ExitCode.FailedStartProcess, null); } SandboxedProcessResult result = await process.GetResultAsync(); // Patch result. result.WarningCount = m_outputErrorObserver.WarningCount; result.LastMessageCount = process.GetLastMessageCount(); result.DetoursMaxHeapSize = process.GetDetoursMaxHeapSize(); result.MessageCountSemaphoreCreated = info.FileAccessManifest.MessageCountSemaphore != null; return(ExitCode.Success, result); } } } finally { fam.UnsetMessageCountSemaphore(); } }