Index: content/common/sandbox_linux/bpf_gpu_policy_linux.cc |
diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc |
index d356897d9e0740668884c496307960ca5c91dddb..94414af4dc017dbe406fbf457f2c6e45fe546d10 100644 |
--- a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc |
+++ b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc |
@@ -22,6 +22,7 @@ |
#include "base/logging.h" |
#include "base/macros.h" |
#include "base/memory/ptr_util.h" |
+#include "base/sys_info.h" |
#include "build/build_config.h" |
#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" |
#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" |
@@ -33,6 +34,7 @@ |
#include "sandbox/linux/syscall_broker/broker_file_permission.h" |
#include "sandbox/linux/syscall_broker/broker_process.h" |
#include "sandbox/linux/system_headers/linux_syscalls.h" |
+#include "ui/gl/gl_implementation.h" |
using sandbox::arch_seccomp_data; |
using sandbox::bpf_dsl::Allow; |
@@ -324,6 +326,56 @@ bool GpuProcessPolicy::PreSandboxHook() { |
} |
} |
+ // If kGpuSandboxStartEarly is set then we need to warmup by loading gl and |
+ // driver libraries before to actually run the sandbox. Another approach would |
+ // be to white list these libraries using the broker file permissons. But |
+ // that would require to white list all single dependencies which is not easy |
+ // and there is no much value compared to the following. |
+ const base::CommandLine& command_line = |
+ *base::CommandLine::ForCurrentProcess(); |
+ if (command_line.HasSwitch(switches::kGpuSandboxStartEarly)) { |
+ // uname is used from GpuControlList when calling |
+ // gpu::ApplyGpuDriverBugWorkarounds. |
+ base::SysInfo::OperatingSystemVersion(); |
+ |
+ gfx::GLImplementation gl_iml = gfx::kGLImplementationNone; |
+ bool fallback_to_osmesa = false; |
+ bool result = gfx::SelectGLImplementation(&gl_iml, &fallback_to_osmesa); |
+ if (!result) |
+ LOG(ERROR) << "Failed to select a gl implementation"; |
+ |
+ std::vector<std::string> driver_libraries; |
+ if (result) { |
+ result = gfx::GetNativeLibraryNamesFromGLImplementation( |
+ gl_iml, &driver_libraries); |
+ if (!result) |
+ LOG(ERROR) << "Failed to retrieve libraries for " |
+ << gfx::GetGLImplementationName(gl_iml); |
+ } |
+ |
+#if defined(DRI_DRIVER_DIR) |
+ // Mesa always fallback to software driver in the 3 following cases: |
+ // 1- there is no real driver. |
+ // 2- it fails to load a real driver. |
+ // 3- User set the env var LIBGL_ALWAYS_SOFTWARE. |
+ if (result && command_line.HasSwitch(switches::kGpuDriverVendor) && |
+ command_line.GetSwitchValueASCII(switches::kGpuDriverVendor) == |
+ "Mesa") { |
+ base::FilePath swrast_lib(DRI_DRIVER_DIR); |
+ swrast_lib = swrast_lib.Append("swrast_dri.so"); |
+ driver_libraries.push_back(swrast_lib.value()); |
+ } |
+#endif |
+ |
+ for (const auto& lib_name : driver_libraries) { |
+ void* dl = |
+ dlopen(lib_name.c_str(), RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); |
+ if (!dl) |
+ LOG(ERROR) << "Failed to open " << lib_name << " with error " |
+ << dlerror(); |
+ } |
+ } |
+ |
return true; |
} |