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 09eedbb37e54698af0fc47af1f5df41937725805..6cfe7c656a0a947c9355f7182e8ad6771365e03a 100644 |
--- a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc |
+++ b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc |
@@ -29,12 +29,15 @@ |
#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" |
#include "content/common/set_process_title.h" |
#include "content/public/common/content_switches.h" |
+#include "gpu/config/gpu_switches.h" |
+#include "gpu/ipc/service/switches.h" |
#include "sandbox/linux/bpf_dsl/bpf_dsl.h" |
#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" |
#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" |
#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/init/gl_factory.h" |
using sandbox::arch_seccomp_data; |
using sandbox::bpf_dsl::Allow; |
@@ -330,6 +333,57 @@ 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)) { |
+ gl::GLImplementation gl_iml = gl::kGLImplementationNone; |
+ std::vector<gl::GLImplementation> allowed_impls = |
+ gl::init::GetAllowedGLImplementations(); |
+ bool fallback_to_osmesa = false; |
+ bool result = |
+ gl::SelectGLImplementation(allowed_impls, &gl_iml, &fallback_to_osmesa); |
+ if (!result) |
+ LOG(ERROR) << "Failed to select a gl implementation"; |
+ |
+ std::vector<std::string> driver_libraries; |
+ if (result) { |
+ result = gl::init::GetNativeLibraryNamesFromGLImplementation( |
+ gl_iml, &driver_libraries); |
+ if (!result) { |
+ LOG(ERROR) << "Failed to retrieve libraries for " |
+ << gl::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; |
} |