summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhenyao Mo <zmo@chromium.org>2023-03-06 22:54:01 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-05-02 08:58:59 +0000
commitd82c07428deb6d22b3cfbd41e891b094145efe7e (patch)
tree8f6e607403819cac92c34ec5ef2c203a8ea11921
parentfc2d84dc7a8642f3ce5d0fda565ee3b6f7debbcb (diff)
downloadqtwebengine-chromium-d82c07428deb6d22b3cfbd41e891b094145efe7e.tar.gz
[Backport] CVE-2023-1818: Use after free in Vulkan. (2/2)
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/4242104: Enable GPU watchdog for SwiftShader. At a longer timeout. R=magchen@chromium.org,geofflang@chromium.org TEST=bots Bug: 1223346 Change-Id: Ic8b7f5e77eae5257711d9c210c4ede1816b834be Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4242104 Commit-Queue: Zhenyao Mo <zmo@chromium.org> Reviewed-by: Maggie Chen <magchen@chromium.org> Reviewed-by: Kyle Charbonneau <kylechar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1113632} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/474369 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/components/viz/service/display_embedder/compositor_gpu_thread.cc13
-rw-r--r--chromium/components/viz/service/display_embedder/compositor_gpu_thread.h2
-rw-r--r--chromium/gpu/ipc/common/gpu_watchdog_timeout.h3
-rw-r--r--chromium/gpu/ipc/service/gpu_init.cc79
-rw-r--r--chromium/gpu/ipc/service/gpu_watchdog_thread.cc35
-rw-r--r--chromium/gpu/ipc/service/gpu_watchdog_thread.h8
6 files changed, 93 insertions, 47 deletions
diff --git a/chromium/components/viz/service/display_embedder/compositor_gpu_thread.cc b/chromium/components/viz/service/display_embedder/compositor_gpu_thread.cc
index e5cb55b8511..d4509649b1b 100644
--- a/chromium/components/viz/service/display_embedder/compositor_gpu_thread.cc
+++ b/chromium/components/viz/service/display_embedder/compositor_gpu_thread.cc
@@ -221,9 +221,9 @@ bool CompositorGpuThread::Initialize() {
StartWithOptions(std::move(thread_options));
// Wait until thread is started and Init() is executed in order to return
- // updated |init_succeded_|.
+ // updated |init_succeeded_|.
WaitUntilThreadStarted();
- return init_succeded_;
+ return init_succeeded_;
}
void CompositorGpuThread::HandleMemoryPressure(
@@ -239,12 +239,11 @@ void CompositorGpuThread::HandleMemoryPressure(
void CompositorGpuThread::Init() {
const auto& gpu_preferences = gpu_channel_manager_->gpu_preferences();
- if (enable_watchdog_) {
+ if (enable_watchdog_ && gpu_channel_manager_->watchdog()) {
watchdog_thread_ = gpu::GpuWatchdogThread::Create(
- gpu_preferences.watchdog_starts_backgrounded, "GpuWatchdog_Compositor");
+ gpu_preferences.watchdog_starts_backgrounded,
+ gpu_channel_manager_->watchdog(), "GpuWatchdog_Compositor");
- if (!watchdog_thread_)
- return;
watchdog_thread_->OnInitComplete();
}
@@ -254,7 +253,7 @@ void CompositorGpuThread::Init() {
memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
FROM_HERE, base::BindRepeating(&CompositorGpuThread::HandleMemoryPressure,
base::Unretained(this))),
- init_succeded_ = true;
+ init_succeeded_ = true;
}
void CompositorGpuThread::CleanUp() {
diff --git a/chromium/components/viz/service/display_embedder/compositor_gpu_thread.h b/chromium/components/viz/service/display_embedder/compositor_gpu_thread.h
index 86b2a0e5c03..6c9f60427e4 100644
--- a/chromium/components/viz/service/display_embedder/compositor_gpu_thread.h
+++ b/chromium/components/viz/service/display_embedder/compositor_gpu_thread.h
@@ -87,7 +87,7 @@ class VIZ_SERVICE_EXPORT CompositorGpuThread
raw_ptr<gpu::GpuChannelManager> gpu_channel_manager_;
const bool enable_watchdog_;
- bool init_succeded_ = false;
+ bool init_succeeded_ = false;
scoped_refptr<VulkanContextProvider> vulkan_context_provider_;
diff --git a/chromium/gpu/ipc/common/gpu_watchdog_timeout.h b/chromium/gpu/ipc/common/gpu_watchdog_timeout.h
index f673ec47381..35d7572275d 100644
--- a/chromium/gpu/ipc/common/gpu_watchdog_timeout.h
+++ b/chromium/gpu/ipc/common/gpu_watchdog_timeout.h
@@ -43,6 +43,9 @@ constexpr int kInitFactor = 2;
constexpr int kInitFactor = 1;
#endif
+// Software rasterizer runs slower than hardware accelerated.
+constexpr int kSoftwareRenderingFactor = 2;
+
} // namespace gpu
#endif // GPU_IPC_COMMON_GPU_WATCHDOG_TIMEOUT_H_
diff --git a/chromium/gpu/ipc/service/gpu_init.cc b/chromium/gpu/ipc/service/gpu_init.cc
index e0e03b53ba9..579ed26b93b 100644
--- a/chromium/gpu/ipc/service/gpu_init.cc
+++ b/chromium/gpu/ipc/service/gpu_init.cc
@@ -345,9 +345,27 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
}
}
+ if (!gl_use_swiftshader_) {
+ gl_use_swiftshader_ = EnableSwiftShaderIfNeeded(
+ command_line, gpu_feature_info_,
+ gpu_preferences_.disable_software_rasterizer, needs_more_info);
+ }
+
+ if (gl_initialized && gl_use_swiftshader_ &&
+ !gl::IsSoftwareGLImplementation(gl::GetGLImplementationParts())) {
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+ VLOG(1) << "Quit GPU process launch to fallback to SwiftShader cleanly "
+ << "on Linux";
+ return false;
+#else // !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
+ SaveHardwareGpuInfoAndGpuFeatureInfo();
+ gl::init::ShutdownGL(nullptr, true);
+ gl_initialized = false;
+#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+ }
+
bool enable_watchdog = !gpu_preferences_.disable_gpu_watchdog &&
- !command_line->HasSwitch(switches::kHeadless) &&
- !gl_use_swiftshader_;
+ !command_line->HasSwitch(switches::kHeadless);
// Disable the watchdog in debug builds because they tend to only be run by
// developers who will not appreciate the watchdog killing the GPU process.
@@ -386,7 +404,10 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
// consuming has completed, otherwise the process is liable to be aborted.
if (enable_watchdog && !delayed_watchdog_enable) {
watchdog_thread_ = GpuWatchdogThread::Create(
- gpu_preferences_.watchdog_starts_backgrounded, "GpuWatchdog");
+ gpu_preferences_.watchdog_starts_backgrounded,
+ gl_use_swiftshader_ ||
+ gl::IsSoftwareGLImplementation(gl::GetGLImplementationParts()),
+ "GpuWatchdog");
watchdog_init.SetGpuWatchdogPtr(watchdog_thread_.get());
}
@@ -432,25 +453,6 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
->GetSupportedFormatsForTexturing();
#endif // defined(USE_OZONE)
- if (!gl_use_swiftshader_) {
- gl_use_swiftshader_ = EnableSwiftShaderIfNeeded(
- command_line, gpu_feature_info_,
- gpu_preferences_.disable_software_rasterizer, needs_more_info);
- }
-
- if (gl_initialized && gl_use_swiftshader_ &&
- !gl::IsSoftwareGLImplementation(gl::GetGLImplementationParts())) {
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- VLOG(1) << "Quit GPU process launch to fallback to SwiftShader cleanly "
- << "on Linux";
- return false;
-#else // !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
- SaveHardwareGpuInfoAndGpuFeatureInfo();
- gl::init::ShutdownGL(nullptr, true);
- gl_initialized = false;
-#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- }
-
gl::GLDisplay* gl_display = nullptr;
if (!gl_initialized) {
@@ -558,8 +560,14 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
#else
SaveHardwareGpuInfoAndGpuFeatureInfo();
gl::init::ShutdownGL(gl_display, true);
- watchdog_thread_ = nullptr;
- watchdog_init.SetGpuWatchdogPtr(nullptr);
+ if (watchdog_thread_.get()) {
+ watchdog_thread_ = nullptr;
+ watchdog_init.SetGpuWatchdogPtr(nullptr);
+ watchdog_thread_ = GpuWatchdogThread::Create(
+ gpu_preferences_.watchdog_starts_backgrounded,
+ /*software_rendering=*/true, "GpuWatchdog");
+ watchdog_init.SetGpuWatchdogPtr(watchdog_thread_.get());
+ }
gl_display = gl::init::InitializeGLNoExtensionsOneOff(
/*init_bindings=*/true, system_device_id);
if (!gl_display) {
@@ -719,8 +727,8 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
UMA_HISTOGRAM_MEDIUM_TIMES("GPU.InitializeOneOffMediumTime",
elapsed_timer.Elapsed());
- // SwANGLE is expected to run slowly, so disable the watchdog
- // in that case.
+ bool recreate_watchdog = false;
+
if (!gl_use_swiftshader_ && command_line->HasSwitch(switches::kUseGL)) {
std::string use_gl = command_line->GetSwitchValueASCII(switches::kUseGL);
std::string use_angle =
@@ -729,6 +737,9 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
(use_angle == gl::kANGLEImplementationSwiftShaderName ||
use_angle == gl::kANGLEImplementationSwiftShaderForWebGLName)) {
gl_use_swiftshader_ = true;
+ if (watchdog_thread_) {
+ recreate_watchdog = true;
+ }
}
}
#if BUILDFLAG(IS_LINUX) || \
@@ -739,19 +750,27 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
// process's address space. Using swiftshader helps ensure that doesn't
// happen and keeps Chrome and linux-chromeos usable with rr.
gl_use_swiftshader_ = true;
+ if (watchdog_thread_) {
+ recreate_watchdog = true;
+ }
}
#endif
if (gl_use_swiftshader_ ||
gl::IsSoftwareGLImplementation(gl::GetGLImplementationParts())) {
gpu_info_.software_rendering = true;
- watchdog_thread_ = nullptr;
- watchdog_init.SetGpuWatchdogPtr(nullptr);
} else if (gl_disabled) {
+ DCHECK(!recreate_watchdog);
watchdog_thread_ = nullptr;
watchdog_init.SetGpuWatchdogPtr(nullptr);
} else if (enable_watchdog && delayed_watchdog_enable) {
- watchdog_thread_ = GpuWatchdogThread::Create(
- gpu_preferences_.watchdog_starts_backgrounded, "GpuWatchdog");
+ recreate_watchdog = true;
+ }
+ if (recreate_watchdog) {
+ watchdog_thread_ = nullptr;
+ watchdog_init.SetGpuWatchdogPtr(nullptr);
+ watchdog_thread_ =
+ GpuWatchdogThread::Create(gpu_preferences_.watchdog_starts_backgrounded,
+ gpu_info_.software_rendering, "GpuWatchdog");
watchdog_init.SetGpuWatchdogPtr(watchdog_thread_.get());
}
diff --git a/chromium/gpu/ipc/service/gpu_watchdog_thread.cc b/chromium/gpu/ipc/service/gpu_watchdog_thread.cc
index 6371fca14d3..5fe6a7ac35b 100644
--- a/chromium/gpu/ipc/service/gpu_watchdog_thread.cc
+++ b/chromium/gpu/ipc/service/gpu_watchdog_thread.cc
@@ -37,7 +37,7 @@
namespace gpu {
-base::TimeDelta GetGpuWatchdogTimeout() {
+base::TimeDelta GetGpuWatchdogTimeout(bool software_rendering) {
std::string timeout_str =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kGpuWatchdogTimeoutSeconds);
@@ -50,17 +50,21 @@ base::TimeDelta GetGpuWatchdogTimeout() {
<< timeout_str;
}
+ base::TimeDelta timeout = kGpuWatchdogTimeout;
#if BUILDFLAG(IS_WIN)
if (base::win::GetVersion() >= base::win::Version::WIN10) {
int num_of_processors = base::SysInfo::NumberOfProcessors();
- if (num_of_processors > 8)
- return (kGpuWatchdogTimeout - base::Seconds(10));
- else if (num_of_processors <= 4)
- return kGpuWatchdogTimeout + base::Seconds(5);
- }
+ if (num_of_processors > 8) {
+ timeout -= base::Seconds(10);
+ } else if (num_of_processors <= 4) {
+ timeout += base::Seconds(5);
+ }
#endif
- return kGpuWatchdogTimeout;
+ if (software_rendering) {
+ timeout *= kSoftwareRenderingFactor;
+ }
+ return timeout;
}
GpuWatchdogThread::GpuWatchdogThread(base::TimeDelta timeout,
@@ -156,9 +160,22 @@ std::unique_ptr<GpuWatchdogThread> GpuWatchdogThread::Create(
// static
std::unique_ptr<GpuWatchdogThread> GpuWatchdogThread::Create(
bool start_backgrounded,
+ bool software_rendering,
+ const std::string& thread_name) {
+ return Create(start_backgrounded, GetGpuWatchdogTimeout(software_rendering),
+ kInitFactor, kRestartFactor, /*test_mode=*/false, thread_name);
+}
+
+// static
+std::unique_ptr<GpuWatchdogThread> GpuWatchdogThread::Create(
+ bool start_backgrounded,
+ const GpuWatchdogThread* existing_watchdog,
const std::string& thread_name) {
- return Create(start_backgrounded, GetGpuWatchdogTimeout(), kInitFactor,
- kRestartFactor, /*test_mode=*/false, thread_name);
+ DCHECK(existing_watchdog);
+ return Create(start_backgrounded, existing_watchdog->watchdog_timeout_,
+ existing_watchdog->watchdog_init_factor_,
+ existing_watchdog->watchdog_restart_factor_,
+ /*test_mode=*/false, thread_name);
}
// Android Chrome goes to the background. Called from the gpu io thread.
diff --git a/chromium/gpu/ipc/service/gpu_watchdog_thread.h b/chromium/gpu/ipc/service/gpu_watchdog_thread.h
index 0ae2182eab8..f0c412903dd 100644
--- a/chromium/gpu/ipc/service/gpu_watchdog_thread.h
+++ b/chromium/gpu/ipc/service/gpu_watchdog_thread.h
@@ -93,6 +93,14 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread
public:
static std::unique_ptr<GpuWatchdogThread> Create(
bool start_backgrounded,
+ bool software_rendering,
+ const std::string& thread_name);
+
+ // Use the existing GpuWatchdogThread to create a second one. This is used
+ // for DrDC thread only.
+ static std::unique_ptr<GpuWatchdogThread> Create(
+ bool start_backgrounded,
+ const GpuWatchdogThread* existing_watchdog,
const std::string& thread_name);
static std::unique_ptr<GpuWatchdogThread> Create(