CVE-2025-29824 — CLFS CClfsLogCcb Use-After-Free (IRP Race)

Last updated: 2026-04-10
Component: clfs.sys
Bug Class: Use-After-Free — CClfsLogCcb freed during IRP_MJ_CLEANUP while IOCTL still in flight
Patch: April 8, 2025 Patch Tuesday
Exploited ITW: Yes — Storm-2460 (RansomEXX), targeted Saudi Arabia, Spain, Venezuela, USA
Discoverer: Microsoft Threat Intelligence (during Storm-2460 investigation)
Related: Clfs, Use After Free, Race Conditions
Tags: clfs, uaf, irp-race, lookaside, ioctl, kernel-mode, lpe, ransomware


Summary

CVE-2025-29824 is a use-after-free in clfs.sys. When a CLFS file descriptor is closed, Windows sends two I/O requests to the driver: IRP_MJ_CLEANUP followed by IRP_MJ_CLOSE. The bug: CClfsLogCcb::Release (which may free the CClfsLogCcb object) was called during IRP_MJ_CLEANUP rather than IRP_MJ_CLOSE. This means:

  1. IRP_MJ_CLEANUP frees CClfsLogCcb
  2. An IOCTL that uses FsContext2 (which points to CClfsLogCcb) can be issued from user space between CLEANUP and CLOSE, operating on freed memory

Patch: Move CClfsLogCcb::Release call from CClfsLogCcb::Cleanup to CClfsRequest::Close — so the object is not freed until CLOSE completes.


CClfsLogCcb Structure

CClfsLogCcb is the per-file-descriptor context block stored in FileObject->FsContext2. Size: 0x110 bytes.

Offset  Field            Type        Notes
+0x00   vtable           PTR64       CClfsLogCcb vtable
+0x08   ...              ...
+0x18   reference_count  LONG        Decremented by CClfsLogCcb::Release
+0x20   ...
+0x98   m_Resource       ERESOURCE   (0x68 bytes) — executive resource for sync
+0x100  ...

The reference count starts at 1 when CClfsLogCcb is created. CClfsLogCcb::Release decrements it; when it hits 0, the destructor runs and the pool allocation is freed.


IRP Sequence and Race Window

Normal sequence:
  User: CloseHandle(log_file)
    → Kernel: IRP_MJ_CLEANUP (CClfsRequest::Cleanup → CClfsLogCcb::Cleanup)
    →         IRP_MJ_CLOSE   (CClfsRequest::Close)

Buggy behavior (pre-patch):
  IRP_MJ_CLEANUP:
    CClfsLogCcb::Cleanup called
    → CClfsLogCcb::Release() ← decrements refcount → if 0, FREES CClfsLogCcb
    ← returns

  *** RACE WINDOW: user can issue IOCTL here ***
  *** FsContext2 still points to freed CClfsLogCcb ***

  IRP_MJ_CLOSE:
    CClfsRequest::Close called
    (object already freed — but CLOSE code may use FsContext2 again)

Key fact: During IRP_MJ_CLEANUP, operations can still be initiated from user space. This is the standard Windows IRP model — IRP_MJ_CLEANUP signals intent to close, but descriptor is not yet invalid.


LookasideList Exploitation Requirement

CClfsLogCcb is freed via LookasideList (kernel lookaside list with depth 24). This means:

  • Objects freed into a LookasideList with < 24 entries are not returned to the pool — they remain in the list
  • An attacker must fill the LookasideList before the freed object can actually be reallocated
  • Required approach:
    1. Create ≥ 25 file descriptors for the same log file
    2. Close 24 of them → fills LookasideList (objects stay in list, not freed to pool)
    3. The 25th closure causes the freed CClfsLogCcb to actually return to the pool → becomes available for reallocation
    4. Race: between step 3’s CLEANUP and CLOSE, spray a same-size object to reclaim the pool slot
    5. Issue IOCTL to get clfs.sys to use the reclaimed CClfsLogCcb as if it were valid

Vulnerable IOCTLs

The following IOCTLs operate on CClfsLogCcb (from FsContext2) after it may be freed:

IOCTL CodeFunctionNotes
0x8007A827CClfsRequest::StartArchivalPrimary exploitation vector (uses CClfsLogCcb for archive context)
0x8007281FArchive-related IOCTLSecondary vector
0x80076856Log state queryReads from CClfsLogCcb.m_Resource (ERESOURCE at +0x98)

CClfsRequest::StartArchival is documented in the bi.zone deep-dive as the key IOCTL to weaponize:

__int64 CClfsRequest::StartArchival(CClfsRequest *this, PIRP Irp) {
    CClfsLogCcb *pCcb = (CClfsLogCcb *)this->m_pFileObject->FsContext2;
    // pCcb may be freed if CLEANUP raced ahead
    pCcb->m_Resource.AcquireExclusive();  // UAF: corrupt ERESOURCE
    ...
}

Exploitation Strategy

After UAF trigger, CClfsLogCcb (0x110 bytes) is freed and can be reclaimed by a controlled allocation. Key targets:

  1. Same-size pool object reclaim: Spray 0x110-byte pool objects with controlled content → CClfsLogCcb.vtable becomes controllable → next virtual call = arbitrary dispatch

  2. ERESOURCE corruption (at +0x98): ERESOURCE contains linked lists; corrupt list pointers → arbitrary write on ExReleaseResourceForThreadLite unlink

  3. Reference count manipulation: Craft fake CClfsLogCcb with reference_count = 0 to cause immediate re-free → double-free chaining

Post-UAF primitive: Identical to other CLFS exploits — pipe attribute AAR/AAW or PreviousMode (Win10):

  • Win10: Corrupt KTHREAD.PreviousMode → arbitrary R/W → token steal
  • Win11: Pipe attribute AAR/AAW → read SYSTEM token → replace current process token

Attack Chain (Storm-2460 / RansomEXX)

1. dllhost.exe loads PipeMagic backdoor
2. CVE-2025-29824 exploit executed from dllhost.exe address space
3. Creates C:\ProgramData\SkyPdf\PDUDrv.blf (CLFS exploit artifact)
4. NtQuerySystemInformation for kernel address leaks
5. RtlSetAllBits via EPROCESS traversal → all privileges enabled
6. Code injection: winlogon.exe → procdump.exe → dllhost.exe
7. Procdump: dump lsass.exe → credential theft
8. RansomEXX: encrypt files via dllhost.exe --do [ransomware path]

Indicators of Compromise

  • BLF file: C:\ProgramData\SkyPdf\PDUDrv.blf
  • Process: dllhost.exe executing procdump.exe -ma lsass.exe
  • Privilege escalation technique: RtlSetAllBits on token privileges

Detection

  • EDR: Watch for clfs.sys IOCTL calls from processes issuing IRP_MJ_CLEANUP + IOCTL in rapid succession
  • File system: C:\ProgramData\SkyPdf\PDUDrv.blf creation
  • Behavior: dllhost.exe spawning procdump.exe with -ma lsass.exe arguments

References

  • bi.zone — “Deep dive into CVE-2025-29824 in Windows” — 2025-08-18
  • StarLabs / Ong How Chong — “My Blind Date with CVE-2025-29824” (CClfsLogCcb structure layout, PoC crash trace)
  • Kaspersky — PipeMagic backdoor analysis (backdoor delivery vehicle)
  • Microsoft MSRC — CVE-2025-29824 advisory — April 2025