chromium/content/browser/renderer_host/jit_policy_browsertest.cc

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

#include "base/strings/string_number_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "sandbox/policy/features.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_WIN)
#include "sandbox/policy/win/sandbox_win.h"
#endif

namespace content {

namespace {

constexpr char kEnabledDomain[] =;
constexpr char kDisabledDomain[] =;

bool RendererIsJitless(RenderProcessHost* rph) {}

#if BUILDFLAG(IS_WIN)
bool RendererHasDynamicCodeMitigation(RenderProcessHost* rph) {
  // Multiple renderer processes might have started. Grab a reference to the
  // base::Process itself as well as grabbing the process ID; this ensures that
  // the process doesn't actually die during the RunLoop::Run() call below, so
  // its pid cannot be reused and confuse the test.
  base::Process proc = rph->GetProcess().Duplicate();
  base::ProcessId renderer_process_id = proc.Pid();

  base::RunLoop run_loop;
  base::Value out_args;
  sandbox::policy::SandboxWin::GetPolicyDiagnostics(
      base::BindLambdaForTesting([&run_loop, &out_args](base::Value args) {
        out_args = std::move(args);
        run_loop.Quit();
      }));
  run_loop.Run();

  const base::Value::List* process_list = out_args.GetIfList();
  CHECK(process_list);

  for (const base::Value& process_value : *process_list) {
    const base::Value::Dict* process = process_value.GetIfDict();
    CHECK(process);
    double pid = *process->FindDouble("processId");
    if (base::checked_cast<base::ProcessId>(pid) != renderer_process_id) {
      continue;
    }

    std::string mitigations = *process->FindString("desiredMitigations");
    uint64_t mask = 0;
    CHECK(base::HexStringToUInt64(mitigations, &mask));

    return !!(mask & sandbox::MITIGATION_DYNAMIC_CODE_DISABLE);
  }

  return false;
}
#endif  // IS_WIN

}  // namespace

class JitPolicyContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {};

// This test fixture installs a test ContentBrowserClient which enables JIT for
// kEnabledDomain and disables JIT for kDisabledDomain.
class JitPolicyBrowserTest : public ContentBrowserTest {};

// This test asserts that navigating to a renderer which has JIT disabled yields
// a jitless renderer process with the DynamicCode mitigation applied.
IN_PROC_BROWSER_TEST_F(JitPolicyBrowserTest, JitDisabledImpliesJitless) {}

// This test asserts that navigating to a JIT-enabled site results in a renderer
// process that is not jitless and does not have the dynamic code mitigation
// enabled.
IN_PROC_BROWSER_TEST_F(JitPolicyBrowserTest, JitEnabledImpliesNoJitless) {}

}  // namespace content