chore: cherry-pick 11 changes from 3-M126 (#43141)

* chore: [30-x-y] cherry-pick 11 changes from 3-M126

* d54105311590 from chromium
* 43b8b682d05c from chromium
* c5dd8839bfaf from chromium
* cdbc1d9684a3 from v8
* 38e4483e47f9 from chromium
* 70d2fe6b7c47 from v8
* 901377bb2f3b from v8
* 1b9040817119 from chromium
* bb28367eed73 from v8
* 99cafbf4b4b9 from chromium
* bc545b15a0ee from v8

* chore: update patches

* 5639725: [wasm] Fix scanning of wasm-to-js params | 5639725

* 5672472: [M120-LTS] Prevent script injection on reload when racing with a navigation | 5672472
This commit is contained in:
Keeley Hammond 2024-08-02 01:11:51 -07:00 committed by GitHub
parent ec272f1e53
commit 1ec867c8a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1150 additions and 0 deletions

View file

@ -137,3 +137,9 @@ fix_font_face_resolution_when_renderer_is_blocked.patch
x11_use_localized_display_label_only_for_browser_process.patch
feat_enable_passing_exit_code_on_service_process_crash.patch
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
cherry-pick-d54105311590.patch
cherry-pick-43b8b682d05c.patch
cherry-pick-c5dd8839bfaf.patch
cherry-pick-38e4483e47f9.patch
cherry-pick-1b9040817119.patch
cherry-pick-99cafbf4b4b9.patch

View file

@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bryant Chandler <bryantchandler@chromium.org>
Date: Mon, 24 Jun 2024 17:28:53 +0000
Subject: Fix pointer tear down order problem
Holding a RenderFrameHost* in the `OnceBinding` isn't safe,
because the `RenderFrameHost` can be destroyed before the
binding. This CL changes the task strategy so that the
RenderFrameHost* doesn't need to be bound in a callback.
Tested using the repro steps in the bug and this change stops
it from reproducing.
Fixed: 347373236
Change-Id: Id639f317b0f37a508833aba9fe52ffc5c0ed590c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5640501
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Commit-Queue: Bryant Chandler <bryantchandler@chromium.org>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1318653}
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 65bee7132f6583cb64d774756423942382c8eed6..2c27db7ee49193cbf91158d576e29bb255378a3e 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -2887,25 +2887,19 @@ void MediaStreamManager::GetRawDeviceIdsOpenedForFrame(
RenderFrameHost* render_frame_host,
blink::mojom::MediaStreamType type,
GetRawDeviceIdsOpenedForFrameCallback callback) const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- CHECK(render_frame_host);
- auto collect_all_render_frame_host_ids = base::BindOnce(
- [](RenderFrameHost* render_frame_host) {
- base::flat_set<GlobalRenderFrameHostId> all_render_frame_host_ids;
- render_frame_host->ForEachRenderFrameHost(
- [&all_render_frame_host_ids](RenderFrameHost* render_frame_host) {
- all_render_frame_host_ids.insert(
- render_frame_host->GetGlobalId());
- });
- return all_render_frame_host_ids;
- },
- render_frame_host);
-
- GetUIThreadTaskRunner()->PostTaskAndReplyWithResult(
- FROM_HERE, std::move(collect_all_render_frame_host_ids),
- base::BindPostTaskToCurrentDefault(
- base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds,
- base::Unretained(this), type, std::move(callback))));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ base::flat_set<GlobalRenderFrameHostId> all_render_frame_host_ids;
+ render_frame_host->ForEachRenderFrameHost(
+ [&all_render_frame_host_ids](RenderFrameHost* render_frame_host) {
+ all_render_frame_host_ids.insert(render_frame_host->GetGlobalId());
+ });
+
+ GetIOThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds,
+ base::Unretained(this), type, std::move(callback),
+ all_render_frame_host_ids));
}
void MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b0b1d0aea5bf251411d0cab06562fd77d8d7c549..819c73370d6e6fc5e6ab24e78646a206b6a5873d 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -10808,12 +10808,9 @@ void WebContentsImpl::GetMediaCaptureRawDeviceIdsOpened(
return;
}
- GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrame,
- base::Unretained(media_stream_manager),
- GetPrimaryMainFrame(), type,
- base::BindPostTaskToCurrentDefault(std::move(callback))));
+ media_stream_manager->GetRawDeviceIdsOpenedForFrame(
+ GetPrimaryMainFrame(), type,
+ base::BindPostTaskToCurrentDefault(std::move(callback)));
}
} // namespace content

View file

