Title: [214765] releases/WebKitGTK/webkit-2.16/Source
Revision
214765
Author
carlo...@webkit.org
Date
2017-04-03 04:02:21 -0700 (Mon, 03 Apr 2017)

Log Message

Merge r214125 - Time channel attack on SVG Filters
https://bugs.webkit.org/show_bug.cgi?id=118689

Reviewed by Simon Fraser.

Source/WebCore:

The time channel attack can happen if the attacker applies FEColorMatrix
or FEConvolveMatrix and provides a matrix which is filled with subnormal
floating point values. Performing floating-point operations on subnormals
is very expensive unless the pixel in the source graphics is black (or
zero). By measuring the time a filter takes to be applied, the attacker
can know whether the pixel he wants to steal from  an iframe is black or
white. By repeating the same process on all the pixels in the iframe, the
attacker can reconstruct the whole page of the iframe.

To fix this issue, the values in the matrices of these filters will clamped
to FLT_MIN. We do not want to consume too much time calculating filtered
pixels because of such tiny values. The difference between applying FLT_MIN
and applying a subnormal should not be even noticeable. Normalizing the
floating-point matrices should happen only at the beginning of the filter
platformApplySoftware().

* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::platformApplySoftware):
* platform/graphics/filters/FEConvolveMatrix.cpp:
(WebCore::FEConvolveMatrix::fastSetInteriorPixels):
(WebCore::FEConvolveMatrix::fastSetOuterPixels):
(WebCore::FEConvolveMatrix::platformApplySoftware):
* platform/graphics/filters/FEConvolveMatrix.h:
* platform/graphics/filters/FilterEffect.h:
(WebCore::FilterEffect::normalizedFloats):

Source/WTF:

Performing arithmetic operations on subnormal floating-point numbers is
very expensive. Normalizing the floating-point number to the minimum normal
value should accelerate the calculations and there won't be a noticeable
difference in the result since all the subnormal values and the minimum
normal value are all very close to zero.

* wtf/MathExtras.h:
(normalizedFloat):

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog	2017-04-03 11:02:21 UTC (rev 214765)
@@ -1,3 +1,19 @@
+2017-03-17  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        Time channel attack on SVG Filters
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+
+        Reviewed by Simon Fraser.
+
+        Performing arithmetic operations on subnormal floating-point numbers is
+        very expensive. Normalizing the floating-point number to the minimum normal
+        value should accelerate the calculations and there won't be a noticeable
+        difference in the result since all the subnormal values and the minimum
+        normal value are all very close to zero.
+
+        * wtf/MathExtras.h:
+        (normalizedFloat):
+
 2017-03-16  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [UNIX] Implement currentSearchLocaleID() and currentTextBreakLocaleID()

Modified: releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/MathExtras.h (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/MathExtras.h	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/MathExtras.h	2017-04-03 11:02:21 UTC (rev 214765)
@@ -198,6 +198,15 @@
     return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static_cast<float>(std::numeric_limits<int>::max());
 }
 
+inline float normalizedFloat(float value)
+{
+    if (value > 0 && value < std::numeric_limits<float>::min())
+        return std::numeric_limits<float>::min();
+    if (value < 0 && value > -std::numeric_limits<float>::min())
+        return -std::numeric_limits<float>::min();
+    return value;
+}
+
 template<typename T> inline bool hasOneBitSet(T value)
 {
     return !((value - 1) & value) && value;

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog	2017-04-03 11:02:21 UTC (rev 214765)
@@ -1,3 +1,36 @@
+2017-03-17  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        Time channel attack on SVG Filters
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+
+        Reviewed by Simon Fraser.
+
+        The time channel attack can happen if the attacker applies FEColorMatrix
+        or FEConvolveMatrix and provides a matrix which is filled with subnormal
+        floating point values. Performing floating-point operations on subnormals
+        is very expensive unless the pixel in the source graphics is black (or
+        zero). By measuring the time a filter takes to be applied, the attacker
+        can know whether the pixel he wants to steal from  an iframe is black or
+        white. By repeating the same process on all the pixels in the iframe, the
+        attacker can reconstruct the whole page of the iframe.
+
+        To fix this issue, the values in the matrices of these filters will clamped
+        to FLT_MIN. We do not want to consume too much time calculating filtered
+        pixels because of such tiny values. The difference between applying FLT_MIN
+        and applying a subnormal should not be even noticeable. Normalizing the
+        floating-point matrices should happen only at the beginning of the filter
+        platformApplySoftware().
+
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEConvolveMatrix.cpp:
+        (WebCore::FEConvolveMatrix::fastSetInteriorPixels):
+        (WebCore::FEConvolveMatrix::fastSetOuterPixels):
+        (WebCore::FEConvolveMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEConvolveMatrix.h:
+        * platform/graphics/filters/FilterEffect.h:
+        (WebCore::FilterEffect::normalizedFloats):
+
 2017-03-17  Zalan Bujtas  <za...@apple.com>
 
         Fix the flow thread state on the descendants of out of flow positioned replaced elements.

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2017-04-03 11:02:21 UTC (rev 214765)
@@ -153,21 +153,22 @@
 
     IntRect imageRect(IntPoint(), resultImage->logicalSize());
     RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect);
+    Vector<float> values = normalizedFloats(m_values);
 
     switch (m_type) {
     case FECOLORMATRIX_TYPE_UNKNOWN:
         break;
     case FECOLORMATRIX_TYPE_MATRIX:
-        effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), m_values);
+        effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), values);
         break;
     case FECOLORMATRIX_TYPE_SATURATE: 
