New issue
Advanced search Search tips
Starred by 1 user
Status: Fixed
Owner:
Closed: Oct 2016
Cc:



Sign in to add a comment
NVIDIA: Escape code leaks uninitialised ExAllocatePoolWithTag memory to userspace.
Project Member Reported by ochang@google.com, Aug 17 2016 Back to list
The handler for the DxgkDdiEscape escape code 0x70000D4 has the following pseudocode:

void __fastcall escape_70000D4(NvMiniportDeviceContext *a1, NvEscapeData *a2)
{
  Escape70000D4 *escape_data_; // rbx@1
  PVOID alloc_buf; // rsi@1
  unsigned int v4; // edi@1
  __int64 user_ptr; // r14@4
  DWORD *v6; // rbx@5
  __int128 v7; // [rsp+40h] [rbp-38h]@1
  __int128 v8; // [rsp+50h] [rbp-28h]@4
  PVOID alloc_buf_; // [rsp+60h] [rbp-18h]@4

  escape_data_ = (Escape70000D4 *)a2;
  a2->unknown_rest[6] = 1;
  LODWORD(v7) = 0;
  memset((char *)&v7 + 4, 0, 0x24ui64);
  alloc_buf = ExAllocatePoolWithTag_(PagedPool, escape_data_->user_ptr_size, 'paVN');
  v4 = 0;
  if ( !alloc_buf )
    v4 = 0xFFFF;
  if ( v4 )
    goto LABEL_12;
  HIDWORD(v8) = escape_data_->user_ptr_size;
  alloc_buf_ = alloc_buf;
  v4 = sub_625BC(0i64, dword_B1BB94, escape_data_->unknown_0, 0x83F30101, (__int64)&v7, 40);
  user_ptr = escape_data_->user_ptr;
  ProbeForWrite((PVOID)escape_data_->user_ptr, escape_data_->user_ptr_size, UserMode);
  memcpy((void *)escape_data_->user_ptr, alloc_buf, escape_data_->user_ptr_size);
  *(_OWORD *)&escape_data_->unknown_2 = v7;
  *(_OWORD *)&escape_data_->unknown_4 = v8;
  escape_data_->user_ptr = user_ptr;
  if ( v4 )
  {
LABEL_12:
    v6 = &escape_data_->header.unknown_rest[6];
    if ( v6 )
    {
      if ( v4 <= 0xFFFFF000 )
        *v6 = -4096 - v4;
    }
  }
  if ( alloc_buf )
    ExFreePoolWithTag_(alloc_buf, 0x7061564Eu);
}

ExAllocatePoolWithTag is called with a user provided size to allocate a buffer, but the subsequent copying of said buffer to the user provided pointer doesn't make sense since the buffer is never initialised with any values. This means that a user mode program can leak uninitialised memory from arbitrarily-sized pool allocations.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

 
poc.zip
2.6 KB Download
Project Member Comment 1 by ochang@google.com, Aug 18 2016
Looks like I made an oversimplified analysis of the pseudocode in the report. The allocated buffer pointer is indeed passed off to the sub_625BC function (as part of a struct member on the stack) which eventually passes it to a bunch of other functions.

However, this doesn't change the fact that with the provided PoC, the pool allocated buffer still isn't being initialised and is copied into the user buffer unchanged.
Project Member Comment 2 by ochang@google.com, Sep 29 2016
Labels: CVE-2016-7386
Project Member Comment 3 by ochang@google.com, Oct 28 2016
Labels: -Restrict-View-Commit
Status: Fixed
Fixed. Bulletin: http://nvidia.custhelp.com/app/answers/detail/a_id/4247
Sign in to add a comment