Enable strict site isolation by default (see issue #2498)

This restores the default site isolation mode for Chromium on desktop
platforms. Unit tests have been updated to reflect the new behavior
expectations.

Known behavior changes in CEF are as follows:
- A spare renderer process may be created on initial browser creation or cross-
  origin navigation. This spare process may be used with a future cross-origin
  navigation or discarded on application shutdown. As a result
  CefRenderProcessHandler::OnRenderThreadCreated, which is called shortly after
  renderer process creation, can no longer be used to reliably transfer state
  for the currently in-progress navigation. Unit tests have been updated to use
  the CreateBrowser/OnBeforePopup |extra_info| value for transferring test state
  to CefRenderProcessHandler::OnBrowserCreated which will be called in the
  correct/expected renderer process.
- Cross-origin navigations will again receive a new renderer process, as
  expected. This behavior had briefly regressed in M78 due to the
  ProcessSharingWithDefaultSiteInstances feature becoming enabled by default.
- Cross-origin navigations initiated by calling LoadURL in the renderer process
  will now crash that process with "bad IPC message" reason
  INVALID_INITIATOR_ORIGIN (213). This is a security feature implemented in
  Chromium.
- A DevTools browser created using CefBrowserHost::ShowDevTools will receive
  the same CefRenderProcessHandler::OnBrowserCreated |extra_info| value that was
  set via CreateBrowser/OnBeforePopup for the parent browser.
This commit is contained in:
Marshall Greenblatt
2019-10-03 17:17:58 +03:00
parent 5da1649653
commit eea1f6be63
8 changed files with 156 additions and 407 deletions

View File

@@ -85,13 +85,12 @@ enum FrameNavFactoryId {
FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN,
};
// Command-line argument names.
const char kTestArg[] = "test";
const char kTestFactoryIdArg[] = "testfid";
// IPC message name.
const char kFrameNavMsg[] = "FrameTest.Navigation";
// Extra info parameter keys.
const char kFrameNavTestCmdKey[] = "frame-nav-test";
// Origins used in tests.
const char kFrameNavOrigin0[] = "http://tests-framenav0.com/";
const char kFrameNavOrigin1[] = "http://tests-framenav1.com/";
@@ -103,10 +102,6 @@ const char kFrameNavOrigin3[] = "http://tests-framenav3.com/";
// below use cases.
const int kMaxMultiNavNavigations = 4;
// Global variables identifying the currently running test.
bool g_frame_nav_test = false;
FrameNavFactoryId g_frame_nav_factory_id = FNF_ID_INVALID;
// Abstract base class representing expectations that result from a navigation.
class FrameNavExpectations {
public:
@@ -274,63 +269,24 @@ class FrameNavExpectationsFactoryRenderer : public FrameNavExpectationsFactory {
virtual scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) = 0;
};
// Browser side app delegate.
class FrameNavBrowserTest : public ClientAppBrowser::Delegate {
public:
FrameNavBrowserTest() {}
void OnBeforeChildProcessLaunch(
CefRefPtr<ClientAppBrowser> app,
CefRefPtr<CefCommandLine> command_line) override {
if (!g_frame_nav_test)
return;
std::stringstream ss;
ss << g_frame_nav_factory_id;
// Indicate to the render process that the test should be run.
command_line->AppendSwitchWithValue(kTestArg, kFrameNavMsg);
command_line->AppendSwitchWithValue(kTestFactoryIdArg, ss.str());
}
protected:
IMPLEMENT_REFCOUNTING(FrameNavBrowserTest);
};
// Renderer side handler.
class FrameNavRendererTest : public ClientAppRenderer::Delegate,
public CefLoadHandler {
public:
FrameNavRendererTest() : run_test_(false), nav_(0) {}
void OnRenderThreadCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefListValue> extra_info) override {
// The g_* values will be set when running in single-process mode.
if (!g_frame_nav_test) {
// Check that the test should be run.
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const std::string& test = command_line->GetSwitchValue(kTestArg);
if (test != kFrameNavMsg)
return;
}
void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) override {
if (!extra_info->HasKey(kFrameNavTestCmdKey))
return;
FrameNavFactoryId factory_id = g_frame_nav_factory_id;
if (factory_id == FNF_ID_INVALID) {
// Retrieve the factory ID from the command-line.
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (command_line->HasSwitch(kTestFactoryIdArg)) {
factory_id = static_cast<FrameNavFactoryId>(
atoi(command_line->GetSwitchValue(kTestFactoryIdArg)
.ToString()
.c_str()));
if (factory_id == FNF_ID_INVALID)
return;
}
}
FrameNavFactoryId factory_id =
static_cast<FrameNavFactoryId>(extra_info->GetInt(kFrameNavTestCmdKey));
run_test_ = factory_id != FNF_ID_INVALID;
if (!run_test_)
return;
run_test_ = true;
factory_ = FrameNavExpectationsFactoryRenderer::FromID(factory_id);
}
@@ -416,26 +372,20 @@ class FrameNavTestHandler : public TestHandler {
public:
explicit FrameNavTestHandler(FrameNavFactoryId factory_id)
: nav_(0),
factory_(FrameNavExpectationsFactoryBrowser::FromID(factory_id)) {
EXPECT_FALSE(g_frame_nav_test);
EXPECT_EQ(FNF_ID_INVALID, g_frame_nav_factory_id);
g_frame_nav_test = true;
g_frame_nav_factory_id = factory_id;
}
factory_(FrameNavExpectationsFactoryBrowser::FromID(factory_id)) {}
~FrameNavTestHandler() override {
EXPECT_TRUE(got_destroyed_);
g_frame_nav_test = false;
g_frame_nav_factory_id = FNF_ID_INVALID;
}
~FrameNavTestHandler() override { EXPECT_TRUE(got_destroyed_); }
void RunTest() override {
// Create the first expectations object.
expectations_ = factory_->Create(
nav_, base::Bind(&FrameNavTestHandler::RunNextNav, this));
CefRefPtr<CefDictionaryValue> extra_info = CefDictionaryValue::Create();
extra_info->SetInt(kFrameNavTestCmdKey, factory_->GetID());
// Create the browser with the initial URL.
CreateBrowser(expectations_->GetMainURL());
CreateBrowser(expectations_->GetMainURL(), NULL, extra_info);
// Time out the test after a reasonable period of time.
SetTestTimeout(15000);
@@ -2351,12 +2301,6 @@ FrameNavExpectationsFactoryRenderer::FromID(FrameNavFactoryId id) {
} // namespace
// Entry point for creating frame browser test objects.
// Called from client_app_delegates.cc.
void CreateFrameBrowserTests(ClientAppBrowser::DelegateSet& delegates) {
delegates.insert(new FrameNavBrowserTest);
}
// Entry point for creating frame renderer test objects.
// Called from client_app_delegates.cc.
void CreateFrameRendererTests(ClientAppRenderer::DelegateSet& delegates) {