-        effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), m_values);
+        effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), values);
         break;
     case FECOLORMATRIX_TYPE_HUEROTATE:
-        effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), m_values);
+        effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), values);
         break;
     case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
-        effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), m_values);
+        effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), values);
         setIsAlphaImage(true);
         break;
     }

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp	2017-04-03 11:02:21 UTC (rev 214765)
@@ -267,7 +267,7 @@
 
     for (int y = yEnd + 1; y > yStart; --y) {
         for (int x = clipRight + 1; x > 0; --x) {
-            int kernelValue = m_kernelMatrix.size() - 1;
+            int kernelValue = paintingData.kernelMatrix.size() - 1;
             int kernelPixel = startKernelPixel;
             int width = m_kernelSize.width();
 
@@ -278,11 +278,11 @@
                 totals[3] = 0;
 
             while (kernelValue >= 0) {
-                totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
-                totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
-                totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
+                totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
+                totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
+                totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
                 if (!preserveAlphaValues)
-                    totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel));
+                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel));
                 ++kernelPixel;
                 --kernelValue;
                 if (!--width) {
@@ -347,7 +347,7 @@
 
     for (int y = height; y > 0; --y) {
         for (int x = width; x > 0; --x) {
-            int kernelValue = m_kernelMatrix.size() - 1;
+            int kernelValue = paintingData.kernelMatrix.size() - 1;
             int kernelPixelX = startKernelPixelX;
             int kernelPixelY = startKernelPixelY;
             int width = m_kernelSize.width();
@@ -361,12 +361,12 @@
             while (kernelValue >= 0) {
                 int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
                 if (pixelIndex >= 0) {
-                    totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex));
-                    totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 1));
-                    totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 2));
+                    totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex));
+                    totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 1));
+                    totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 2));
                 }
                 if (!preserveAlphaValues && pixelIndex >= 0)
-                    totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 3));
+                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 3));
                 ++kernelPixelX;
                 --kernelValue;
                 if (!--width) {
@@ -436,6 +436,7 @@
     paintingData.width = paintSize.width();
     paintingData.height = paintSize.height();
     paintingData.bias = m_bias * 255;
+    paintingData.kernelMatrix = normalizedFloats(m_kernelMatrix);
 
     // Drawing fully covered pixels
     int clipRight = paintSize.width() - m_kernelSize.width();

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h	2017-04-03 11:02:21 UTC (rev 214765)
@@ -83,6 +83,7 @@
         int width;
         int height;
         float bias;
+        Vector<float> kernelMatrix;
     };
 
     FEConvolveMatrix(Filter&, const IntSize&, float, float,

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FilterEffect.h (214764 => 214765)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FilterEffect.h	2017-04-03 10:32:41 UTC (rev 214764)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FilterEffect.h	2017-04-03 11:02:21 UTC (rev 214765)
@@ -26,6 +26,7 @@
 #include "FloatRect.h"
 #include "IntRect.h"
 #include <runtime/Uint8ClampedArray.h>
+#include <wtf/MathExtras.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
@@ -170,6 +171,14 @@
     void forceValidPreMultipliedPixels();
 
     void clipAbsolutePaintRect();
+    
+    static Vector<float> normalizedFloats(const Vector<float>& values)
+    {
+        Vector<float> normalizedValues(values.size());
+        for (size_t i = 0; i < values.size(); ++i)
+            normalizedValues[i] = normalizedFloat(values[i]);
+        return normalizedValues;
+    }
 
 private:
     std::unique_ptr<ImageBuffer> m_imageBufferResult;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to