Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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();
            }
        }
Пример #4
0
        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();
            }
        }