CVE-2022-34671
A memory corruption vulnerability exists in the Shader Functionality (MOV instruction index) functionality of NVIDIA D3D10 Driver Version 516.94 and 31.0.15.1694. A specially-crafted executable/shader file can lead to memory corruption. An attacker can use arbitrary code execution to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
NVIDIA D3D10 Driver NVIDIA D3D10 Driver, Version 516.94 , 31.0.15.1694
D3D10 Driver - https://nvidia.com
8.5 - CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
CWE-787 - Out-of-bounds Write
NVIDIA Graphics drivers is software for NVIDIA Graphics GPU installed on the PC. It is used to communicate between the operating system and the GPU device. This software is required in most cases for the hardware device to function properly.
A specially crafted compute shader can cause memory corruption vulnerability. An attacker can provide a specially crafted shader file to trigger this vulnerability. This vulnerability potentially could be triggered from guest machines running virtualization environments (ie. VMware, qemu, VirtualBox, etc.) in order to perform guest-to-host escape, as it was demonstrated before (TALOS-2018-0533, TALOS-2018-0568, etc.). Theoretically this vulnerability could be also triggered from web browser (using webGL and webassembly). We were able to trigger this vulnerability from HYPER-V guest using the RemoteFX feature, leading to executing the vulnerable code on the HYPER-V host (inside of the rdvgm.exe process). While the RemoteFX was recently deprecated by Microsoft, some older machines may still use this software.
This vulnerability can be triggered by supplying a malformed compute shader. This leads to memory corruption problem in NVIDIA driver.
Example of compute shader triggering the bug:
00000007: 0x0000035c - 0x00000364 dcl_input vThreadGrouID.xy
00000008: 0x00000364 - 0x0000036c dcl_input vThreadID.xy
00000009: 0x0000036c - 0x00000374 dcl_temps 4
00000010: 0x00000374 - 0x00000384 dcl_indexable_temp x0[32], 4
...
00000039: 0x0000060c - 0x00000628 LEN:0028 mov x1275068416[r0.w].x, l(1.1)
NVIDIA driver takes the movX X value directly from the shader byte code and uses it as an index register (RSI) to the write operation (OR):
00007FFEEDFF423E | 83F8 04 | cmp eax,4 |
00007FFEEDFF4241 | 75 18 | jne nvwgf2umx.7FFEEDFF425B |
00007FFEEDFF4243 | 8379 10 00 | cmp dword ptr ds:[rcx+10],0 |
00007FFEEDFF4247 | 75 12 | jne nvwgf2umx.7FFEEDFF425B |
00007FFEEDFF4249 | 49:8B86 F8050000 | mov rax,qword ptr ds:[r14+5F8] |
00007FFEEDFF4250 | 8B51 14 | mov edx,dword ptr ds:[rcx+14] |
00007FFEEDFF4253 | 0914B0 | or dword ptr ds:[rax+rsi*4],edx | * RSI - taken directly from the shader bytecode, 1275068416
00007FFEEDFF4256 | E9 A5010000 | jmp nvwgf2umx.7FFEEDFF4400 |
In other words, an attacker can control the destination address used by instruction (0x07FFEEDFF4253).
Stack trace:
0:039> kb
# RetAddr : Args to Child : Call Site
00 00007ffe`edff3ac9 : 00000094`59adf108 00000094`59adf0b0 000001d7`663da690 00000000`00000002 : nvwgf2umx!NVDEV_Thunk+0x5ba73
01 00007ffe`edff2806 : 00000000`ef0088a0 00000000`ef008823 00000000`ef008823 00000000`ef00888d : nvwgf2umx!NVDEV_Thunk+0x5b2e9
02 00007ffe`ede06db0 : 000001d7`6636e6c8 00000000`00000000 000001d7`6a4e3100 00000094`59adfb10 : nvwgf2umx!NVDEV_Thunk+0x5a026
03 00007ffe`ede082da : 000001d7`6636e6c8 00000094`593f7000 00007ffe`edda0460 00007fff`7db07955 : nvwgf2umx+0xc6db0
04 00007ffe`ee187905 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nvwgf2umx+0xc82da
05 00007ffe`ee1876b8 : 000001d7`6636ff10 00000000`00000000 000001d7`643fccc0 000001d7`66390a28 : nvwgf2umx!NVDEV_Thunk+0x1ef125
06 00007ffe`ee288724 : 00000000`00000000 00007fff`7db407b0 000001d7`663701a0 000001d7`66390620 : nvwgf2umx!NVDEV_Thunk+0x1eeed8
07 00007ffe`ee28866f : 00000000`00000000 000001d7`0000000f 000001d7`66331480 00000000`00000000 : nvwgf2umx!NVDEV_Thunk+0x2eff44
08 00007ffe`ef01e376 : 000001d7`66331480 00000000`00000000 00000000`00000000 00000000`00000000 : nvwgf2umx!NVDEV_Thunk+0x2efe8f
09 00007fff`7c8e7034 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nvwgf2umx!OpenAdapter12+0x5985c6
0a 00007fff`7db42651 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
0b 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
0:039> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
*** WARNING: Unable to verify checksum for POC_EXEC11.exe
KEY_VALUES_STRING: 1
Key : AV.Fault
Value: Write
Key : Analysis.CPU.mSec
Value: 2171
Key : Analysis.DebugAnalysisManager
Value: Create
Key : Analysis.Elapsed.mSec
Value: 28773
Key : Analysis.Init.CPU.mSec
Value: 1046
Key : Analysis.Init.Elapsed.mSec
Value: 51354
Key : Analysis.Memory.CommitPeak.Mb
Value: 88
Key : Timeline.OS.Boot.DeltaSec
Value: 683754
Key : Timeline.Process.Start.DeltaSec
Value: 39
Key : WER.OS.Branch
Value: vb_release
Key : WER.OS.Timestamp
Value: 2019-12-06T14:06:00Z
Key : WER.OS.Version
Value: 10.0.19041.1
NTGLOBALFLAG: 70
PROCESS_BAM_CURRENT_THROTTLED: 0
PROCESS_BAM_PREVIOUS_THROTTLED: 0
APPLICATION_VERIFIER_FLAGS: 0
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ffeedff4253 (nvwgf2umx!NVDEV_Thunk+0x000000000005ba73)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000001
Parameter[1]: 000001d89a4e2df0
Attempt to write to address 000001d89a4e2df0
FAULTING_THREAD: 00001f5c
PROCESS_NAME: POC_EXEC11.exe
WRITE_ADDRESS: 000001d89a4e2df0
ERROR_CODE: (NTSTATUS) 0xc0000005 - Instrukcja w 0x%p odwo a a si do pami ci pod adresem 0x%p. Pami nie mo e by %s.
EXCEPTION_CODE_STR: c0000005
EXCEPTION_PARAMETER1: 0000000000000001
EXCEPTION_PARAMETER2: 000001d89a4e2df0
STACK_TEXT:
00000094`59adf060 00007ffe`edff3ac9 : 00000094`59adf108 00000094`59adf0b0 000001d7`663da690 00000000`00000002 : nvwgf2umx!NVDEV_Thunk+0x5ba73
00000094`59adf070 00007ffe`edff2806 : 00000000`ef0088a0 00000000`ef008823 00000000`ef008823 00000000`ef00888d : nvwgf2umx!NVDEV_Thunk+0x5b2e9
00000094`59adf520 00007ffe`ede06db0 : 000001d7`6636e6c8 00000000`00000000 000001d7`6a4e3100 00000094`59adfb10 : nvwgf2umx!NVDEV_Thunk+0x5a026
00000094`59adf5d0 00007ffe`ede082da : 000001d7`6636e6c8 00000094`593f7000 00007ffe`edda0460 00007fff`7db07955 : nvwgf2umx+0xc6db0
00000094`59adf6d0 00007ffe`ee187905 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nvwgf2umx+0xc82da
00000094`59adfae0 00007ffe`ee1876b8 : 000001d7`6636ff10 00000000`00000000 000001d7`643fccc0 000001d7`66390a28 : nvwgf2umx!NVDEV_Thunk+0x1ef125
00000094`59adfbd0 00007ffe`ee288724 : 00000000`00000000 00007fff`7db407b0 000001d7`663701a0 000001d7`66390620 : nvwgf2umx!NVDEV_Thunk+0x1eeed8
00000094`59adfc80 00007ffe`ee28866f : 00000000`00000000 000001d7`0000000f 000001d7`66331480 00000000`00000000 : nvwgf2umx!NVDEV_Thunk+0x2eff44
00000094`59adfce0 00007ffe`ef01e376 : 000001d7`66331480 00000000`00000000 00000000`00000000 00000000`00000000 : nvwgf2umx!NVDEV_Thunk+0x2efe8f
00000094`59adfd10 00007fff`7c8e7034 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nvwgf2umx!OpenAdapter12+0x5985c6
00000094`59adfd40 00007fff`7db42651 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
00000094`59adfd70 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
SYMBOL_NAME: nvwgf2umx!NVDEV_Thunk+5ba73
MODULE_NAME: nvwgf2umx
IMAGE_NAME: nvwgf2umx.dll
STACK_COMMAND: ~39s ; .cxr ; kb
FAILURE_BUCKET_ID: INVALID_POINTER_WRITE_c0000005_nvwgf2umx.dll!NVDEV_Thunk
BUCKET_ID_MODPRIVATE: 1
OS_VERSION: 10.0.19041.1
BUILDLAB_STR: vb_release
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
IMAGE_VERSION: 31.0.15.1694
FAILURE_ID_HASH: {845a9326-c135-84e0-eeae-2cab50421828}
Followup: MachineOwner
---------
2022-09-22 - Vendor Disclosure
2022-09-22 - Initial Vendor Contact
2022-12-01 - Vendor Patch Release
2022-12-06 - Public Release
Discovered by Piotr Bania of Cisco Talos.