chromium/sandbox/win/src/startup_information_helper.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SANDBOX_WIN_SRC_STARTUP_INFORMATION_HELPER_H_
#define SANDBOX_WIN_SRC_STARTUP_INFORMATION_HELPER_H_

#include <Windows.h>

#include <vector>

#include "base/memory/scoped_refptr.h"
#include "base/win/startup_information.h"
#include "sandbox/win/src/app_container_base.h"
#include "sandbox/win/src/process_mitigations.h"
#include "sandbox/win/src/security_capabilities.h"

namespace sandbox {
using base::win::StartupInformation;

// Wraps base::win::StartupInformation and allows some querying of what is
// set. This is specialized for the dance between
// BrokerServices::SpawnTarget() and TargetProcess::Create().
class StartupInformationHelper {
 public:
  StartupInformationHelper();
  ~StartupInformationHelper();

  // Adds flags to the |dwFlags| field.
  void UpdateFlags(DWORD flags);
  // Sets |lpDesktop|. If |desktop| is empty, sets as nullptr.
  void SetDesktop(std::wstring desktop);
  // Creates PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY based on |flags|.
  void SetMitigations(MitigationFlags flags);
  // Creates PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY if |restrict| is true.
  void SetRestrictChildProcessCreation(bool restrict);
  // Sets stdout and stderr handles. Also allows these to be inherited into
  // the child process. Should be called once only.
  void SetStdHandles(HANDLE stdout_handle, HANDLE stderr_handle);
  // Ignores duplicate or invalid handles.
  void AddInheritedHandle(HANDLE handle);
  // Create PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES and
  //        PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY
  // based on |container|. |container| should be valid.
  void SetAppContainer(AppContainer* container);
  // Creates PROC_THREAD_ATTRIBUTE_JOB_LIST with |job_handle|.
  void AddJobToAssociate(HANDLE job_handle);

  // Will one or more jobs be associated via the wrapped StartupInformation.
  bool HasJobsToAssociate() { return !job_handle_list_.empty(); }
  // Have handles been provided for secure inheritance?
  bool ShouldInheritHandles() { return inherit_handles_; }

  // Compiles fields into PROC_THREAD_ attributes and populates startup
  // information. Must be called before GetStartupInformation().
  bool BuildStartupInformation();

  // Sets whether or not the process created using this startup information will
  // have its environment filtered.
  void SetFilterEnvironment(bool filter);

  // Obtains whether or not the environment for the process created with this
  // startup information should be filtered.
  bool IsEnvironmentFiltered();

  // Gets wrapped object, valid once BuildStartupInformation() has been called.
  base::win::StartupInformation* GetStartupInformation() {
    return &startup_info_;
  }

 private:
  void operator=(const StartupInformationHelper&) = delete;
  StartupInformationHelper(const StartupInformationHelper&) = delete;

  DWORD CountAttributes();

  // Fields that are not passed into CreateProcessAsUserW().
  // This can only be true if security_capabilities_ is also initialized.
  bool enable_low_privilege_app_container_ = false;
  bool restrict_child_process_creation_ = false;
  HANDLE stdout_handle_ = INVALID_HANDLE_VALUE;
  HANDLE stderr_handle_ = INVALID_HANDLE_VALUE;
  bool inherit_handles_ = false;
  bool filter_environment_ = false;
  size_t mitigations_size_ = 0;

  // startup_info_.startup_info() is passed to CreateProcessAsUserW().
  StartupInformation startup_info_;

  // These need to have the same lifetime as startup_info_.startup_info();
  std::wstring desktop_;
  DWORD64 mitigations_[2]{};
  COMPONENT_FILTER component_filter_{};
  DWORD child_process_creation_ = 0;
  DWORD all_applications_package_policy_ = 0;
  std::vector<HANDLE> inherited_handle_list_;
  std::vector<HANDLE> job_handle_list_;
  std::unique_ptr<SecurityCapabilities> security_capabilities_;
};
}  // namespace sandbox

#endif  // SANDBOX_WIN_SRC_STARTUP_INFORMATION_HELPER_H_