@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Johannes Kron <kron@chromium.org>
Date: Wed, 19 Jun 2024 20:59:48 +0000
Subject: Use BindPostTask() + weak pointer in callback handler
The callback handler incorrectly accessed member objects directly which may
cause UAF. Avoid this by using BindPostTask() together with a weak pointer.
Fixed: 346898524
Change-Id: I9d03d6decfd0212af88d3d0d8d70f83f1081d2e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5639016
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Johannes Kron <kron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1317142}
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
index 4fb3e8eb5f34a7ee9e8b0f22a7c842129cdc31eb..e2710fba1a8d7a4cee6023558898c74706a9c189 100644
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
@@ -326,13 +326,18 @@ void OnStreamSample(gfx::ScopedInUseIOSurface io_surface,
destRectInFrame:dest_rect_in_frame
frameRate:requested_capture_format_->
frame_rate];
+
+ __block base::OnceCallback<void()> on_update_configuration_error =
+ base::BindPostTask(
+ device_task_runner_,
+ base::BindOnce(
+ &ScreenCaptureKitDeviceMac::OnUpdateConfigurationError,
+ weak_factory_.GetWeakPtr()));
[stream_
updateConfiguration:config
completionHandler:^(NSError* _Nullable error) {
if (error) {
- client()->OnError(
- media::VideoCaptureError::kScreenCaptureKitStreamError,
- FROM_HERE, "Error on updateConfiguration");
+ std::move(on_update_configuration_error).Run();
}
}];
}
@@ -361,6 +366,21 @@ void OnStreamError() {
FROM_HERE, "Stream delegate called didStopWithError");
}
}
+ void OnUpdateContentFilterCompleted(NSError* _Nullable error) {
+ DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
+ is_resetting_ = false;
+
+ if (error) {
+ client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
+ FROM_HERE,
+ "Error on updateContentFilter (fullscreen window).");
+ }
+ }
+ void OnUpdateConfigurationError() {
+ DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
+ client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
+ FROM_HERE, "Error on updateConfiguration");
+ }
// IOSurfaceCaptureDeviceBase:
void OnStart() override {
@@ -411,15 +431,16 @@ void ResetStreamTo(SCWindow* window) override {
SCContentFilter* filter =
[[SCContentFilter alloc] initWithDesktopIndependentWindow:window];
+ __block base::OnceCallback<void(NSError*)>
+ on_update_content_filter_completed = base::BindPostTask(
+ device_task_runner_,
+ base::BindOnce(
+ &ScreenCaptureKitDeviceMac::OnUpdateContentFilterCompleted,
+ weak_factory_.GetWeakPtr()));
+
[stream_ updateContentFilter:filter
completionHandler:^(NSError* _Nullable error) {
- is_resetting_ = false;
- if (error) {
- client()->OnError(
- media::VideoCaptureError::kScreenCaptureKitStreamError,
- FROM_HERE,
- "Error on updateContentFilter (fullscreen window).");
- }
+ std::move(on_update_content_filter_completed).Run(error);
}];
}

View file

@ -0,0 +1,264 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Philip Pfaffe <pfaffe@chromium.org>
Date: Tue, 18 Jun 2024 10:04:45 +0000
Subject: Prevent script injection on reload when racing with a navigation
DevTools passes the loaderId now when calling Page.reload, in order to
prevent accidentally reloading the wrong page when a navigation occurred
concurrently. It can still happen that the navigation kicks in in between the reload iniated in the browser and the script injection that happens in the renderer, which would run the injected script on the wrong target. We need to check the loaderId also on the renderer side.
Fixed: 341136300
Change-Id: I891fb37fa10e6789c8697a0f29bf7118788a9319
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5625857
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316330}
diff --git a/third_party/blink/renderer/core/inspector/build.gni b/third_party/blink/renderer/core/inspector/build.gni
index 2e9feebe066f938506d63d157be65828aa2a27c9..39de006f5f97f9e2a84ee4d38f7bb98e99c41924 100644
--- a/third_party/blink/renderer/core/inspector/build.gni
+++ b/third_party/blink/renderer/core/inspector/build.gni
@@ -138,6 +138,7 @@ blink_core_tests_inspector = [
"inspector_emulation_agent_test.cc",
"inspector_highlight_test.cc",
"inspector_history_test.cc",
+ "inspector_page_agent_unittest.cc",
"inspector_preload_agent_unittest.cc",
"inspector_media_context_impl_unittest.cc",
"inspector_session_state_test.cc",
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index 1825080b32ab6d7adb86236a389c08caf0b90c5c..f17565a6178c3f47037378faf965cd0f52cb0d26 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -479,6 +479,42 @@ String InspectorPageAgent::CachedResourceTypeJson(
return ResourceTypeJson(ToResourceType(cached_resource.GetType()));
}
+InspectorPageAgent::PageReloadScriptInjection::PageReloadScriptInjection(
+ InspectorAgentState& agent_state)
+ : pending_script_to_evaluate_on_load_once_(&agent_state,
+ /*default_value=*/{}),
+ target_url_for_pending_script_(&agent_state,
+ /*default_value=*/{}) {}
+
+void InspectorPageAgent::PageReloadScriptInjection::clear() {
+ script_to_evaluate_on_load_once_ = {};
+ pending_script_to_evaluate_on_load_once_.Set({});
+ target_url_for_pending_script_.Set({});
+}
+
+void InspectorPageAgent::PageReloadScriptInjection::SetPending(
+ String script,
+ const KURL& target_url) {
+ pending_script_to_evaluate_on_load_once_.Set(script);
+ target_url_for_pending_script_.Set(target_url.GetString().GetString());
+}
+
+void InspectorPageAgent::PageReloadScriptInjection::PromoteToLoadOnce() {
+ script_to_evaluate_on_load_once_ =
+ pending_script_to_evaluate_on_load_once_.Get();
+ target_url_for_active_script_ = target_url_for_pending_script_.Get();
+ pending_script_to_evaluate_on_load_once_.Set({});
+ target_url_for_pending_script_.Set({});
+}
+
+String InspectorPageAgent::PageReloadScriptInjection::GetScriptForInjection(
+ const KURL& target_url) {
+ if (target_url_for_active_script_ == target_url.GetString()) {
+ return script_to_evaluate_on_load_once_;
+ }
+ return {};
+}
+
InspectorPageAgent::InspectorPageAgent(
InspectedFrames* inspected_frames,
Client* client,
@@ -495,8 +531,6 @@ InspectorPageAgent::InspectorPageAgent(
screencast_enabled_(&agent_state_, /*default_value=*/false),
lifecycle_events_enabled_(&agent_state_, /*default_value=*/false),
bypass_csp_enabled_(&agent_state_, /*default_value=*/false),
- pending_script_to_evaluate_on_load_once_(&agent_state_,
- /*default_value=*/String()),
scripts_to_evaluate_on_load_(&agent_state_,
/*default_value=*/String()),
worlds_to_evaluate_on_load_(&agent_state_,
@@ -506,7 +540,8 @@ InspectorPageAgent::InspectorPageAgent(
/*default_value=*/false),
standard_font_size_(&agent_state_, /*default_value=*/0),
fixed_font_size_(&agent_state_, /*default_value=*/0),
- script_font_families_cbor_(&agent_state_, std::vector<uint8_t>()) {}
+ script_font_families_cbor_(&agent_state_, std::vector<uint8_t>()),
+ script_injection_on_load_(agent_state_) {}
void InspectorPageAgent::Restore() {
if (enabled_.Get())
@@ -545,8 +580,7 @@ protocol::Response InspectorPageAgent::enable() {
protocol::Response InspectorPageAgent::disable() {
agent_state_.ClearAllFields();
pending_isolated_worlds_.clear();
- script_to_evaluate_on_load_once_ = String();
- pending_script_to_evaluate_on_load_once_.Set(String());
+ script_injection_on_load_.clear();
instrumenting_agents_->RemoveInspectorPageAgent(this);
inspector_resource_content_loader_->Cancel(
resource_content_loader_client_id_);
@@ -672,8 +706,9 @@ protocol::Response InspectorPageAgent::setAdBlockingEnabled(bool enable) {
protocol::Response InspectorPageAgent::reload(
Maybe<bool> optional_bypass_cache,
Maybe<String> optional_script_to_evaluate_on_load) {
- pending_script_to_evaluate_on_load_once_.Set(
- optional_script_to_evaluate_on_load.value_or(""));
+ script_injection_on_load_.SetPending(
+ optional_script_to_evaluate_on_load.value_or(""),
+ inspected_frames_->Root()->Loader().GetDocumentLoader()->Url());
v8_session_->setSkipAllPauses(true);
v8_session_->resume(true /* terminate on resume */);
return protocol::Response::Success();
@@ -989,7 +1024,9 @@ void InspectorPageAgent::DidCreateMainWorldContext(LocalFrame* frame) {
EvaluateScriptOnNewDocument(*frame, key);
}
- if (script_to_evaluate_on_load_once_.empty()) {
+ String script = script_injection_on_load_.GetScriptForInjection(
+ frame->Loader().GetDocumentLoader()->Url());
+ if (script.empty()) {
return;
}
ScriptState* script_state = ToScriptStateForMainWorld(frame);
@@ -997,9 +1034,8 @@ void InspectorPageAgent::DidCreateMainWorldContext(LocalFrame* frame) {
return;
}
- v8_session_->evaluate(
- script_state->GetContext(),
- ToV8InspectorStringView(script_to_evaluate_on_load_once_));
+ v8_session_->evaluate(script_state->GetContext(),
+ ToV8InspectorStringView(script));
}
void InspectorPageAgent::EvaluateScriptOnNewDocument(
@@ -1049,9 +1085,7 @@ void InspectorPageAgent::LoadEventFired(LocalFrame* frame) {
void InspectorPageAgent::WillCommitLoad(LocalFrame*, DocumentLoader* loader) {
if (loader->GetFrame() == inspected_frames_->Root()) {
- script_to_evaluate_on_load_once_ =
- pending_script_to_evaluate_on_load_once_.Get();
- pending_script_to_evaluate_on_load_once_.Set(String());
+ script_injection_on_load_.PromoteToLoadOnce();
}
GetFrontend()->frameNavigated(BuildObjectForFrame(loader->GetFrame()),
protocol::Page::NavigationTypeEnum::Navigation);
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
index 6e6263beee810946d03934e7f707bb49a3177a2f..e7003baa895494bf61ad06f875d825ac9f53aec2 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
@@ -94,6 +94,22 @@ class CORE_EXPORT InspectorPageAgent final
kOtherResource
};
+ class CORE_EXPORT PageReloadScriptInjection {
+ private:
+ String script_to_evaluate_on_load_once_;
+ String target_url_for_active_script_;
+ InspectorAgentState::String pending_script_to_evaluate_on_load_once_;
+ InspectorAgentState::String target_url_for_pending_script_;
+
+ public:
+ explicit PageReloadScriptInjection(InspectorAgentState&);
+
+ void clear();
+ void SetPending(String script, const KURL& target_url);
+ void PromoteToLoadOnce();
+ String GetScriptForInjection(const KURL& target_url);
+ };
+
static bool CachedResourceContent(const Resource*,
String* result,
bool* base64_encoded);
@@ -307,7 +323,6 @@ class CORE_EXPORT InspectorPageAgent final
ad_script_identifiers_;
v8_inspector::V8InspectorSession* v8_session_;
Client* client_;
- String script_to_evaluate_on_load_once_;
Member<InspectorResourceContentLoader> inspector_resource_content_loader_;
int resource_content_loader_client_id_;
InspectorAgentState::Boolean intercept_file_chooser_;
@@ -315,7 +330,6 @@ class CORE_EXPORT InspectorPageAgent final
InspectorAgentState::Boolean screencast_enabled_;
InspectorAgentState::Boolean lifecycle_events_enabled_;
InspectorAgentState::Boolean bypass_csp_enabled_;
- InspectorAgentState::String pending_script_to_evaluate_on_load_once_;
InspectorAgentState::StringMap scripts_to_evaluate_on_load_;
InspectorAgentState::StringMap worlds_to_evaluate_on_load_;
InspectorAgentState::BooleanMap
@@ -323,6 +337,7 @@ class CORE_EXPORT InspectorPageAgent final
InspectorAgentState::Integer standard_font_size_;
InspectorAgentState::Integer fixed_font_size_;
InspectorAgentState::Bytes script_font_families_cbor_;
+ PageReloadScriptInjection script_injection_on_load_;
};
} // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b81f6b4735392f3f542ccbb2a114c2def185be1c
--- /dev/null
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc
@@ -0,0 +1,57 @@
+// 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 "third_party/blink/renderer/core/inspector/inspector_page_agent.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+class PageReloadScriptInjectionTest : public testing::Test {
+ protected:
+ blink::mojom::blink::DevToolsSessionStatePtr session_state_cookie_;
+ blink::InspectorAgentState agent_state_;
+ blink::InspectorPageAgent::PageReloadScriptInjection injection_;
+ blink::InspectorSessionState state_;
+
+ public:
+ PageReloadScriptInjectionTest()
+ : agent_state_("page"),
+ injection_(agent_state_),
+ state_(session_state_cookie_.Clone()) {}
+
+ void SetUp() override { agent_state_.InitFrom(&state_); }
+};
+
+TEST_F(PageReloadScriptInjectionTest, PromotesScript) {
+ blink::KURL url("http://example.com");
+ injection_.SetPending("script", url);
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+ injection_.PromoteToLoadOnce();
+ ASSERT_EQ(injection_.GetScriptForInjection(url), "script");
+ injection_.PromoteToLoadOnce();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+}
+
+TEST_F(PageReloadScriptInjectionTest, ClearsScript) {
+ blink::KURL url("http://example.com");
+ injection_.SetPending("script", url);
+ injection_.clear();
+ injection_.PromoteToLoadOnce();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+
+ injection_.SetPending("script", url);
+ injection_.PromoteToLoadOnce();
+ ASSERT_EQ(injection_.GetScriptForInjection(url), "script");
+ injection_.clear();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+}
+
+TEST_F(PageReloadScriptInjectionTest, ChecksLoaderId) {
+ blink::KURL url("http://example.com");
+ blink::KURL url2("about:blank");
+ injection_.SetPending("script", url);
+ injection_.PromoteToLoadOnce();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url2).empty());
+}

View file

@ -0,0 +1,166 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yann Dago <ydago@chromium.org>
Date: Mon, 8 Jul 2024 16:20:32 +0000
Subject: Ensure chrome://policy/test messages ignored when not supported
It was possible to go to chrome://policy and in the dev tools and send
the right message to set test policies even if the policy test page was disabled and/or unavailable because both pages share the same handler.
Bug: 338248595
Change-Id: If689325999cb108b2b71b2821d905e42efd3390d
Low-Coverage-Reason: TRIVIAL_CHANGE
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5679162
Auto-Submit: Yann Dago <ydago@chromium.org>
Reviewed-by: Rohit Rao <rohitrao@chromium.org>
Reviewed-by: Sergey Poromov <poromov@chromium.org>
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1324277}
diff --git a/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
index e27325a18087c8a01d21111f2fa0dd6e6da60023..a03c639b8654a5cbedccc3c38de4007dba084bf8 100644
--- a/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
@@ -8,6 +8,7 @@
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
+#include "chrome/browser/enterprise/browser_management/browser_management_service.h"
#include "chrome/browser/enterprise/browser_management/management_service_factory.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
@@ -270,6 +271,57 @@ class PolicyTestHandlerTest : public PlatformBrowserTest {
#endif
};
+IN_PROC_BROWSER_TEST_F(PolicyTestHandlerTest,
+ HandleSetLocalTestPoliciesNotSupported) {
+ // Ensure chrome://policy/test not supported.
+ policy::ScopedManagementServiceOverrideForTesting profile_management(
+ policy::ManagementServiceFactory::GetForProfile(GetProfile()),
+ policy::EnterpriseManagementAuthority::CLOUD);
+ std::unique_ptr<PolicyUIHandler> handler = SetUpHandler();
+ const std::string jsonString =
+ R"([
+ {"level": 0,"scope": 0,"source": 0, "namespace": "chrome",
+ "name": "AutofillAddressEnabled","value": false},
+ {"level": 1,"scope": 1,"source": 2, "namespace": "chrome",
+ "name": "CloudReportingEnabled","value": true}
+ ])";
+ const std::string revertAppliedPoliciesButtonDisabledJs =
+ R"(
+ document
+ .querySelector('#revert-applied-policies')
+ .disabled;
+ )";
+
+ base::Value::List list_args;
+
+ list_args.Append("setLocalTestPolicies");
+ list_args.Append(jsonString);
+ list_args.Append("{}");
+
+ // Open chrome://policy
+ ASSERT_TRUE(
+ content::NavigateToURL(web_contents(), GURL(chrome::kChromeUIPolicyURL)));
+ web_ui()->HandleReceivedMessage("setLocalTestPolicies", list_args);
+
+ base::RunLoop().RunUntilIdle();
+
+ const policy::PolicyNamespace chrome_namespace(policy::POLICY_DOMAIN_CHROME,
+ std::string());
+ policy::PolicyService* policy_service =
+ GetProfile()->GetProfilePolicyConnector()->policy_service();
+
+ // Check policies not applied
+ const policy::PolicyMap* policy_map =
+ &policy_service->GetPolicies(chrome_namespace);
+ ASSERT_TRUE(policy_map);
+
+ {
+ const policy::PolicyMap::Entry* entry =
+ policy_map->Get(policy::key::kAutofillAddressEnabled);
+ ASSERT_FALSE(entry);
+ }
+}
+
IN_PROC_BROWSER_TEST_F(PolicyTestHandlerTest,
HandleSetAndRevertLocalTestPolicies) {
if (!policy::utils::IsPolicyTestingEnabled(/*pref_service=*/nullptr,
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
index 0d13979009fc4df379432d5eea1a394607203615..1dc6ecc6bed91115be10021c0661f8d81456161b 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -49,6 +49,7 @@
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/browser/ui/webui/policy/policy_ui.h"
#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/channel_info.h"
#include "chrome/grit/branded_strings.h"
#include "components/crx_file/id_util.h"
#include "components/enterprise/browser/controller/browser_dm_token_storage.h"
@@ -69,6 +70,7 @@
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_scheduler.h"
#include "components/policy/core/common/policy_types.h"
+#include "components/policy/core/common/policy_utils.h"
#include "components/policy/core/common/remote_commands/remote_commands_service.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/core/common/schema_map.h"
@@ -316,6 +318,12 @@ void PolicyUIHandler::HandleCopyPoliciesJson(const base::Value::List& args) {
void PolicyUIHandler::HandleSetLocalTestPolicies(
const base::Value::List& args) {
std::string policies = args[1].GetString();
+ AllowJavascript();
+
+ if (!PolicyUI::ShouldLoadTestPage(Profile::FromWebUI(web_ui()))) {
+ ResolveJavascriptCallback(args[0], true);
+ return;
+ }
policy::LocalTestPolicyProvider* local_test_provider =
static_cast<policy::LocalTestPolicyProvider*>(
@@ -338,12 +346,14 @@ void PolicyUIHandler::HandleSetLocalTestPolicies(
->UseLocalTestPolicyProvider();
local_test_provider->LoadJsonPolicies(policies);
- AllowJavascript();
ResolveJavascriptCallback(args[0], true);
}
void PolicyUIHandler::HandleRevertLocalTestPolicies(
const base::Value::List& args) {
+ if (!PolicyUI::ShouldLoadTestPage(Profile::FromWebUI(web_ui()))) {
+ return;
+ }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
Profile::FromWebUI(web_ui())->GetPrefs()->ClearPref(
prefs::kUserCloudSigninPolicyResponseFromPolicyTestPage);
diff --git a/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm b/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
index 577caf2012e0cdcdcf5baa4c5a288119da40cabd..94466842c2faeb13fd0ae33ba619362f8a43cd06 100644
--- a/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
+++ b/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
@@ -220,6 +220,12 @@
const base::Value::List& args) {
std::string json_policies_string = args[1].GetString();
+ if (!PolicyUI::ShouldLoadTestPage(
+ ChromeBrowserState::FromWebUIIOS(web_ui()))) {
+ web_ui()->ResolveJavascriptCallback(args[0], true);
+ return;
+ }
+
policy::LocalTestPolicyProvider* local_test_provider =
static_cast<policy::LocalTestPolicyProvider*>(
GetApplicationContext()
@@ -238,6 +244,11 @@
void PolicyUIHandler::HandleRevertLocalTestPolicies(
const base::Value::List& args) {
+ if (!PolicyUI::ShouldLoadTestPage(
+ ChromeBrowserState::FromWebUIIOS(web_ui()))) {
+ return;
+ }
+
ChromeBrowserState::FromWebUIIOS(web_ui())
->GetPolicyConnector()
->RevertUseLocalTestPolicyProvider();

View file

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Wed, 19 Jun 2024 02:49:58 +0000
Subject: Destruct controller before referenced WebUI in CreateWebUIIfNeeded
Reset `controller` first before resetting `web_ui_`, since the
controller still has a pointer to `web_ui_`, to avoid referencing to
the already deleted `web_ui_` object from `controller`'s destructor.
Bug: 345640549
Change-Id: Ie9c193436b593845d8269605f68bf94bc75beed7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5624749
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316830}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 8a9beaf3bfb9fe5eca8ca6675c7c45b4b880db03..85041c38c8d2e84d780948a4dab94013ce39dfbe 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -10268,6 +10268,11 @@ void NavigationRequest::CreateWebUIIfNeeded(RenderFrameHostImpl* frame_host) {
bindings() != web_ui_->GetBindings()) {
RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
base::WeakPtr<NavigationRequest> self = GetWeakPtr();
+ // Reset `controller` first before resetting `web_ui_`, since the controller
+ // still has a pointer to `web_ui_`, to avoid referencing to the already
+ // deleted `web_ui_` object from `controller`'s destructor. See also
+ // https://crbug.com/345640549.
+ controller.reset();
web_ui_.reset();
// Resetting the WebUI may indirectly call content's embedders and delete
// `this`. There are no known occurrences of it, so we assume this never

View file

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "mark a. foltz" <mfoltz@chromium.org>
Date: Mon, 17 Jun 2024 23:07:32 +0000
Subject: Retain refptr to shared helper to prevent UAF.
Capture a reference to the shared helper in the onerror handler to
prevent a UAF that can occur when the browser drops the mojo
connection.
Bug: 346692546
Change-Id: Ifb264488a6fa8417c134a34d902605d2c141720b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5634908
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Mark Foltz <mfoltz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316145}
diff --git a/media/audio/mac/audio_loopback_input_mac_impl.mm b/media/audio/mac/audio_loopback_input_mac_impl.mm
index 7b301492f17a3f1da96b8ff990f6deeb4a19b6e3..f90c00e668f58c2389e622466422ae7aa237c94d 100644
--- a/media/audio/mac/audio_loopback_input_mac_impl.mm
+++ b/media/audio/mac/audio_loopback_input_mac_impl.mm
@@ -394,12 +394,15 @@ - (void)stream:(SCStream*)stream
base::BindRepeating(&SCKAudioInputStream::OnStreamError,
base::Unretained(this)));
+ // Make a local copy of the shared_refptr in case the error handler is called
+ // after `this` is destroyed.
+ auto local_shared_helper = shared_helper_;
[stream_ startCaptureWithCompletionHandler:^(NSError* error) {
if (!error) {
return;
}
- shared_helper_->OnStreamError(error);
+ local_shared_helper->OnStreamError(error);
}];
}

View file

@ -3,3 +3,8 @@ deps_add_v8_object_setinternalfieldfornodecore.patch
cherry-pick-8b400f9b7d66.patch
cherry-pick-ba6cab40612d.patch
merged_wasm_add_missing_type_canonicalization_for_exceptions_js.patch
cherry-pick-cdbc1d9684a3.patch
cherry-pick-70d2fe6b7c47.patch
cherry-pick-901377bb2f3b.patch
cherry-pick-bb28367eed73.patch
cherry-pick-bc545b15a0ee.patch

View file

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leszek Swirski <leszeks@chromium.org>
Date: Fri, 21 Jun 2024 15:11:40 +0200
Subject: Allow reduced hasInstance to abort
Fixed: 343507800
Change-Id: I579041fe82e975d83a72e4744013cb04c4d3dc70
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5644891
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94585}
diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
index efcdd6d2028a5e0f0ec1149925ab2e1fe5f90412..78f4dd57d339eaad8b265721ef37137291da7940 100644
--- a/src/maglev/maglev-graph-builder.cc
+++ b/src/maglev/maglev-graph-builder.cc
@@ -8639,10 +8639,9 @@ ReduceResult MaglevGraphBuilder::TryBuildFastInstanceOf(
if (has_instance_field->IsJSFunction()) {
SaveCallSpeculationScope saved(this);
- ReduceResult result =
- ReduceCallForConstant(has_instance_field->AsJSFunction(), args);
- DCHECK(!result.IsDoneWithAbort());
- call_result = result.value();
+ GET_VALUE_OR_ABORT(
+ call_result,
+ ReduceCallForConstant(has_instance_field->AsJSFunction(), args));
} else {
call_result = BuildGenericCall(GetConstant(*has_instance_field),
Call::TargetType::kAny, args);

View file

@ -0,0 +1,221 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thibaud Michaud <thibaudm@chromium.org>
Date: Fri, 21 Jun 2024 16:31:15 +0200
Subject: Fix scanning of wasm-to-js params
Wasm-to-js wrappers are sometimes compiled as on-heap Code objects, for
example when tiering-up from a WasmFuncRef call origin. The frames of
these functions are mapped to a subclass of TypedFrame, however
TypedFrame::Iterate() only supports iterating the generic wasm-to-js
wrapper.
Add support for iterating the tagged parameters of optimized wasm-to-js
wrappers in TypedFrame::Iterate. For this we also add two 16-bit fields
in the Code object to encode the incoming tagged parameter region, which
we would normally find in the WasmCode data.
R=jkummerow@chromium.org
Fixed: 346597059
Change-Id: I425619fca86c38f91f1ca9cbeb70e7b5a7b2d6c1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5639725
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94589}
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index 0181588337df73bfa97220d895733c40b92bd40b..033469e626ffb35846ae5114632f3dc000400935 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -2295,6 +2295,14 @@ CompilationJob::Status FinalizeWrapperCompilation(
Handle<AbstractCode>::cast(code),
info->GetDebugName().get()));
}
+ // Set the wasm-to-js specific code fields needed to scan the incoming stack
+ // parameters.
+ if (code->kind() == CodeKind::WASM_TO_JS_FUNCTION) {
+ code->set_wasm_js_tagged_parameter_count(
+ call_descriptor->GetTaggedParameterSlots() & 0xffff);
+ code->set_wasm_js_first_tagged_parameter(
+ call_descriptor->GetTaggedParameterSlots() >> 16);
+ }
return CompilationJob::SUCCEEDED;
}
return CompilationJob::FAILED;
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
index 7677022ce31c1b8ead0cc2eb37fb505b750639be..12bd5b8fd27f67c73938550acc4af1857eace59a 100644
--- a/src/diagnostics/objects-printer.cc
+++ b/src/diagnostics/objects-printer.cc
@@ -2102,7 +2102,14 @@ void Code::CodePrint(std::ostream& os, const char* name, Address current_pc) {
os << "\n - instruction_size: " << instruction_size();
os << "\n - metadata_size: " << metadata_size();
- os << "\n - inlined_bytecode_size: " << inlined_bytecode_size();
+ if (kind() != CodeKind::WASM_TO_JS_FUNCTION) {
+ os << "\n - inlined_bytecode_size: " << inlined_bytecode_size();
+ } else {
+ os << "\n - wasm_js_tagged_parameter_count: "
+ << wasm_js_tagged_parameter_count();
+ os << "\n - wasm_js_first_tagged_parameter: "
+ << wasm_js_first_tagged_parameter();
+ }
os << "\n - osr_offset: " << osr_offset();
os << "\n - handler_table_offset: " << handler_table_offset();
os << "\n - unwinding_info_offset: " << unwinding_info_offset();
diff --git a/src/execution/frames.cc b/src/execution/frames.cc
index 92dff2f7e8c8f72e38eef4feb5b10ace9fe2535c..2693fb2a859dc7489ef802c3064beace88608415 100644
--- a/src/execution/frames.cc
+++ b/src/execution/frames.cc
@@ -1562,7 +1562,7 @@ void WasmFrame::Iterate(RootVisitor* v) const {
frame_header_limit);
}
-void TypedFrame::IterateParamsOfWasmToJSWrapper(RootVisitor* v) const {
+void TypedFrame::IterateParamsOfGenericWasmToJSWrapper(RootVisitor* v) const {
Tagged<Object> maybe_signature = Tagged<Object>(
Memory<Address>(fp() + WasmToJSWrapperConstants::kSignatureOffset));
if (IsSmi(maybe_signature)) {
@@ -1678,6 +1678,18 @@ void TypedFrame::IterateParamsOfWasmToJSWrapper(RootVisitor* v) const {
}
}
}
+
+void TypedFrame::IterateParamsOfOptimizedWasmToJSWrapper(RootVisitor* v) const {
+ Tagged<GcSafeCode> code = GcSafeLookupCode();
+ if (code->wasm_js_tagged_parameter_count() > 0) {
+ FullObjectSlot tagged_parameter_base(&Memory<Address>(caller_sp()));
+ tagged_parameter_base += code->wasm_js_first_tagged_parameter();
+ FullObjectSlot tagged_parameter_limit =
+ tagged_parameter_base + code->wasm_js_tagged_parameter_count();
+ v->VisitRootPointers(Root::kStackRoots, nullptr, tagged_parameter_base,
+ tagged_parameter_limit);
+ }
+}
#endif // V8_ENABLE_WEBASSEMBLY
void TypedFrame::Iterate(RootVisitor* v) const {
@@ -1709,10 +1721,13 @@ void TypedFrame::Iterate(RootVisitor* v) const {
CHECK(entry->code.has_value());
Tagged<GcSafeCode> code = entry->code.value();
#if V8_ENABLE_WEBASSEMBLY
- bool is_wasm_to_js =
+ bool is_generic_wasm_to_js =
code->is_builtin() && code->builtin_id() == Builtin::kWasmToJsWrapperCSA;
- if (is_wasm_to_js) {
- IterateParamsOfWasmToJSWrapper(v);
+ bool is_optimized_wasm_to_js = this->type() == WASM_TO_JS_FUNCTION;
+ if (is_generic_wasm_to_js) {
+ IterateParamsOfGenericWasmToJSWrapper(v);
+ } else if (is_optimized_wasm_to_js) {
+ IterateParamsOfOptimizedWasmToJSWrapper(v);
}
#endif // V8_ENABLE_WEBASSEMBLY
DCHECK(code->is_turbofanned());
@@ -1745,10 +1760,14 @@ void TypedFrame::Iterate(RootVisitor* v) const {
// wrapper switched to before pushing the outgoing stack parameters and
// calling the target. It marks the limit of the stack param area, and is
// distinct from the beginning of the spill area.
- Address central_stack_sp =
- Memory<Address>(fp() + WasmToJSWrapperConstants::kCentralStackSPOffset);
+ int central_stack_sp_offset =
+ is_generic_wasm_to_js
+ ? WasmToJSWrapperConstants::kCentralStackSPOffset
+ : WasmImportWrapperFrameConstants::kCentralStackSPOffset;
+ Address central_stack_sp = Memory<Address>(fp() + central_stack_sp_offset);
FullObjectSlot parameters_limit(
- is_wasm_to_js && central_stack_sp != kNullAddress
+ (is_generic_wasm_to_js || is_optimized_wasm_to_js) &&
+ central_stack_sp != kNullAddress
? central_stack_sp
: frame_header_base.address() - spill_slots_size);
#else
diff --git a/src/execution/frames.h b/src/execution/frames.h
index 081c74bf124ccfa57e4b40f75cbe42b00c771b2e..908239b4161235aeda04fe5526ddea8d56b09425 100644
--- a/src/execution/frames.h
+++ b/src/execution/frames.h
@@ -634,7 +634,8 @@ class TypedFrame : public CommonFrame {
Tagged<HeapObject> unchecked_code() const override { return {}; }
void Iterate(RootVisitor* v) const override;
- void IterateParamsOfWasmToJSWrapper(RootVisitor* v) const;
+ void IterateParamsOfGenericWasmToJSWrapper(RootVisitor* v) const;
+ void IterateParamsOfOptimizedWasmToJSWrapper(RootVisitor* v) const;
protected:
inline explicit TypedFrame(StackFrameIteratorBase* iterator);
diff --git a/src/objects/code-inl.h b/src/objects/code-inl.h
index baaced29afdbc87eae1c34b8df779e17e41410c4..1e1d66a87ee633cbdb49265444f53b5db790d9dd 100644
--- a/src/objects/code-inl.h
+++ b/src/objects/code-inl.h
@@ -48,6 +48,8 @@ GCSAFE_CODE_FWD_ACCESSOR(bool, has_tagged_outgoing_params)
GCSAFE_CODE_FWD_ACCESSOR(bool, marked_for_deoptimization)
GCSAFE_CODE_FWD_ACCESSOR(Tagged<Object>, raw_instruction_stream)
GCSAFE_CODE_FWD_ACCESSOR(int, stack_slots)
+GCSAFE_CODE_FWD_ACCESSOR(uint16_t, wasm_js_tagged_parameter_count)
+GCSAFE_CODE_FWD_ACCESSOR(uint16_t, wasm_js_first_tagged_parameter)
GCSAFE_CODE_FWD_ACCESSOR(Address, constant_pool)
GCSAFE_CODE_FWD_ACCESSOR(Address, safepoint_table_address)
#undef GCSAFE_CODE_FWD_ACCESSOR
@@ -428,6 +430,31 @@ void Code::set_inlined_bytecode_size(unsigned size) {
RELAXED_WRITE_UINT_FIELD(*this, kInlinedBytecodeSizeOffset, size);
}
+// For optimized on-heap wasm-js wrappers, we repurpose the (otherwise unused)
+// 32-bit InlinedBytecodeSize field to encode two 16 values needed for scanning
+// the frame: the count and starting offset of incoming tagged parameters.
+// TODO(wasm): Eventually the wrappers should be managed off-heap by the wasm
+// engine. Remove these accessors when that is the case.
+void Code::set_wasm_js_tagged_parameter_count(uint16_t count) {
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
+ RELAXED_WRITE_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset, count);
+}
+
+uint16_t Code::wasm_js_tagged_parameter_count() const {
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
+ return RELAXED_READ_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset);
+}
+
+void Code::set_wasm_js_first_tagged_parameter(uint16_t count) {
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
+ RELAXED_WRITE_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset + 2, count);
+}
+
+uint16_t Code::wasm_js_first_tagged_parameter() const {
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
+ return RELAXED_READ_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset + 2);
+}
+
BytecodeOffset Code::osr_offset() const {
return BytecodeOffset(RELAXED_READ_INT32_FIELD(*this, kOsrOffsetOffset));
}
diff --git a/src/objects/code.h b/src/objects/code.h
index 9a079a94ba0126b24532362a0ce233477f42c221..1da011899807125d6dc9ffb6d56622f5f15ad465 100644
--- a/src/objects/code.h
+++ b/src/objects/code.h
@@ -124,6 +124,15 @@ class Code : public ExposedTrustedObject {
// [deoptimization_data]: Array containing data for deopt for non-baseline
// code.
DECL_ACCESSORS(deoptimization_data, Tagged<TrustedFixedArray>)
+ // [parameter_count]: The number of formal parameters, including the
+ // receiver. Currently only available for optimized functions.
+ // TODO(saelo): make this always available. This is just a matter of figuring
+ // out how to obtain the parameter count during code generation when no
+ // BytecodeArray is available from which it can be copied.
+ DECL_PRIMITIVE_ACCESSORS(parameter_count, uint16_t)
+ inline uint16_t parameter_count_without_receiver() const;
+ DECL_PRIMITIVE_ACCESSORS(wasm_js_tagged_parameter_count, uint16_t)
+ DECL_PRIMITIVE_ACCESSORS(wasm_js_first_tagged_parameter, uint16_t)
// Whether this type of Code uses deoptimization data, in which case the
// deoptimization_data field will be populated.
@@ -503,6 +512,10 @@ class GcSafeCode : public HeapObject {
inline bool CanDeoptAt(Isolate* isolate, Address pc) const;
inline Tagged<Object> raw_instruction_stream(
PtrComprCageBase code_cage_base) const;
+ // The two following accessors repurpose the InlinedBytecodeSize field, see
+ // comment in code-inl.h.
+ inline uint16_t wasm_js_tagged_parameter_count() const;
+ inline uint16_t wasm_js_first_tagged_parameter() const;
private:
OBJECT_CONSTRUCTORS(GcSafeCode, HeapObject);

View file

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olivier=20Fl=C3=BCckiger?= <olivf@chromium.org>
Date: Mon, 24 Jun 2024 16:22:09 +0200
Subject: Fix skipped smi check due to phi hoisting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Given we have a phi (29) assumed to be smi at graph building time, we
must not untag it's input phis (10,12) to float64.
╭─────►Block b2
│ 10: φᵀ r0 (n4, n29) (compressed) → (x), 3 uses
│ 12: φᵀ r2 (n6, n39) (compressed) → (x), 6 uses
...
│ 13: CheckedSmiUntag [n10:(x)] → (x), 2 uses
│ 14: CheckedSmiUntag [n12:(x)] → (x), 1 uses
...
│╭──────17: BranchIfToBooleanTrue [n16:(x)] b3 b9
...
││ │ 29: φᵀ <accumulator> (n10, n12) (compressed) → (x), 4 uses
...
││ │ 33: UnsafeSmiUntag [n29:(x)] → (x), 1 uses
Doing so could invalidate the `UnsafeSmiUntag` instruction.
This can only happen when hoisting the untagging out of the loop, as
this will remove the original `CheckedSmiUntag` instruction.
Fixed: 348567825
Change-Id: I2d7f2c3b544f991be9850d44bf11c3f632a0bb46
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5645901
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Auto-Submit: Olivier Flückiger <olivf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94615}
diff --git a/src/maglev/maglev-phi-representation-selector.cc b/src/maglev/maglev-phi-representation-selector.cc
index 02e030bcb543287433c944e5f298998cdc5b7ce9..cabe3a29383b111fc0f1568a40d439e1513bc154 100644
--- a/src/maglev/maglev-phi-representation-selector.cc
+++ b/src/maglev/maglev-phi-representation-selector.cc
@@ -285,6 +285,14 @@ MaglevPhiRepresentationSelector::ProcessPhi(Phi* node) {
ValueRepresentation::kHoleyFloat64};
}
+ // When hoisting we must ensure that we don't turn a tagged flowing into
+ // CheckedSmiUntag into a float64. This would cause us to loose the smi check
+ // which in turn can invalidate assumptions on aliasing values.
+ if (hoist_untagging.size() && node->uses_require_31_bit_value()) {
+ allowed_inputs_for_uses.Remove(
+ {ValueRepresentation::kFloat64, ValueRepresentation::kHoleyFloat64});
+ }
+
auto intersection = possible_inputs & allowed_inputs_for_uses;
TRACE_UNTAGGING(" + intersection reprs: " << intersection);
@@ -615,6 +623,7 @@ void MaglevPhiRepresentationSelector::ConvertTaggedPhiTo(
TaggedToFloat64ConversionType::kOnlyNumber),
block, NewNodePosition::kEnd);
} else {
+ DCHECK(!phi->uses_require_31_bit_value());
untagged = AddNode(NodeBase::New<CheckedNumberOrOddballToFloat64>(
builder_->zone(), {input},
TaggedToFloat64ConversionType::kOnlyNumber),

View file

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakob Kummerow <jkummerow@chromium.org>
Date: Thu, 11 Jul 2024 16:34:00 +0200
Subject: Fix cast of memory index
"uint8_t" must have been a typo.
Fixed: 351327767
Bug: 42203854
Change-Id: I196c961ec2f2ed16acfe16bf304d7eae6551aacc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5695665
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94981}
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
index 16f1f1470b782ce3584ba4bb6626501c9f9551b7..02364fdf5d3d17fa0f03fd48d21523a4bae3f21e 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -3395,7 +3395,7 @@ Node* WasmGraphBuilder::MemStart(uint32_t mem_index) {
DCHECK_NOT_NULL(instance_cache_);
V8_ASSUME(cached_memory_index_ == kNoCachedMemoryIndex ||
cached_memory_index_ >= 0);
- if (mem_index == static_cast<uint8_t>(cached_memory_index_)) {
+ if (mem_index == static_cast<uint32_t>(cached_memory_index_)) {
return instance_cache_->mem_start;
}
return LoadMemStart(mem_index);
@@ -3405,7 +3405,7 @@ Node* WasmGraphBuilder::MemSize(uint32_t mem_index) {
DCHECK_NOT_NULL(instance_cache_);
V8_ASSUME(cached_memory_index_ == kNoCachedMemoryIndex ||
cached_memory_index_ >= 0);
- if (mem_index == static_cast<uint8_t>(cached_memory_index_)) {
+ if (mem_index == static_cast<uint32_t>(cached_memory_index_)) {
return instance_cache_->mem_size;
}

View file

@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darius Mercadier <dmercadier@chromium.org>
Date: Tue, 18 Jun 2024 16:10:26 +0200
Subject: Lower LoadStackArgument to a Tagged load
If we start with a graph that looks like
```
x = LoadStackArgument(a, 40)
...
Allocate()
...
y = LoadStackArgument(a, 40)
```
This used to be lowered to
```
x1 = Load<WordPtr>(a, 40)
x2 = TaggedBitcast(x1, WordPtr->Tagged)
...
Allocate()
...
y1 = Load<WordPtr>(a, 40)
y2 = TaggedBitcast(y1, WordPtr->Tagged)
```
And then, Load Elimination would remove the second Load, and we'd get:
```
x1 = Load<WordPtr>(a, 40)
x2 = TaggedBitcast(x1, WordPtr->Tagged)
...
Allocate()
...
y2 = TaggedBitcast(x1, WordPtr->Tagged)
```
And now we would be in trouble: if the allocation in the middle
triggers a GC, then `x1` could move, and thus `y2` could refer to a
stale pointer. In theory, Turbofan knows where tagged values are, and
can thus update them when the GC moves things, but here, `x1` is not
marked as Tagged (but rather as a raw WordPtr).
This CL fixes this issue by doing a Tagged load from the start, since
the value we're loading is clearly tagged.
Fixed: chromium:347724915
Change-Id: Ia659155fbc602907ab9a50fb992c79df6ccdaa44
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5630530
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94527}
diff --git a/src/compiler/turboshaft/machine-lowering-reducer-inl.h b/src/compiler/turboshaft/machine-lowering-reducer-inl.h
index 8f37ef00f7edc1395586439fad4c39f426520d87..1f8ecb428f7d53d20369b82d958b2309ab09d2eb 100644
--- a/src/compiler/turboshaft/machine-lowering-reducer-inl.h
+++ b/src/compiler/turboshaft/machine-lowering-reducer-inl.h
@@ -2372,9 +2372,17 @@ class MachineLoweringReducer : public Next {
}
V<Object> REDUCE(LoadStackArgument)(V<WordPtr> base, V<WordPtr> index) {
- V<WordPtr> argument = __ template LoadNonArrayBufferElement<WordPtr>(
- base, AccessBuilder::ForStackArgument(), index);
- return __ BitcastWordPtrToTagged(argument);
+ // Note that this is a load of a Tagged value
+ // (MemoryRepresentation::TaggedPointer()), but since it's on the stack
+ // where stack slots are all kSystemPointerSize, we use kSystemPointerSize
+ // for element_size_log2. On 64-bit plateforms with pointer compression,
+ // this means that we're kinda loading a 32-bit value from an array of
+ // 64-bit values.
+ return __ Load(
+ base, index, LoadOp::Kind::RawAligned(),
+ MemoryRepresentation::TaggedPointer(),
+ CommonFrameConstants::kFixedFrameSizeAboveFp - kSystemPointerSize,
+ kSystemPointerSizeLog2);
}
OpIndex REDUCE(StoreTypedElement)(OpIndex buffer, V<Object> base,
diff --git a/test/mjsunit/compiler/regress-347724915.js b/test/mjsunit/compiler/regress-347724915.js
new file mode 100644
index 0000000000000000000000000000000000000000..4a5d1a9a2e3dd7674bf0872c94a971b5f28ddf72
--- /dev/null
+++ b/test/mjsunit/compiler/regress-347724915.js
@@ -0,0 +1,26 @@
+// Copyright 2024 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function f(...args) {
+ let arr1 = [ undefined, undefined, undefined ];
+ %SimulateNewspaceFull();
+ arr1[0] = args[0];
+ // The following allocation will trigger a full GC, which will move the
+ // argument passed to the function (because it was a young object).
+ let arr2 = [ arr1 ];
+ // Here we're accessing `args[0]` again. This might be load-eliminated with
+ // the `args[0]` load from a few lines above, which has been moved by the GC
+ // since then. This should be fine though, as the loaded value should be
+ // marked as Tagged, which means that it shouldn't point to the stale value
+ // but instead have been updated during GC.
+ arr1[1] = args[0]
+ return arr2;
+}
+
+%PrepareFunctionForOptimization(f);
+let expected = f({ x : 42 });
+%OptimizeFunctionOnNextCall(f);
+assertEquals(expected, f({x : 42}));