NVIDIA Driver - Unchecked Write to User-Provided Pointer in Escape 0x700010d







Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=894

The DxgkDdiEscape handler for 0x700010d accepts a user provided pointer as the
destination for a memcpy call, without doing any checks on said pointer.

void __fastcall escape_700010D(NvMiniportDeviceContext* ctx, NvEscapeData *escape)
    v8 = escape->unknown_2;
    if ( v8 == 1 )
      data.size = escape->size;
      data.buf = ExAllocatePoolWithTag((POOL_TYPE)512, 0xC08i64 * data.size, 0x7061564Eu);
      v9 = Escape7Handler(0i64, dword_7DCB84, dword_7DCB84, 626, &data, 0x190);
    else if ( escape->unknown_2 == 1 )
      memcpy(escape->user_ptr, data.buf, 3080i64 * escape->size);

(Win 10 x64 372.54) crashing context with PoC (in memcpy) on a write to 0x4141414141414141:

CONTEXT:  ffffd0002d2ab5c0 -- (.cxr 0xffffd0002d2ab5c0)
rax=0000000000000001 rbx=ffffc0016c9b9b40 rcx=000000000000000f
rdx=bebe9ebf4b4e0ecf rsi=0000000000000001 rdi=000000007061564e
rip=fffff8005488ab00 rsp=ffffd0002d2abfe8 rbp=ffffd0002d2ac0f0
 r8=0000000000000bf9  r9=ffffd00024014ac0 r10=0000000000000000
r11=4141414141414141 r12=0000000000000340 r13=fffff800542b0000
r14=ffffe0008fb2d000 r15=0000000000000001
iopl=0         nv up ei pl nz ac po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010216
fffff800`5488ab00 f3410f7f03      movdqu  xmmword ptr [r11],xmm0 ds:002b:41414141`41414141=????????????????????????????????

To reproduce, compile the PoC as a x64 binary (requires linking with
setupapi.lib, and WDK for D3DKMTEscape), and run. It may require some changes
as for it to work as the escape data must contain the right values (e.g. a
field that appears to be gpu bus device function). My PoC should hopefully set
all the right values for the machine it's running on.

Proof of Concept: