Bug 1217290 - Refactor WebGL max & min attribute constants for WebGL fingerprinting r=arthuredelstein,daoshengmu,jgilbert

MozReview-Commit-ID: 5fxOdV8euJ0

--HG--
extra : rebase_source : 6c961a6e1bb0bea22ee464b8e166994224170b03
This commit is contained in:
Chung-Sheng Fu 2017-07-27 15:49:46 +08:00
Родитель 886fe4b600
Коммит 2077ced147
3 изменённых файлов: 161 добавлений и 37 удалений

Просмотреть файл

@ -54,30 +54,6 @@
class nsIDocShell;
/*
* Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
* https://bugzilla.mozilla.org/show_bug.cgi?id=686732
*
* Exceptions: some of the following values are set to higher values than in the spec because
* the values in the spec are ridiculously low. They are explicitly marked below
*/
#define MINVALUE_GL_MAX_TEXTURE_SIZE 1024 // Different from the spec, which sets it to 64 on page 162
#define MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE 512 // Different from the spec, which sets it to 16 on page 162
#define MINVALUE_GL_MAX_VERTEX_ATTRIBS 8 // Page 164
#define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS 16 // Page 164
#define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS 128 // Page 164
#define MINVALUE_GL_MAX_VARYING_VECTORS 8 // Page 164
#define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS 8 // Page 164
#define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0 // Page 164
#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
/*
* Minimum value constants define in 6.2 State Tables of OpenGL ES - 3.0.4
*/
#define MINVALUE_GL_MAX_3D_TEXTURE_SIZE 256
#define MINVALUE_GL_MAX_ARRAY_TEXTURE_LAYERS 256
/*
* WebGL-only GLenums
*/
@ -1511,6 +1487,9 @@ public:
return mGLMaxTextureUnits;
}
float mGLAliasedLineWidthRange[2];
float mGLAliasedPointSizeRange[2];
bool IsFormatValidForFB(TexInternalFormat format) const;
protected:

Просмотреть файл

