Diff
Modified: branches/safari-603-branch/Source/WTF/ChangeLog (214270 => 214271)
--- branches/safari-603-branch/Source/WTF/ChangeLog 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WTF/ChangeLog 2017-03-22 19:50:09 UTC (rev 214271)
@@ -1,3 +1,23 @@
+2017-03-22 Jason Marcell <[email protected]>
+
+ Merge r214125. rdar://problem/30921831
+
+ 2017-03-17 Said Abou-Hallawa <[email protected]>
+
+ 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-02-21 Matthew Hanson <[email protected]>
Merge r212692. rdar://problem/30635854
Modified: branches/safari-603-branch/Source/WTF/wtf/MathExtras.h (214270 => 214271)
--- branches/safari-603-branch/Source/WTF/wtf/MathExtras.h 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WTF/wtf/MathExtras.h 2017-03-22 19:50:09 UTC (rev 214271)
@@ -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: branches/safari-603-branch/Source/WebCore/ChangeLog (214270 => 214271)
--- branches/safari-603-branch/Source/WebCore/ChangeLog 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog 2017-03-22 19:50:09 UTC (rev 214271)
@@ -1,3 +1,40 @@
+2017-03-22 Jason Marcell <[email protected]>
+
+ Merge r214125. rdar://problem/30921831
+
+ 2017-03-17 Said Abou-Hallawa <[email protected]>
+
+ 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-21 Jason Marcell <[email protected]>
Merge r214014. rdar://problem/30921815
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (214270 => 214271)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp 2017-03-22 19:50:09 UTC (rev 214271)
@@ -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: branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp (214270 => 214271)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp 2017-03-22 19:50:09 UTC (rev 214271)
@@ -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: branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h (214270 => 214271)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h 2017-03-22 19:50:09 UTC (rev 214271)
@@ -83,6 +83,7 @@
int width;
int height;
float bias;
+ Vector<float> kernelMatrix;
};
FEConvolveMatrix(Filter&, const IntSize&, float, float,
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FilterEffect.h (214270 => 214271)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FilterEffect.h 2017-03-22 19:43:25 UTC (rev 214270)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/filters/FilterEffect.h 2017-03-22 19:50:09 UTC (rev 214271)
@@ -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;