Почему этот тег iframe приводит к сбою Safari в 64-разрядной версии Windows?

Если вы не слышали, этот кусок кода вызовет сбой BSoD на 64-битной Windows 7 при запуске в Safari

<iframe height='18082563'></iframe>

Поэтому, естественно, возникает вопрос, как именно это происходит, и почему 18082563, а не сказать "1808256 4"?

2 ответа

Решение

Это объяснение этому.

http://pastebin.com/XTWnLF3p

Ошибка возникает из-за запроса NineGrid, поступающего через GdiDrawStream, отправляемого от имени библиотеки тем UX, которая обрабатывает темы Windows, начиная с XP и позже.

Браузеры Webkit (наряду с IE8 - но не IE9, казалось бы) пытаются отображать HTML-элементы на странице, используя собственный скин ОС. В этом случае в функции drawControl (см. http://www.opensource.apple.com/source/WebCore/WebCore-658.28/rendering/RenderThemeWin.cpp) вызывается DrawThemeBackground, которое обрабатывает скины элементов управления ОС.

Отправляется 96-байтовый буфер (0x60) (параметры 2 и 3 GdiDrawStream - это размер и адрес буфера, параметр 1 - это HDC).

Рисование Steam-буферов начинается с магического значения, за которым следует серия команд, идентифицированных 32-байтовым рынком. Вот поток, отправленный со специальным iframe при просмотре в Safari:

44727753 = 'DrwS' = DrawStream Magic

Командные буферы:

#0: 00000000 <SET TARGET>
    3b01017a // Destination DC (hdc) *** Must match HDC in GdiDrawStream argument 1 ***
    // Destination Clip (ERECTL):
    0000011b // Left
    00000011 // Top
    0000012c // Right
    0089f580 // Bottom               *** Multiply by 2, and you get the "magic" value used in the iframe PoC ***
#1: 00000001 <SET SOURCE>
    058506a3 // Source Surface (pso)  *** Dumped the surface from kernel mode, got a 13x5 32BPP bitmap which is the Luna/Aero scrollbar slider control ***
#2: 00000009 <NINEGRID>
// Destination Clip (ERECTL):          *** Should match the Destination Clip of the Target
    0000011b // Left
    00000011 // Top
    0000012c // Right
    0089f580 // Bottom
// Source Clip (ERECTL):                 *** Should be within the bounds of the surface (which is 13x5 in this case)
    00000000 // Left
    00000000 // Top
    0000000e // Right
    00000001 // Bottom
// NINEGRID_BITMAP_INFO             *** Documented in RDP docs. Should fit within the surface and destination.
    00000001 // Flags (DSDNG_STRETCH)
    0000000a // Left Width
    00000003 // Right Width
    00000000 // Top Height
    00000000 // Bottom Height
    00000000 // Transparent

Вот сырая свалка:

0: kd> dds @r8 l18
00000000`003be664  44727753
00000000`003be668  00000000
00000000`003be66c  2b0108d5   // HDC, this will change from dump to dump
00000000`003be670  0000011b
00000000`003be674  00000011
00000000`003be678  0000012c
00000000`003be67c  0089f580
00000000`003be680  00000001
00000000`003be684  018503c2   // Bitmap Surface, this will change from dump to dump
00000000`003be688  00000009
00000000`003be68c  0000011b
00000000`003be690  00000011
00000000`003be694  0000012c
00000000`003be698  0089f580
00000000`003be69c  00000000
00000000`003be6a0  00000000
00000000`003be6a4  0000000e
00000000`003be6a8  00000001
00000000`003be6ac  00000001
00000000`003be6b0  0000000a
00000000`003be6b4  00000003
00000000`003be6b8  00000000
00000000`003be6bc  00000000
00000000`003be6c0  00000000

По сути, вы видите iframe, который имеет особенно интересную высоту, когда математическая ошибка в преобразовании NineGrid при рисовании и тематическом отображении полосы прокрутки вызывает запись "за пределами". Этот PoC будет работать в IE 8, но IE 8 имеет хорошо известную ошибку CSS, в которой он имеет максимальный предел пикселей (около 1342177), поэтому он не проявляется сразу.

ДРУГИЕ ВЫСОТЫ ВОЗМОЖНЫ, а некоторые могут быть достаточно маленькими, так что даже IE 8 попадает в угол высоты NineGrid.

IE9, по-видимому, вообще не управляет темами, использующими UxTheme, и его поведение полосы прокрутки отличается от IE 8, поэтому, несмотря на то, что ограничения по пикселям больше нет, PoC не работает. Firefox не был протестирован.

НЕ ТОЛЬКО УЛУЧШЕНИЯ. Тестирование с использованием HTML такой же высоты привело к сбою в Safari.

Это означает, что любой клиент, локальный или удаленный, который создает скины элементов управления (т. Е. Почти все из них - даже кнопка во флэш-PDF), может привести к преобразованию NineGrid, которое попадет в эту ошибку. Это совсем не специфично для WebKit.

Как примечание, MS недавно выпустила MS12-008, который исправляет это.

Другие вопросы по тегам