Changeset 214765 in webkit


Ignore:
Timestamp:
Apr 3, 2017 4:02:21 AM (7 years ago)
Author:
Carlos Garcia Campos
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):

Location:
releases/WebKitGTK/webkit-2.16/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog

    r214755 r214765  
     12017-03-17  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Time channel attack on SVG Filters
     4        https://bugs.webkit.org/show_bug.cgi?id=118689
     5
     6        Reviewed by Simon Fraser.
     7
     8        Performing arithmetic operations on subnormal floating-point numbers is
     9        very expensive. Normalizing the floating-point number to the minimum normal
     10        value should accelerate the calculations and there won't be a noticeable
     11        difference in the result since all the subnormal values and the minimum
     12        normal value are all very close to zero.
     13
     14        * wtf/MathExtras.h:
     15        (normalizedFloat):
     16
    1172017-03-16  Carlos Garcia Campos  <cgarcia@igalia.com>
    218
  • releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/MathExtras.h

    r207787 r214765  
    199199}
    200200
     201inline float normalizedFloat(float value)
     202{
     203    if (value > 0 && value < std::numeric_limits<float>::min())
     204        return std::numeric_limits<float>::min();
     205    if (value < 0 && value > -std::numeric_limits<float>::min())
     206        return -std::numeric_limits<float>::min();
     207    return value;
     208}
     209
    201210template<typename T> inline bool hasOneBitSet(T value)
    202211{
  • releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog

    r214764 r214765  
     12017-03-17  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Time channel attack on SVG Filters
     4        https://bugs.webkit.org/show_bug.cgi?id=118689
     5
     6        Reviewed by Simon Fraser.
     7
     8        The time channel attack can happen if the attacker applies FEColorMatrix
     9        or FEConvolveMatrix and provides a matrix which is filled with subnormal
     10        floating point values. Performing floating-point operations on subnormals
     11        is very expensive unless the pixel in the source graphics is black (or
     12        zero). By measuring the time a filter takes to be applied, the attacker
     13        can know whether the pixel he wants to steal from  an iframe is black or
     14        white. By repeating the same process on all the pixels in the iframe, the
     15        attacker can reconstruct the whole page of the iframe.
     16
     17        To fix this issue, the values in the matrices of these filters will clamped
     18        to FLT_MIN. We do not want to consume too much time calculating filtered
     19        pixels because of such tiny values. The difference between applying FLT_MIN
     20        and applying a subnormal should not be even noticeable. Normalizing the
     21        floating-point matrices should happen only at the beginning of the filter
     22        platformApplySoftware().
     23
     24        * platform/graphics/filters/FEColorMatrix.cpp:
     25        (WebCore::FEColorMatrix::platformApplySoftware):
     26        * platform/graphics/filters/FEConvolveMatrix.cpp:
     27        (WebCore::FEConvolveMatrix::fastSetInteriorPixels):
     28        (WebCore::FEConvolveMatrix::fastSetOuterPixels):
     29        (WebCore::FEConvolveMatrix::platformApplySoftware):
     30        * platform/graphics/filters/FEConvolveMatrix.h:
     31        * platform/graphics/filters/FilterEffect.h:
     32        (WebCore::FilterEffect::normalizedFloats):
     33
    1342017-03-17  Zalan Bujtas  <zalan@apple.com>
    235
  • releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp

    r192140 r214765  
    154154    IntRect imageRect(IntPoint(), resultImage->logicalSize());
    155155    RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect);
     156    Vector<float> values = normalizedFloats(m_values);
    156157
    157158    switch (m_type) {
     
    159160        break;
    160161    case FECOLORMATRIX_TYPE_MATRIX:
    161         effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), m_values);
     162        effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), values);
    162163        break;
    163164    case FECOLORMATRIX_TYPE_SATURATE:
    164         effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), m_values);
     165        effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), values);
    165166        break;
    166167    case FECOLORMATRIX_TYPE_HUEROTATE:
    167         effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), m_values);
     168        effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), values);
    168169        break;
    169170    case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
    170         effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), m_values);
     171        effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), values);
    171172        setIsAlphaImage(true);
    172173        break;
  • releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp

    r211173 r214765  
    268268    for (int y = yEnd + 1; y > yStart; --y) {
    269269        for (int x = clipRight + 1; x > 0; --x) {
    270             int kernelValue = m_kernelMatrix.size() - 1;
     270            int kernelValue = paintingData.kernelMatrix.size() - 1;
    271271            int kernelPixel = startKernelPixel;
    272272            int width = m_kernelSize.width();
     
    279279
    280280            while (kernelValue >= 0) {
    281                 totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
    282                 totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
    283                 totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
     281                totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
     282                totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
     283                totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel++));
    284284                if (!preserveAlphaValues)
    285                     totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel));
     285                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(kernelPixel));
    286286                ++kernelPixel;
    287287                --kernelValue;
     
    348348    for (int y = height; y > 0; --y) {
    349349        for (int x = width; x > 0; --x) {
    350             int kernelValue = m_kernelMatrix.size() - 1;
     350            int kernelValue = paintingData.kernelMatrix.size() - 1;
    351351            int kernelPixelX = startKernelPixelX;
    352352            int kernelPixelY = startKernelPixelY;
     
    362362                int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
    363363                if (pixelIndex >= 0) {
    364                     totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex));
    365                     totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 1));
    366                     totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 2));
     364                    totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex));
     365                    totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 1));
     366                    totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 2));
    367367                }
    368368                if (!preserveAlphaValues && pixelIndex >= 0)
    369                     totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 3));
     369                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->item(pixelIndex + 3));
    370370                ++kernelPixelX;
    371371                --kernelValue;
     
    437437    paintingData.height = paintSize.height();
    438438    paintingData.bias = m_bias * 255;
     439    paintingData.kernelMatrix = normalizedFloats(m_kernelMatrix);
    439440
    440441    // Drawing fully covered pixels
  • releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h

    r209871 r214765  
    8484        int height;
    8585        float bias;
     86        Vector<float> kernelMatrix;
    8687    };
    8788
  • releases/WebKitGTK/webkit-2.16/Source/WebCore/platform/graphics/filters/FilterEffect.h

    r191867 r214765  
    2727#include "IntRect.h"
    2828#include <runtime/Uint8ClampedArray.h>
     29#include <wtf/MathExtras.h>
    2930#include <wtf/RefCounted.h>
    3031#include <wtf/RefPtr.h>
     
    171172
    172173    void clipAbsolutePaintRect();
     174   
     175    static Vector<float> normalizedFloats(const Vector<float>& values)
     176    {
     177        Vector<float> normalizedValues(values.size());
     178        for (size_t i = 0; i < values.size(); ++i)
     179            normalizedValues[i] = normalizedFloat(values[i]);
     180        return normalizedValues;
     181    }
    173182
    174183private:
Note: See TracChangeset for help on using the changeset viewer.