CVE-2018-12153
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 crash on host).
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
7.7 - CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
CWE-131: Incorrect Calculation of Buffer Size
This vulnerability can be triggered by supplying a malformed pixel shader (in text or binary form) to the Intel igdusc64.dll driver. Such an 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.
By supplying a specially generated shader file, an attacker can force the igdusc64.dll to execute the “memcpy_s” function with arguments that trigger an exception, which later forces termination of the program in order to prevent memory corruption.
The initial problem starts when there is no proper validation of the return value provided by “sub_483870”. This value will be later used in the “sub_34BC30” in a while loop condition (maximum value of iterations). By supplying a malformed shader, an attacker can force this value to be 0xFFFFFFFF (-1), and therefore force the while loop in “sub_34BC30” to iterate a large number of times. Every iteration “sub_0x1E9A0” is called, fragments of which are provided below:
.text:000000000001E9E7 lea eax, ds:0[rbx*4] [1]
.text:000000000001E9EE mov ecx, eax ; Size (32bit value)
.text:000000000001E9F0 mov r14d, eax
.text:000000000001E9F3 call malloc
.text:000000000001E9F8 mov rbp, rax
.text:000000000001E9FB test rax, rax
.text:000000000001E9FE jz short loc_1EA3B
.text:000000000001EA00 mov r8d, r14d ; Size
.text:000000000001EA03 xor edx, edx ; Val
.text:000000000001EA05 mov rcx, rax ; Dst
.text:000000000001EA08 call memset
.text:000000000001EA0D mov r8, [rsi+18h] ; Src
.text:000000000001EA11 test r8, r8
.text:000000000001EA14 jz short loc_1EA31
.text:000000000001EA16 mov r9d, [rsi+20h] ; src size (count) 32-bit value
.text:000000000001EA1A mov edx, r14d ; DstSize
.text:000000000001EA1D mov rcx, rbp ; Dst
.text:000000000001EA20 shl r9, 2 ; src size << 2 -> extended to 64-bits [2]
.text:000000000001EA24 call memcpy_s ; memcpy_s(
.text:000000000001EA24 ; void *dest,
.text:000000000001EA24 ; size_t destSize,
.text:000000000001EA24 ; const void *src,
.text:000000000001EA24 ; size_t count
.text:000000000001EA24 ; )
.text:000000000001EA24 ;
.text:000000000001EA24 ;
.text:000000000001EA24 ; rcx - dest
.text:000000000001EA24 ; rdx - dest size
.text:000000000001EA24 ; r8 - src
.text:000000000001EA24 ; r9 - src size (count)
Please note that at [1], the LEA instruction is used to calculate the final size for the malloc
call. This is done by multiplying RBX register by 4 and truncating the result to a 32-bit value (the result is later stored in ECX / R14D). As you can see, the instruction at 0x1EA20 calculates the source size (count) parameter for the memcpy_s
function. The initial 32-bit value is taken from [rsi+0x20] memory and is multiplied later by shifting left at [2] (shl 2 / fast multiply by 4) but the result of this operation is a 64-bit value, not 32-bit, and it is stored in the R9 register.
By supplying the malformed pixel shader, an attacker can force the Intel igdusc64.dll driver to allocate memory with size 0 (calculated size parameter passed to malloc
will be 0 due to 32-bit number limitations) but the src
size (count) parameter passed to the memcpy_s
function will be much bigger (0x0000000080000000). If the normal memcpy
function would have been used that could cause a memory corruption, but since the memcpy_s
function is used in, the incorrect parameter will be detected and the exception will be thrown which will result in the application being terminated.
...
before memcpy_s: [i=33] rcx(dest)=0x0000001ddcea7040 rdx(dest_size)=0x10000000 r8(src)=0x0000001dd4e95040 r9(count)=0x0000000008000000 [rsi+20h]=0x02000000
after memcpy_s: returned 0x00000000
przed memcpy_s: rbx=0x0000000008000000 eax=rbx*4=0x20000000
before memcpy_s: [i=34] rcx(dest)=0x0000001d8000c040 rdx(dest_size)=0x20000000 r8(src)=0x0000001ddcea7040 r9(count)=0x0000000010000000 [rsi+20h]=0x04000000
after memcpy_s: returned 0x00000000
przed memcpy_s: rbx=0x0000000010000000 eax=rbx*4=0x40000000
before memcpy_s: [i=35] rcx(dest)=0x0000001dccf1d040 rdx(dest_size)=0x40000000 r8(src)=0x0000001d8000c040 r9(count)=0x0000000020000000 [rsi+20h]=0x08000000
after memcpy_s: returned 0x00000000
przed memcpy_s: rbx=0x0000000020000000 eax=rbx*4=0x80000000
before memcpy_s: [i=36] rcx(dest)=0x0000001e0cf2a040 rdx(dest_size)=0x80000000 r8(src)=0x0000001dccf1d040 r9(count)=0x0000000040000000 [rsi+20h]=0x10000000
after memcpy_s: returned 0x00000000
przed memcpy_s: rbx=0x0000000040000000 eax=rbx*4=0x00000000
before memcpy_s: [i=37] rcx(dest)=0x0000001dccad8af0 rdx(dest_size)=0x00000000 r8(src)=0x0000001e0cf2a040 r9(count)=0x0000000080000000 [rsi+20h]=0x20000000
0:000> g
(41c8.26d0): Security check failure or stack buffer overrun - code c0000409 (!!! second chance !!!)
igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+0x2323:
00007ffc`013697c3 cd29 int 29h
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\SYSTEM32\igd10iumd64.dll -
DUMP_CLASS: 2
DUMP_QUALIFIER: 0
FAULTING_IP:
igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+2323
00007ffc`013697c3 cd29 int 29h
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ffc013697c3 (igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+0x0000000000002323)
ExceptionCode: c0000409 (Security check failure or stack buffer overrun)
ExceptionFlags: 00000001
NumberParameters: 1
Parameter[0]: 0000000000000005
Subcode: 0x5 FAST_FAIL_INVALID_ARG
FAULTING_THREAD: 000026d0
PROCESS_NAME: POC_EXEC_SHADER.exe
ERROR_CODE: (NTSTATUS) 0xc0000409 - <Unable to get error code text>
EXCEPTION_CODE: (NTSTATUS) 0xc0000409 - <Unable to get error code text>
EXCEPTION_CODE_STR: c0000409
EXCEPTION_PARAMETER1: 0000000000000005
WATSON_BKT_PROCSTAMP: 5aaff6e9
WATSON_BKT_MODULE: igdusc64.dll
WATSON_BKT_MODSTAMP: 5a32f1cc
WATSON_BKT_MODOFFSET: 997c3
WATSON_BKT_MODVER: 10.18.14.4889
MODULE_VER_PRODUCT: Intel HD Graphics Drivers for Windows 8(R)
BUILD_VERSION_STRING: 6.3.9600.17415 (winblue_r4.141028-1500)
MODLIST_WITH_TSCHKSUM_HASH: 20e3a9569894c2d493762eac712fad7b6fab693e
MODLIST_SHA1_HASH: bda2d4950a1660ae4a44fc3b80dcd66d3bc070ce
NTGLOBALFLAG: 70
APPLICATION_VERIFIER_FLAGS: 0
PRODUCT_TYPE: 1
SUITE_MASK: 272
DUMP_TYPE: fe
ANALYSIS_SESSION_HOST: SPLINTER
ANALYSIS_SESSION_TIME: 03-21-2018 13:30:30.0896
ANALYSIS_VERSION: 10.0.15063.468 amd64fre
THREAD_ATTRIBUTES:
OS_LOCALE: PLK
PROBLEM_CLASSES:
ID: [0n262]
Type: [FAIL_FAST]
Class: Primary
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Add
Data: Omit
PID: [Unspecified]
TID: [Unspecified]
Frame: [0]
ID: [0n251]
Type: [INVALID_ARG_FAILURE]
Class: Addendum
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Add
Data: Omit
PID: [Unspecified]
TID: [Unspecified]
Frame: [0]
ID: [0n111]
Type: [EXPLOITABLE]
Class: Addendum
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Add
Data: Omit
PID: [0x41c8]
TID: [0x26d0]
Frame: [0] : igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>
BUGCHECK_STR: FAIL_FAST_INVALID_ARG_FAILURE_EXPLOITABLE
DEFAULT_BUCKET_ID: FAIL_FAST_INVALID_ARG_FAILURE_EXPLOITABLE
PRIMARY_PROBLEM_CLASS: FAIL_FAST
LAST_CONTROL_TRANSFER: from 00007ffc01369788 to 00007ffc013697c3
STACK_TEXT:
0000001d`c9babff0 00007ffc`01369788 : 0000001d`c9bac1b4 00000000`0d8a60f4 00000000`40000000 00007ffc`0136c848 : igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+0x2323
0000001d`c9bac020 00007ffc`013697a5 : 00000000`00000022 0000001d`ccad8af0 0000001e`0cf2a040 00000000`00000000 : igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+0x22e8
0000001d`c9bac060 00007ffc`01367c67 : 00000000`0000023c 0000001d`00000004 0000001d`c9ddd9b8 00000000`0000023c : igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+0x2305
0000001d`c9bac0a0 00007ffc`012dea29 : 00000000`40000000 0000001d`c9ddd9b8 00000000`00000001 00000000`00000003 : igdusc64!USC::DeleteCompilerOutputPixelShaderOpenGL_impl<USC::SCompilerOutputPixelShaderOpenGL_Gen9>+0x7c7
0000001d`c9bac0d0 00007ffc`0160be94 : 00000000`20000000 00000000`ffffffff 0000001d`c9bac228 0000001d`c9ddd900 : igdusc64!USC::CShaderInputDecl::GetVertexIDRegisterNum+0xcb69
0000001d`c9bac100 00007ffc`01744570 : 0000001d`00000001 0000001d`ccb425a8 0000001d`0000015e 0000001d`ccb21254 : igdusc64!USC::SetClientCallbacks+0x250f34
0000001d`c9bac160 00007ffc`0173dce9 : 00000000`00000001 00000000`0000023c 00000000`00000001 0000001d`c9bac478 : igdusc64!USC::SetClientCallbacks+0x389610
0000001d`c9bac350 00007ffc`0173c542 : 0000001d`ccb21254 0000001d`cca9f290 00000000`0000023c 0000001d`ccb42468 : igdusc64!USC::SetClientCallbacks+0x382d89
0000001d`c9bac3e0 00007ffc`0173b544 : 0000001d`ccae5b50 0000001d`c9bac600 0000001d`ccb42468 0000001d`cca9f8b0 : igdusc64!USC::SetClientCallbacks+0x3815e2
0000001d`c9bac510 00007ffc`0173bd63 : 0000001d`ccae5b50 0000001d`c9bac650 00000000`00000001 0000001d`cca9f8b0 : igdusc64!USC::SetClientCallbacks+0x3805e4
0000001d`c9bac590 00007ffc`01735157 : 0000001d`00000001 00000000`00000001 0000001d`ccae5660 0000001d`cca9f8b0 : igdusc64!USC::SetClientCallbacks+0x380e03
0000001d`c9bac650 00007ffc`01735c41 : 00000000`00000081 00000000`00000001 00007ffc`01c54ad6 0000001d`c9e17880 : igdusc64!USC::SetClientCallbacks+0x37a1f7
0000001d`c9bac6b0 00007ffc`01730fcf : 00000000`00000001 0000001d`ccae70a0 0000001d`c9e175f0 0000001d`ccae5660 : igdusc64!USC::SetClientCallbacks+0x37ace1
0000001d`c9bac6f0 00007ffc`017ceca9 : 00000000`00000001 00000000`00000001 00000000`00000001 00000000`00000000 : igdusc64!USC::SetClientCallbacks+0x37606f
0000001d`c9bac8b0 00007ffc`013e6707 : 0000001d`00000000 0000001d`00000001 0000001d`c9dd7d40 0000001d`00000001 : igdusc64!USC::getInitShaderWriteMask+0x22409
0000001d`c9bacad0 00007ffc`013e6bf9 : 00000000`00000001 00007ffc`00000001 0000001d`c9d80001 00000000`00000000 : igdusc64!USC::SetClientCallbacks+0x2b7a7
0000001d`c9bacc00 00007ffc`013e8956 : 0000001d`c9bacd00 0000001d`c9bacd00 00000000`00000001 0000001d`c9dd1d00 : igdusc64!USC::SetClientCallbacks+0x2bc99
0000001d`c9baccb0 00007ffc`013e9043 : 0000001d`00000000 0000001d`00000001 0000001d`c9bace70 00000000`00000001 : igdusc64!USC::SetClientCallbacks+0x2d9f6
0000001d`c9bacd50 00007ffc`013e9274 : 00000000`00000001 0000001d`00000001 0000001d`c9bad170 00007ffc`01760131 : igdusc64!USC::SetClientCallbacks+0x2e0e3
0000001d`c9bacdd0 00007ffc`0175ef3e : 00000000`00000001 0000001d`c9bacf50 0000001d`c9dd1d10 00000000`00000300 : igdusc64!USC::SetClientCallbacks+0x2e314
0000001d`c9bace50 00007ffc`01318907 : 00000001`c9d92001 0000001d`c9dd1080 0000001d`c9bad7d8 0000001d`c9d80000 : igdusc64!USC::SetClientCallbacks+0x3a3fde
0000001d`c9bad080 00007ffc`01320eeb : 00003900`00000000 00003900`00000000 00003900`00000000 00000001`00000000 : igdusc64!OpenCompiler12+0x4267
0000001d`c9bad120 00007ffc`013230ef : 00000000`00000001 0000001d`c9d9204c 0000001d`c9bad7d8 0000001d`c9dc01b0 : igdusc64!OpenCompiler12+0xc84b
0000001d`c9bad490 00007ffc`0131ecd4 : 0000001d`c9dceb00 00000000`00000000 0000001d`c9bad800 00000000`00000001 : igdusc64!OpenCompiler12+0xea4f
0000001d`c9bad580 00007ffc`02fbc43c : 00007ffc`03759580 0000001d`c9bad800 00000000`00000001 00000000`00000001 : igdusc64!OpenCompiler12+0xa634
0000001d`c9bad5e0 00007ffc`0371cce8 : 00007ffc`00000080 0000001d`00000001 00007ffc`03759580 00007ffc`03759580 : igd10iumd64!OpenAdapter10_2+0x3ae83c
0000001d`c9bad700 00007ffc`0371c7c1 : 0000001d`c9db7340 0000001d`c9dad5a0 0000001d`c9badda8 00000000`00000000 : d3d11!CPixelShader::CLS::FinalConstruct+0x238
0000001d`c9bad8c0 00007ffc`0371c6d0 : 0000001d`c9dd0990 0000001d`c9dd0940 00007ffc`03753448 0000001d`c9badda8 : d3d11!CLayeredObjectWithCLS<CPixelShader>::FinalConstruct+0xd5
0000001d`c9bad930 00007ffc`0371c5a7 : 0000001d`c9dd0990 0000001d`c9dd0990 00000000`00000009 0000001d`c9baf140 : d3d11!CLayeredObjectWithCLS<CPixelShader>::CreateInstance+0x11c
0000001d`c9bad990 00007ffc`03707fdd : 00000000`00000000 00000000`00000009 00000000`00000000 0000001d`c9baf110 : d3d11!CDevice::CreateLayeredChild+0x1cff
0000001d`c9baef50 00007ffc`03707e39 : 0000001d`c9dd0958 00000000`00000009 0000001d`c9baf4c8 00000000`00000003 : d3d11!NDXGI::CDevice::CreateLayeredChild+0x222
0000001d`c9baf0d0 00007ffc`0371ca78 : 0000001d`c9dab610 0000001d`00000009 0000001d`c9dab610 0000001d`c9baf3b0 : d3d11!NOutermost::CDevice::CreateLayeredChild+0x281
0000001d`c9baf290 00007ffc`0371c9d8 : 0000001d`c9d91fb0 0000001d`00000000 0000001d`c9baf510 00000000`00000000 : d3d11!CDevice::CreateAndRecreateLayeredChild<SD3D11LayeredPixelShaderCreationArgs>+0x78
0000001d`c9baf2f0 00007ffc`03720766 : 0000001d`c9dabc30 0000001d`c9d91fb0 00000000`00001718 00000000`00000000 : d3d11!CDevice::CreatePixelShader_Worker+0x1a0
0000001d`c9baf440 00007ff6`686e6700 : 00000001`00000000 00000000`00000000 ffffffff`fffffffe 0000001d`c9c74a60 : d3d11!CDevice::ID3D10Device1_CreatePixelShader_+0x26
0000001d`c9baf490 00007ff6`686e6634 : 00007ff6`686f2888 00000000`00008000 0000001d`c9dce1f0 00000000`0000021c : POC_EXEC_SHADER!FuzzFunction+0x40
0000001d`c9baf540 00007ff6`686e5caa : 0000001d`c9baf870 00007ff6`686e0000 0069005f`0000000a 00007ffb`00000000 : POC_EXEC_SHADER+0x6634
0000001d`c9baf830 00007ff6`686e7d62 : 00000000`0000000a 00000000`0000000a 00000000`00000000 00007ff6`67d7f000 : POC_EXEC_SHADER+0x5caa
0000001d`c9bafa70 00007ffc`06db13d2 : 00007ff6`686e7dd0 00000000`00000000 00000000`00000000 00000000`00000000 : POC_EXEC_SHADER!FuzzFunction+0x16a2
0000001d`c9bafab0 00007ffc`08a254f4 : 00007ffc`06db13b0 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x22
0000001d`c9bafae0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34
THREAD_SHA1_HASH_MOD_FUNC: 817c6f72227ee987fefc30f98ceaf74ae31d6a27
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 29fa308109451b13e5a8204ec4cfbde54f8fd1f9
THREAD_SHA1_HASH_MOD: 221f28973e14c9cd059813826a888982f6ef78fc
FOLLOWUP_IP:
igdusc64!USC::CShaderInputDecl::GetVertexIDRegisterNum+cb69
00007ffc`012dea29 488bce mov rcx,rsi
FAULT_INSTR_CODE: e8ce8b48
SYMBOL_STACK_INDEX: 4
SYMBOL_NAME: igdusc64!USC::CShaderInputDecl::GetVertexIDRegisterNum+cb69
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: igdusc64
IMAGE_NAME: igdusc64.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 5a32f1cc
STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ; dt ntdll!LdrpFailureData ; ~0s ; kb
BUCKET_ID: FAIL_FAST_INVALID_ARG_FAILURE_EXPLOITABLE_igdusc64!USC::CShaderInputDecl::GetVertexIDRegisterNum+cb69
FAILURE_EXCEPTION_CODE: c0000409
FAILURE_IMAGE_NAME: igdusc64.dll
BUCKET_ID_IMAGE_STR: igdusc64.dll
FAILURE_MODULE_NAME: igdusc64
BUCKET_ID_MODULE_STR: igdusc64
FAILURE_FUNCTION_NAME: USC::CShaderInputDecl::GetVertexIDRegisterNum
BUCKET_ID_FUNCTION_STR: USC::CShaderInputDecl::GetVertexIDRegisterNum
BUCKET_ID_OFFSET: cb69
BUCKET_ID_MODTIMEDATESTAMP: 5a32f1cc
BUCKET_ID_MODCHECKSUM: 5fd23b
BUCKET_ID_MODVER_STR: 10.18.14.4889
BUCKET_ID_PREFIX_STR: FAIL_FAST_INVALID_ARG_FAILURE_EXPLOITABLE_
FAILURE_PROBLEM_CLASS: FAIL_FAST
FAILURE_SYMBOL_NAME: igdusc64.dll!USC::CShaderInputDecl::GetVertexIDRegisterNum
FAILURE_BUCKET_ID: FAIL_FAST_INVALID_ARG_FAILURE_EXPLOITABLE_c0000409_igdusc64.dll!USC::CShaderInputDecl::GetVertexIDRegisterNum
TARGET_TIME: 2018-03-21T12:30:46.000Z
OSBUILD: 9600
OSSERVICEPACK: 17415
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
OSPLATFORM_TYPE: x64
OSNAME: Windows 8.1
OSEDITION: Windows 8.1 WinNt SingleUserTS
USER_LCID: 0
OSBUILD_TIMESTAMP: 2014-10-29 03:45:30
BUILDDATESTAMP_STR: 141028-1500
BUILDLAB_STR: winblue_r4
BUILDOSVER_STR: 6.3.9600.17415
ANALYSIS_SESSION_ELAPSED_TIME: 3e6e
ANALYSIS_SOURCE: UM
FAILURE_ID_HASH_STRING: um:fail_fast_invalid_arg_failure_exploitable_c0000409_igdusc64.dll!usc::cshaderinputdecl::getvertexidregisternum
FAILURE_ID_HASH: {7f9c49a1-193c-e6e4-cca8-012bb2329742}
Followup: MachineOwner
---------
2018-04-19 - Vendor Disclosure
2018-10-09 - Public Release
Discovered by Piotr Bania of Cisco Talos.