Commit 2d873e0c by Jonah Ryan-Davis Committed by Commit Bot

GL: Workaround to sanitize amdgpu renderer strings.

On Linux with the amdgpu driver, the GL_RENDERER string contains precise kernel and DRM version info. We should sanitize this info before using these strings for user privacy. Bug: chromium:1181193 Change-Id: I047d1abf5b51412b4258a021761cc450385ef0fe Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2727658 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent ad01350e
...@@ -535,6 +535,13 @@ struct FeaturesGL : FeatureSetBase ...@@ -535,6 +535,13 @@ struct FeaturesGL : FeatureSetBase
"sync_vertex_arrays_to_default", FeatureCategory::OpenGLWorkarounds, "sync_vertex_arrays_to_default", FeatureCategory::OpenGLWorkarounds,
"Only use the default VAO because of missing support or driver bugs", &members, "Only use the default VAO because of missing support or driver bugs", &members,
"http://anglebug.com/5577"}; "http://anglebug.com/5577"};
// On desktop Linux/AMD when using the amdgpu drivers, the precise kernel and DRM version are
// leaked via GL_RENDERER. We workaround this to improve user privacy.
Feature sanitizeAmdGpuRendererString = {
"sanitize_amdgpu_renderer_string", FeatureCategory::OpenGLWorkarounds,
"Strip precise kernel and DRM version information from amdgpu renderer strings.", &members,
"http://crbug.com/1181193"};
}; };
inline FeaturesGL::FeaturesGL() = default; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -22,6 +22,51 @@ ...@@ -22,6 +22,51 @@
namespace rx namespace rx
{ {
// On Linux with the amdgpu driver, the renderer string looks like:
//
// AMD Radeon (TM) <GPU model> Graphics (<GPUgeneration>, DRM <DRMversion>, <kernelversion>,
// LLVM <LLVMversion>) eg. AMD Radeon (TM) RX 460 Graphics (POLARIS11,
// DRM 3.35.0, 5.4.0-65-generic, LLVM 11.0.0)
//
// We also want to handle the case without GPUGeneration:
// AMD Radeon GPU model (DRM DRMversion, kernelversion, LLVM LLVMversion)
//
// Thanks to Jeff Gilbert of Mozilla for this example
// https://phabricator.services.mozilla.com/D105636
std::string SanitizeRendererString(std::string rendererString)
{
size_t pos = rendererString.find(", DRM ");
if (pos != std::string::npos)
{
rendererString.resize(pos);
rendererString.push_back(')');
return rendererString;
}
pos = rendererString.find(" (DRM ");
if (pos != std::string::npos)
{
rendererString.resize(pos);
return rendererString;
}
return rendererString;
}
// OpenGL ES requires a prefix of "OpenGL ES" for the GL_VERSION string.
// We can also add the prefix to desktop OpenGL for consistency.
std::string SanitizeVersionString(std::string versionString, bool isES)
{
if (versionString.find("OpenGL") == std::string::npos)
{
std::string prefix = "OpenGL ";
if (isES)
{
prefix += "ES ";
}
versionString = prefix + versionString;
}
return versionString;
}
DisplayGL::DisplayGL(const egl::DisplayState &state) : DisplayImpl(state) {} DisplayGL::DisplayGL(const egl::DisplayState &state) : DisplayImpl(state) {}
DisplayGL::~DisplayGL() {} DisplayGL::~DisplayGL() {}
...@@ -102,7 +147,14 @@ egl::Error DisplayGL::makeCurrentSurfaceless(gl::Context *context) ...@@ -102,7 +147,14 @@ egl::Error DisplayGL::makeCurrentSurfaceless(gl::Context *context)
std::string DisplayGL::getRendererDescription() std::string DisplayGL::getRendererDescription()
{ {
return GetRendererString(getRenderer()->getFunctions()); std::string rendererString = GetRendererString(getRenderer()->getFunctions());
const angle::FeaturesGL &features = getRenderer()->getFeatures();
if (features.sanitizeAmdGpuRendererString.enabled)
{
return SanitizeRendererString(rendererString);
}
return rendererString;
} }
std::string DisplayGL::getVendorString() std::string DisplayGL::getVendorString()
...@@ -112,7 +164,9 @@ std::string DisplayGL::getVendorString() ...@@ -112,7 +164,9 @@ std::string DisplayGL::getVendorString()
std::string DisplayGL::getVersionString() std::string DisplayGL::getVersionString()
{ {
return GetVersionString(getRenderer()->getFunctions()); std::string versionString = GetVersionString(getRenderer()->getFunctions());
return SanitizeVersionString(versionString,
getRenderer()->getFunctions()->standard == STANDARD_GL_ES);
} }
} // namespace rx } // namespace rx
...@@ -19,6 +19,7 @@ class Surface; ...@@ -19,6 +19,7 @@ class Surface;
namespace rx namespace rx
{ {
class ShareGroupGL : public ShareGroupImpl class ShareGroupGL : public ShareGroupImpl
{}; {};
......
//
// Copyright 2021 The ANGLE 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.
//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "tests/angle_unittests_utils.h"
namespace rx
{
extern std::string SanitizeRendererString(std::string rendererString);
extern std::string SanitizeVersionString(std::string versionString, bool isES);
namespace testing
{
namespace
{
TEST(DisplayGLTest, SanitizeRendererStringIntel)
{
std::string testString = "Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2)";
std::string testExpectation = "Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2)";
EXPECT_EQ(SanitizeRendererString(testString), testExpectation);
}
TEST(DisplayGLTest, SanitizeRendererStringLLVMPipe)
{
std::string testString = "llvmpipe (LLVM 11.0.0, 256 bits)";
std::string testExpectation = "llvmpipe (LLVM 11.0.0, 256 bits)";
EXPECT_EQ(SanitizeRendererString(testString), testExpectation);
}
TEST(DisplayGLTest, SanitizeRendererStringRadeonVega)
{
std::string testString = "Radeon RX Vega";
std::string testExpectation = "Radeon RX Vega";
EXPECT_EQ(SanitizeRendererString(testString), testExpectation);
}
TEST(DisplayGLTest, SanitizeRendererStringRadeonTM)
{
std::string testString =
"AMD Radeon (TM) RX 460 Graphics (POLARIS11, DRM 3.35.0, 5.4.0-65-generic, LLVM 11.0.0)";
std::string testExpectation = "AMD Radeon (TM) RX 460 Graphics (POLARIS11)";
EXPECT_EQ(SanitizeRendererString(testString), testExpectation);
}
TEST(DisplayGLTest, SanitizeRendererStringRadeonWithoutGeneration)
{
std::string testString = "AMD Radeon RX 5700 (DRM 3.35.0, 5.4.0-65-generic, LLVM 11.0.0)";
std::string testExpectation = "AMD Radeon RX 5700";
EXPECT_EQ(SanitizeRendererString(testString), testExpectation);
}
TEST(DisplayGLTest, SanitizeVersionStringOpenGLMissing)
{
std::string testString = "4.6.0 NVIDIA 391.76";
std::string testExpectation = "OpenGL 4.6.0 NVIDIA 391.76";
EXPECT_EQ(SanitizeVersionString(testString, false), testExpectation);
}
// Note: OpenGL renderers with this prefix don't actually seem to be present in the wild
TEST(DisplayGLTest, SanitizeVersionStringOpenGLPresent)
{
std::string testString = "OpenGL 4.5.0 - Build 22.20.16.4749";
std::string testExpectation = "OpenGL 4.5.0 - Build 22.20.16.4749";
EXPECT_EQ(SanitizeVersionString(testString, false), testExpectation);
}
TEST(DisplayGLTest, SanitizeVersionStringOpenGLESMissing)
{
std::string testString = "4.6.0 NVIDIA 419.67";
std::string testExpectation = "OpenGL ES 4.6.0 NVIDIA 419.67";
EXPECT_EQ(SanitizeVersionString(testString, true), testExpectation);
}
TEST(DisplayGLTest, SanitizeVersionStringOpenGLESPresent)
{
std::string testString = "OpenGL ES 3.2 v1.r12p0-04rel0.44f2946824bb8739781564bffe2110c9";
std::string testExpectation = "OpenGL ES 3.2 v1.r12p0-04rel0.44f2946824bb8739781564bffe2110c9";
EXPECT_EQ(SanitizeVersionString(testString, true), testExpectation);
}
} // anonymous namespace
} // namespace testing
} // namespace rx
...@@ -2089,6 +2089,11 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -2089,6 +2089,11 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
IsApple() && IsIntel(vendor) && !IsHaswell(device)); IsApple() && IsIntel(vendor) && !IsHaswell(device));
ANGLE_FEATURE_CONDITION(features, syncVertexArraysToDefault, ANGLE_FEATURE_CONDITION(features, syncVertexArraysToDefault,
!nativegl::SupportsVertexArrayObjects(functions)); !nativegl::SupportsVertexArrayObjects(functions));
// http://crbug.com/1181193
// On desktop Linux/AMD when using the amdgpu drivers, the precise kernel and DRM version are
// leaked via GL_RENDERER. We workaround this too improve user security.
ANGLE_FEATURE_CONDITION(features, sanitizeAmdGpuRendererString, IsLinux() && hasAMD);
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
...@@ -2570,17 +2575,7 @@ std::string GetVendorString(const FunctionsGL *functions) ...@@ -2570,17 +2575,7 @@ std::string GetVendorString(const FunctionsGL *functions)
std::string GetVersionString(const FunctionsGL *functions) std::string GetVersionString(const FunctionsGL *functions)
{ {
std::string versionString = GetString(functions, GL_VERSION); return GetString(functions, GL_VERSION);
if (versionString.find("OpenGL") == std::string::npos)
{
std::string prefix = "OpenGL ";
if (functions->standard == STANDARD_GL_ES)
{
prefix += "ES ";
}
versionString = prefix + versionString;
}
return versionString;
} }
} // namespace rx } // namespace rx
...@@ -164,6 +164,10 @@ angle_test("angle_unittests") { ...@@ -164,6 +164,10 @@ angle_test("angle_unittests") {
defines += [ "ANGLE_ENABLE_HLSL" ] defines += [ "ANGLE_ENABLE_HLSL" ]
} }
if (angle_enable_gl) {
sources += angle_unittests_gl_sources
}
deps = [ deps = [
":angle_test_expectations", ":angle_test_expectations",
"$angle_root:angle_json_serializer", "$angle_root:angle_json_serializer",
......
...@@ -155,6 +155,9 @@ angle_unittests_hlsl_sources = [ ...@@ -155,6 +155,9 @@ angle_unittests_hlsl_sources = [
"compiler_tests/UnrollFlatten_test.cpp", "compiler_tests/UnrollFlatten_test.cpp",
] ]
angle_unittests_gl_sources =
[ "../libANGLE/renderer/gl/DisplayGL_unittest.cpp" ]
if (is_android) { if (is_android) {
angle_unittests_sources += angle_unittests_sources +=
[ "compiler_tests/ImmutableString_test_ESSL_autogen.cpp" ] [ "compiler_tests/ImmutableString_test_ESSL_autogen.cpp" ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment