Talos Vulnerability Report

TALOS-2018-0533

Intel Unified Shader Compiler for Intel Graphics Accelerator Pointer Corruption

October 9, 2018
CVE Number

CVE-2018-12152

Summary

An exploitable pointer corruption 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 a pointer corruption resulting in at least denial of service or, if exploited successfully, code execution. 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 a VMware guest and the VMware host will be affected (potentially leading VMware toi crash or a guest-to-host escape).

Tested Versions

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

Product URLs

http://intel.com

CVSSv3 Score

9.0 - CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-822: Untrusted Pointer Dereference

Details

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 a local machine (usermode), from VMware guest usermode (to cause memory corruption on VMware host) or theoretically through WEBGL (remote website) – assuming the browser will not use ANGLE and will somehow supply the malformed shader to the vulnerable Intel driver.

A specifically crafted shader file causes igdusc64.dll driver to execute memory location taken from a pointer that is corrupted/invalid:

17a0.13ec): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
igdusc64!USC::SetClientCallbacks+0x360024:
00007ffe`8b9daf84 ff90e0000000    call    qword ptr [rax+0E0h] ds:00007ffe`00000160=????????????????

More disassembly:

.text:000000000045AF40 loc_45AF40:                             ; CODE XREF: sub_45AEB0+112°j
.text:000000000045AF40                 mov     rax, [r14+20h]
.text:000000000045AF44                 mov     ecx, [rsi+rax]  ; rsi = 0/8; rax = mem
.text:000000000045AF47                 mov     rax, [r15+18h]
.text:000000000045AF4B                 cmp     ecx, [rax+30h]
.text:000000000045AF4E                 jnb     short loc_45AFBB
.text:000000000045AF50                 mov     rdi, [rax+28h]
.text:000000000045AF54                 test    rdi, rdi
.text:000000000045AF57                 jz      short loc_45AF64
.text:000000000045AF59                 cmp     ecx, [rax+30h]
.text:000000000045AF5C                 jnb     short loc_45AF64
.text:000000000045AF5E                 mov     rdi, [rdi+rcx*8] ; rdi = mem with call pointer (v-table), rcx = index
... 
.text:000000000045AF7E                 mov     rax, [rdi]
.text:000000000045AF81                 mov     rcx, rdi
.text:000000000045AF84                 call    qword ptr [rax+0E0h]

An attacker can influence the index value (0x45AF5E) used for calculating the final pointer however this is not the culprit of the problem. The actual pointer corruption happens in some odd way, earlier in sub_142B0. This function writes a new pointer to a [mem - 4] region where later [mem] region is being used by the function that uses this region as a “source” for a call instruction destination. Meaning the final pointer will in fact be computed from two different pointers.

addr_45AF44: rsi=0x0000000000000008 rax=0x0000008029c2eae4 [rsi+rax]=0x0100e400000002a6  
addr_45AF4B: ecx = 0x000002a6 must be < [@rax+0x30]=0x0000032e  
addr_45AF5E: rdi_calced=0x0000008029505a78 rdi=0x00000080297b3000 rcx=0x00000000000002a6
    
0:000> ? @rax
Evaluate expression: 140728898420864 = 00007ffe`00000080
0:000> dd poi(poi(0x80297b3000+(0x2a6*8)))
00007ffe`00000080  ???????? ???????? ???????? ????????

0:000> dd (poi(0x80297b3000+(0x2a6*8)))
00000080`29505a78  00000080 00007ffe 00000000 c0c0c0c0

but 4 bytes before we have a valid pointer:
0:000>  dd (poi(0x80297b3000+(0x2a6*8)))-4
00000080`29505a74  29505a08 00000080 00007ffe 00000000
00000080`29505a84  c0c0c0c0 2966cec0 00000080 0000006f

0:000> ? poi(00000080`29505a74)
Evaluate expression: 550448945672 = 00000080`29505a08
0:000> db poi(00000080`29505a74)
00000080`29505a08  18 0f ae 29 80 00 00 00-fe 7f 00 00 00 00 00 00  ...)............
00000080`29505a18  c0 c0 c0 c0 c0 ce 66 29-80 00 00 00 00 00 00 00  ......f)........

In this example the memory address with call destination was 0x0000008029505a78, but sub_142B0 wrote a pointer to 0x0000008029505a74 - so 4 bytes before that.

# writing to mem rbx=0x0000008029505a74 [rbx]=0x8bad6200abcd0068 [rbx+4]=0x00007ffe8bad6200   value=0x0000008029505a08 

The rest of v-table does not appear to be corrupted, all other entries are valid:

...
[index 0x29f] dump: addr=0x0000008022d822ce value=0x00007ffe8bad1400 
[index 0x2a0] dump: addr=0x0000008022d8214a value=0x00007ffe8bad1400 
[index 0x2a1] dump: addr=0x0000008022d8220c value=0x00007ffe8bad1400 
[index 0x2a2] dump: addr=0x0000008022d81fc6 value=0x00007ffe8bad1400 
[index 0x2a3] dump: addr=0x0000008022d82088 value=0x00007ffe8bad1400 
[index 0x2a4] dump: addr=0x0000008022d82390 value=0x00007ffe8bad1400 
[index 0x2a5] dump: addr=0x0000008022d81f04 value=0x00007ffe8bad1400 
[index 0x2a6] dump: addr=0x0000008029505a78 value=0x00007ffe00000080 *BAD*

and all the entries appear to point to correct function locations:

0:000> u poi(0x00007ffe8bad1400)
igdusc64!USC::CShaderInputDecl::GetVertexIDRegisterNum+0x29f0:
00007ffe`8b5948b0 48895c2408      mov     qword ptr [rsp+8],rbx
00007ffe`8b5948b5 57              push    rdi
00007ffe`8b5948b6 4883ec20        sub     rsp,20h

The heap memory itself doesn’t appear to be corrupted as well. Whether such “limited” control for the attacker is enough to turn this bug into full code execution is unclear, but cannot be excluded entirely.

Crash Information

*******************************************************************************
*                                                                             *
*                        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::SetClientCallbacks+360024
00007ffe`8b9daf84 ff90e0000000    call    qword ptr [rax+0E0h]

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 00007ffe8b9daf84 (igdusc64!USC::SetClientCallbacks+0x0000000000360024)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: 00007ffe00000160
Attempt to read from address 00007ffe00000160

FAULTING_THREAD:  000013ec

PROCESS_NAME:  WIN_SHADER.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  0000000000000000

EXCEPTION_PARAMETER2:  00007ffe00000160

FOLLOWUP_IP: 
igdusc64!USC::SetClientCallbacks+360024
00007ffe`8b9daf84 ff90e0000000    call    qword ptr [rax+0E0h]

READ_ADDRESS:  00007ffe00000160 

WATSON_BKT_PROCSTAMP:  5a89e571

WATSON_BKT_MODULE:  igdusc64.dll

WATSON_BKT_MODSTAMP:  5a32f1cc

WATSON_BKT_MODOFFSET:  44af84

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:  7a536923884739ba15d73c254d557dac9948796e

MODLIST_SHA1_HASH:  09cee563152c19a057cc45f96a1cbed214d1c51b

NTGLOBALFLAG:  2000000

APPLICATION_VERIFIER_FLAGS:  0

PRODUCT_TYPE:  1

SUITE_MASK:  272

DUMP_TYPE:  fe

APPLICATION_VERIFIER_LOADED: 1

ANALYSIS_SESSION_HOST:  SPLINTER

ANALYSIS_SESSION_TIME:  02-19-2018 17:56:01.0124

ANALYSIS_VERSION: 10.0.15063.468 amd64fre

THREAD_ATTRIBUTES: 
OS_LOCALE:  PLK

PROBLEM_CLASSES: 

    ID:     [0n292]
    Type:   [@ACCESS_VIOLATION]
    Class:  Addendum
    Scope:  BUCKET_ID
    Name:   Omit
    Data:   Omit
    PID:    [Unspecified]
    TID:    [0x13ec]
    Frame:  [0] : igdusc64!USC::SetClientCallbacks

    ID:     [0n264]
    Type:   [INVALID_POINTER_READ]
    Class:  Primary
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [Unspecified]
    TID:    [0x13ec]
    Frame:  [0] : igdusc64!USC::SetClientCallbacks

    ID:     [0n92]
    Type:   [AVRF]
    Class:  Addendum
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [0x17a0]
    TID:    [0x13ec]
    Frame:  [0] : igdusc64!USC::SetClientCallbacks

    ID:     [0n102]
    Type:   [IN_CALL]
    Class:  Addendum
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [0x17a0]
    TID:    [0x13ec]
    Frame:  [0] : igdusc64!USC::SetClientCallbacks

BUGCHECK_STR:  APPLICATION_FAULT_INVALID_POINTER_READ_IN_CALL_AVRF

DEFAULT_BUCKET_ID:  INVALID_POINTER_READ_IN_CALL_AVRF

PRIMARY_PROBLEM_CLASS:  APPLICATION_FAULT

LAST_CONTROL_TRANSFER:  from 00007ffe8b9d97ae to 00007ffe8b9daf84

STACK_TEXT:  
00000080`20c2c970 00007ffe`8b9d97ae : 00000000`00000006 00000080`20c2ca79 00000080`2342afd0 00000000`00000000 : igdusc64!USC::SetClientCallbacks+0x360024
00000080`20c2c9c0 00007ffe`8b9db142 : 00000000`00000070 00000080`2966cdc0 00000000`00000001 00000080`2966cdc0 : igdusc64!USC::SetClientCallbacks+0x35e84e
00000080`20c2cae0 00007ffe`8ba880de : 00000000`00000001 00000000`00000000 00000000`00000001 00000000`00000001 : igdusc64!USC::SetClientCallbacks+0x3601e2
00000080`20c2cb40 00007ffe`8ba8ed5a : 00000000`00000000 00000000`00000001 00000080`20c2cc70 00000000`00000001 : igdusc64!USC::getInitShaderWriteMask+0x1b83e
00000080`20c2cb70 00007ffe`8b6a6707 : 00000080`00000001 00000080`00000000 00000080`2966cdc0 00000080`00000001 : igdusc64!USC::getInitShaderWriteMask+0x224ba
00000080`20c2cd90 00007ffe`8b6a6bf9 : 00000000`00000001 00007ffe`00000001 00000080`22460001 00000000`00000000 : igdusc64!USC::SetClientCallbacks+0x2b7a7
00000080`20c2cec0 00007ffe`8b6a8956 : 00000080`20c2d000 00000080`20c2d000 00000000`00000001 00000080`22efcd00 : igdusc64!USC::SetClientCallbacks+0x2bc99
00000080`20c2cf70 00007ffe`8b6a9043 : 00000080`00000000 00000080`00000001 00000080`20c2d130 00000000`00000001 : igdusc64!USC::SetClientCallbacks+0x2d9f6
00000080`20c2d010 00007ffe`8b6a9274 : 00000000`00000001 00000080`00000001 00000080`20c2d430 00007ffe`8ba20131 : igdusc64!USC::SetClientCallbacks+0x2e0e3
00000080`20c2d090 00007ffe`8ba1ef3e : 00000000`00000001 00000080`20c2d210 00000080`22efcd90 00000000`00000000 : igdusc64!USC::SetClientCallbacks+0x2e314
00000080`20c2d110 00007ffe`8b5d8907 : 00000000`00000000 00000000`00000000 00000080`20c2da98 00000080`22460000 : igdusc64!USC::SetClientCallbacks+0x3a3fde
00000080`20c2d340 00007ffe`8b5e0eeb : 00003900`00000000 00003900`00000000 00003900`00000000 00000001`00000000 : igdusc64!OpenCompiler12+0x4267
00000080`20c2d3e0 00007ffe`8b5e30ef : 00000000`00000001 00000080`228f544c 00000080`20c2da98 00000080`2293fca0 : igdusc64!OpenCompiler12+0xc84b
00000080`20c2d750 00007ffe`8b5decd4 : 00000080`22690fc0 00000000`00000000 00000080`20c2dac0 00000000`00000001 : igdusc64!OpenCompiler12+0xea4f
00000080`20c2d840 00007ffe`8cc6c43c : 00007ffe`8d3a9580 00000080`20c2dac0 00000000`00000001 00000000`00000001 : igdusc64!OpenCompiler12+0xa634
00000080`20c2d8a0 00007ffe`8d36cce8 : 00007ffe`00000080 00000080`00000001 00007ffe`8d3a9580 00007ffe`8d3a9580 : igd10iumd64!OpenAdapter10_2+0x3ae83c
00000080`20c2d9c0 00007ffe`8d36c7c1 : 00000080`22c59eb0 00000080`22c50110 00000080`20c2e068 00000000`00000000 : d3d11!CPixelShader::CLS::FinalConstruct+0x238
00000080`20c2db80 00007ffe`8d36c6d0 : 00000080`22654c10 00000080`22654bb0 00007ffe`8d3a3448 00000080`20c2e068 : d3d11!CLayeredObjectWithCLS<CPixelShader>::FinalConstruct+0xd5
00000080`20c2dbf0 00007ffe`8d36c5a7 : 00000080`22654c10 00000080`22654c10 00000000`00000009 00000080`20c2f400 : d3d11!CLayeredObjectWithCLS<CPixelShader>::CreateInstance+0x11c
00000080`20c2dc50 00007ffe`8d357fdd : 00000000`00000000 00000000`00000009 00000000`00000000 00000080`20c2f3d0 : d3d11!CDevice::CreateLayeredChild+0x1cff
00000080`20c2f210 00007ffe`8d357e39 : 00000080`22654bc8 00000000`00000009 00000080`20c2f790 00000080`22654bb0 : d3d11!NDXGI::CDevice::CreateLayeredChild+0x222
00000080`20c2f390 00007ffe`8d36ca78 : 00000080`22c0a020 00000000`00000009 00000080`22c0a020 00000080`20c2f670 : d3d11!NOutermost::CDevice::CreateLayeredChild+0x281
00000080`20c2f550 00007ffe`8d36c9d8 : 00000080`228f53b0 00007ff7`00000000 00000080`20c2f7d1 00000000`00000000 : d3d11!CDevice::CreateAndRecreateLayeredChild<SD3D11LayeredPixelShaderCreationArgs>+0x78
00000080`20c2f5b0 00007ffe`8d370766 : 00000080`22c0a640 00000080`228f53b0 00000000`00000c50 00000000`00000000 : d3d11!CDevice::CreatePixelShader_Worker+0x1a0
00000080`20c2f700 00007ff7`f9371e45 : 00000080`22c0a670 00000003`0000a000 00000001`00000000 00000000`00000000 : d3d11!CDevice::ID3D10Device1_CreatePixelShader_+0x26
00000080`20c2f750 00007ff7`f9371d57 : 00007ff7`f9377758 00000000`7fa4e1cc 00000080`22731cb0 00000000`0000021c : WIN_SHADER!XFunction+0x55
00000080`20c2f810 00007ff7`f9371475 : 00000080`20c2fb40 00007ff7`f9370000 0069005f`0000000a 00007ffe`00000000 : WIN_SHADER!MyWnd::MyCreateWindow+0x8c7
00000080`20c2fb00 00007ff7`f9372f72 : 00000000`0000000a 00000000`0000000a 00000000`00000000 00007ff7`f8bf4000 : WIN_SHADER!WinMain+0xe5
00000080`20c2fd40 00007ffe`924413d2 : 00007ff7`f9372fe0 00000000`00000000 00000000`00000000 00000000`00000000 : WIN_SHADER!__scrt_common_main_seh+0x10a
00000080`20c2fd80 00007ffe`928654f4 : 00007ffe`924413b0 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x22
00000080`20c2fdb0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34


THREAD_SHA1_HASH_MOD_FUNC:  54bd68918001db9210a1b61a7b11ba25e22eee6c

THREAD_SHA1_HASH_MOD_FUNC_OFFSET:  764b97d120f46a3de1b4521c67db3c4d8d212a77

THREAD_SHA1_HASH_MOD:  82eb628f0bda9b98aba4b00425c9f9871de8070d

FAULT_INSTR_CODE:  e090ff

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  igdusc64!USC::SetClientCallbacks+360024

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

FAILURE_BUCKET_ID:  INVALID_POINTER_READ_IN_CALL_AVRF_c0000005_igdusc64.dll!USC::SetClientCallbacks

BUCKET_ID:  APPLICATION_FAULT_INVALID_POINTER_READ_IN_CALL_AVRF_igdusc64!USC::SetClientCallbacks+360024

FAILURE_EXCEPTION_CODE:  c0000005

FAILURE_IMAGE_NAME:  igdusc64.dll

BUCKET_ID_IMAGE_STR:  igdusc64.dll

FAILURE_MODULE_NAME:  igdusc64

BUCKET_ID_MODULE_STR:  igdusc64

FAILURE_FUNCTION_NAME:  USC::SetClientCallbacks

BUCKET_ID_FUNCTION_STR:  USC::SetClientCallbacks

BUCKET_ID_OFFSET:  360024

BUCKET_ID_MODTIMEDATESTAMP:  5a32f1cc

BUCKET_ID_MODCHECKSUM:  5fd23b

BUCKET_ID_MODVER_STR:  10.18.14.4889

BUCKET_ID_PREFIX_STR:  APPLICATION_FAULT_INVALID_POINTER_READ_IN_CALL_AVRF_

FAILURE_PROBLEM_CLASS:  APPLICATION_FAULT

FAILURE_SYMBOL_NAME:  igdusc64.dll!USC::SetClientCallbacks

TARGET_TIME:  2018-02-19T16:56:33.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:  7f05

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:  um:invalid_pointer_read_in_call_avrf_c0000005_igdusc64.dll!usc::setclientcallbacks

FAILURE_ID_HASH:  {d3a24a98-8db8-b62b-d9a8-84b5ce850132}

Followup:     MachineOwner
---------


0:000> !exploitable
Exploitability Classification: EXPLOITABLE
Recommended Bug Title: Exploitable - Read Access Violation on Control Flow starting at igdusc64!USC::SetClientCallbacks+0x360024 (Hash=0x5c4d4910.0x7f7c4345)

Timeline

2018-02-27 - Vendor Disclosure
2018-10-09 - Public Release

Credit

Discovered by Piotr Bania of Cisco Talos.