[Webkit-unassigned] [Bug 60771] New: Integer overflow on chrome in text width estimation code
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Fri May 13 08:12:43 PDT 2011
https://bugs.webkit.org/show_bug.cgi?id=60771
Summary: Integer overflow on chrome in text width estimation
code
Product: WebKit
Version: 528+ (Nightly build)
Platform: PC
OS/Version: Windows Vista
Status: NEW
Severity: Normal
Priority: P1
Component: CSS
AssignedTo: webkit-unassigned at lists.webkit.org
ReportedBy: skylined at chromium.org
Created an attachment (id=93454)
--> (https://bugs.webkit.org/attachment.cgi?id=93454&action=review)
Repro (crashes renderer)
Chromium bug: http://code.google.com/p/chromium/issues/detail?id=82275
Repro:
<html>
<script>
iFontSize = 0x7300;
iLetterSpacing = 0x1376;
iStringLength = 0xFFFF;
setTimeout(function f() {
document.write(
'<style>*{' +
'font-size: ' + iFontSize + 'px;' +
'letter-spacing: ' + iLetterSpacing + 'px;' +
'-webkit-box-reflect: above -1px url(x);' +
'-webkit-transition-duration: 0s;' +
'}</style>' +
'<body>' + new Array(iStringLength + 1).join('W') + '</body>');
}, 1000);
</script>
</html>
webkit\source\webcore\platform\graphics\chromium\fontchromiumwin.cpp @ 244:
IntRect TransparencyAwareGlyphPainter::estimateTextBounds()
{
int totalWidth = 0;
for (int i = 0; i < m_numGlyphs; i++)
totalWidth += lroundf(m_glyphBuffer.advanceAt(m_from + i));
const FontMetrics& fontMetrics = m_font->fontMetrics();
return IntRect(m_point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
m_point.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
fontMetrics.lineSpacing());
}
The repro cause the value of the integer totalWidth to get incremented to a very large number, which combined with the "ascent" and "descent" values will overflow. The result is a very large negative width for the IntRect.
A little later one in code flow, it looks like the code tries to check if the values make sense:
bad math related to "pixelSize":
c:\src\chromium\src\third_party\webkit\source\webcore\platform\graphics\chromium\transparencywin.cpp @ 358:
void TransparencyWin::initializeNewContext()
{
int pixelSize = m_layerSize.width() * m_layerSize.height();
if (pixelSize <= 0)
return;
Unfortunately, this check is as good as useless and we do not return. On windows, the negative width makes it all way up to the platform layer where GDI returns an error when the code asks windows to allocate a bitmap. The code detects this failure and terminates the renderer as if there had been an OOM condition.
It should be obvious that the math for totalWidth and IntRect width and the sanity checks on the IntRects width are incorrect and that we should not rely on the platform layer to save us.
I was hoping I could find a way to increase totalWidth to the point where the value becomes positive again, so GDI doesn't throw an error and I could prove this is actually exploitable. I have been unable to do this because the css properties I am using seem to get ignored if I increase them any further. There must be some earlier checks, but I was unable to find them.
--
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.
More information about the webkit-unassigned
mailing list