@ -381,11 +381,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_PACK_ALIGNMENT:
case LOCAL_GL_SUBPIXEL_BITS:
case LOCAL_GL_SAMPLE_BUFFERS:
case LOCAL_GL_SAMPLES:
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: {
case LOCAL_GL_SAMPLES: {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
@ -414,6 +410,18 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
return JS::Int32Value(mGLMaxRenderbufferSize);
case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
return JS::Int32Value(mGLMaxVertexTextureImageUnits);
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
return JS::Int32Value(mGLMaxFragmentTextureImageUnits);
case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
return JS::Int32Value(mGLMaxCombinedTextureImageUnits);
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
return JS::Int32Value(mGLMaxVertexAttribs);
case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
return JS::Int32Value(mGLMaxVertexUniformVectors);
@ -494,15 +502,21 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_DEPTH_RANGE:
case LOCAL_GL_ALIASED_POINT_SIZE_RANGE:
case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: {
GLenum driverPName = pname;
if (gl->IsCoreProfile() &&
driverPName == LOCAL_GL_ALIASED_POINT_SIZE_RANGE)
{
driverPName = LOCAL_GL_POINT_SIZE_RANGE;
}
GLfloat fv[2] = { 0 };
gl->fGetFloatv(driverPName, fv);
switch (pname) {
case LOCAL_GL_ALIASED_POINT_SIZE_RANGE:
fv[0] = mGLAliasedPointSizeRange[0];
fv[1] = mGLAliasedPointSizeRange[1];
break;
case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE:
fv[0] = mGLAliasedLineWidthRange[0];
fv[1] = mGLAliasedLineWidthRange[1];
break;
// case LOCAL_GL_DEPTH_RANGE:
default:
gl->fGetFloatv(pname, fv);
break;
}
JSObject* obj = dom::Float32Array::Create(cx, this, 2, fv);
if (!obj) {
rv = NS_ERROR_OUT_OF_MEMORY;

Просмотреть файл

@ -34,6 +34,66 @@
#include "nsCocoaFeatures.h"
#endif
////////////////////
// Minimum value constants defined in GLES 2.0.25 $6.2 "State Tables":
const uint32_t kMinMaxVertexAttribs = 8; // Page 164
const uint32_t kMinMaxVertexUniformVectors = 128; // Page 164
const uint32_t kMinMaxFragmentUniformVectors = 16; // Page 164
const uint32_t kMinMaxVaryingVectors = 8; // Page 164
const uint32_t kMinMaxVertexTextureImageUnits = 0; // Page 164
const uint32_t kMinMaxFragmentTextureImageUnits = 8; // Page 164
const uint32_t kMinMaxCombinedTextureImageUnits = 8; // Page 164
const uint32_t kMinMaxColorAttachments = 4;
const uint32_t kMinMaxDrawBuffers = 4;
// These few deviate from the spec: (The minimum values in the spec are ridiculously low)
const uint32_t kMinMaxTextureSize = 1024; // ES2 spec says `64` (p162)
const uint32_t kMinMaxCubeMapTextureSize = 512; // ES2 spec says `16` (p162)
const uint32_t kMinMaxRenderbufferSize = 1024; // ES2 spec says `1` (p164)
// Minimum value constants defined in GLES 3.0.4 $6.2 "State Tables":
const uint32_t kMinMax3DTextureSize = 256;
const uint32_t kMinMaxArrayTextureLayers = 256;
////////////////////
// "Common" but usable values to avoid WebGL fingerprinting:
const uint32_t kCommonMaxTextureSize = 2048;
const uint32_t kCommonMaxCubeMapTextureSize = 2048;
const uint32_t kCommonMaxRenderbufferSize = 2048;
const uint32_t kCommonMaxVertexTextureImageUnits = 8;
const uint32_t kCommonMaxFragmentTextureImageUnits = 8;
const uint32_t kCommonMaxCombinedTextureImageUnits = 16;
const uint32_t kCommonMaxVertexAttribs = 16;
const uint32_t kCommonMaxVertexUniformVectors = 256;
const uint32_t kCommonMaxFragmentUniformVectors = 224;
const uint32_t kCommonMaxVaryingVectors = 8;
const uint32_t kCommonMaxViewportDims = 4096;
// The following ranges came from a 2013 Moto E and an old macbook.
const float kCommonAliasedPointSizeRangeMin = 1;
const float kCommonAliasedPointSizeRangeMax = 63;
const float kCommonAliasedLineWidthRangeMin = 1;
const float kCommonAliasedLineWidthRangeMax = 5;
template<class T>
static bool
RestrictCap(T* const cap, const T restrictedVal)
{
if (*cap < restrictedVal) {
return false; // already too low!
}
*cap = restrictedVal;
return true;
}
////////////////////
namespace mozilla {
bool
@ -454,6 +514,7 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
// even though the hardware supports much more. The
// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value.
gl->GetUIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
mGLMaxCombinedTextureImageUnits = mGLMaxTextureUnits;
if (mGLMaxTextureUnits < 8) {
const nsPrintfCString reason("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %u is < 8!",
@ -532,6 +593,76 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
}
}
////////////////
gl->fGetFloatv(LOCAL_GL_ALIASED_LINE_WIDTH_RANGE, mGLAliasedLineWidthRange);
const GLenum driverPName = gl->IsCoreProfile() ? LOCAL_GL_POINT_SIZE_RANGE
: LOCAL_GL_ALIASED_POINT_SIZE_RANGE;
gl->fGetFloatv(driverPName, mGLAliasedPointSizeRange);
////////////////
if (gfxPrefs::WebGLMinCapabilityMode()) {
bool ok = true;
ok &= RestrictCap(&mGLMaxVertexTextureImageUnits , kMinMaxVertexTextureImageUnits);
ok &= RestrictCap(&mGLMaxFragmentTextureImageUnits, kMinMaxFragmentTextureImageUnits);
ok &= RestrictCap(&mGLMaxCombinedTextureImageUnits, kMinMaxCombinedTextureImageUnits);
ok &= RestrictCap(&mGLMaxVertexAttribs , kMinMaxVertexAttribs);
ok &= RestrictCap(&mGLMaxVertexUniformVectors , kMinMaxVertexUniformVectors);
ok &= RestrictCap(&mGLMaxFragmentUniformVectors, kMinMaxFragmentUniformVectors);
ok &= RestrictCap(&mGLMaxVaryingVectors , kMinMaxVaryingVectors);
ok &= RestrictCap(&mGLMaxColorAttachments, kMinMaxColorAttachments);
ok &= RestrictCap(&mGLMaxDrawBuffers , kMinMaxDrawBuffers);
ok &= RestrictCap(&mGLMaxTextureSize , kMinMaxTextureSize);
ok &= RestrictCap(&mGLMaxCubeMapTextureSize, kMinMaxCubeMapTextureSize);
ok &= RestrictCap(&mGLMax3DTextureSize , kMinMax3DTextureSize);
ok &= RestrictCap(&mGLMaxArrayTextureLayers, kMinMaxArrayTextureLayers);
ok &= RestrictCap(&mGLMaxRenderbufferSize , kMinMaxRenderbufferSize);
if (!ok) {
GenerateWarning("Unable to restrict WebGL limits to minimums.");
return false;
}
mDisableFragHighP = true;
} else if (nsContentUtils::ShouldResistFingerprinting()) {
bool ok = true;
ok &= RestrictCap(&mGLMaxTextureSize , kCommonMaxTextureSize);
ok &= RestrictCap(&mGLMaxCubeMapTextureSize, kCommonMaxCubeMapTextureSize);
ok &= RestrictCap(&mGLMaxRenderbufferSize , kCommonMaxRenderbufferSize);
ok &= RestrictCap(&mGLMaxVertexTextureImageUnits , kCommonMaxVertexTextureImageUnits);
ok &= RestrictCap(&mGLMaxFragmentTextureImageUnits, kCommonMaxFragmentTextureImageUnits);
ok &= RestrictCap(&mGLMaxCombinedTextureImageUnits, kCommonMaxCombinedTextureImageUnits);
ok &= RestrictCap(&mGLMaxVertexAttribs , kCommonMaxVertexAttribs);
ok &= RestrictCap(&mGLMaxVertexUniformVectors , kCommonMaxVertexUniformVectors);
ok &= RestrictCap(&mGLMaxFragmentUniformVectors, kCommonMaxFragmentUniformVectors);
ok &= RestrictCap(&mGLMaxVaryingVectors , kCommonMaxVaryingVectors);
ok &= RestrictCap(&mGLAliasedLineWidthRange[0], kCommonAliasedLineWidthRangeMin);
ok &= RestrictCap(&mGLAliasedLineWidthRange[1], kCommonAliasedLineWidthRangeMax);
ok &= RestrictCap(&mGLAliasedPointSizeRange[0], kCommonAliasedPointSizeRangeMin);
ok &= RestrictCap(&mGLAliasedPointSizeRange[1], kCommonAliasedPointSizeRangeMax);
ok &= RestrictCap(&mGLMaxViewportDims[0], kCommonMaxViewportDims);
ok &= RestrictCap(&mGLMaxViewportDims[1], kCommonMaxViewportDims);
if (!ok) {
GenerateWarning("Unable to restrict WebGL limits in order to resist fingerprinting");
return false;
}
}
////////////////
if (gl->IsCompatibilityProfile()) {
gl->fEnable(LOCAL_GL_POINT_SPRITE);
}