# CVE-2026-44809 — Windows CLFS `clfs.sys` Use-After-Free in FlushLog Cleanup Path

---

## Summary

| **Product**           | Microsoft Windows — `clfs.sys` (Common Log File System kernel driver) |
|-----------------------|-----------------------------------------------------------------------|
| **Vendor**            | Microsoft Corporation |
| **Severity**          | High |
| **Affected Versions** | Windows 10 (all versions); Windows 11 (21H2–24H2); Windows Server 2016–2025 |
| **Impact**            | Elevation of Privilege — Local user to SYSTEM |
| **CVE ID**            | CVE-2026-44809 |
| **CWE**               | CWE-416: Use After Free |
| **Patch Available**   | Yes |
| **Patch Date**        | June 2026 — KB5094126 |

---

## CVSS 4.0 Detailed Scoring

**Base Score:** 8.5 (HIGH)
**Vector String:** `CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H`

| **Metric** | **Value** | **Rationale** |
|---|---|---|
| **Attack Vector (AV)** | Local | Requires local authenticated session |
| **Attack Complexity (AC)** | Low | Race window is deterministic; BLF format is documented |
| **Attack Requirements (AT)** | None | CLFS is always present in all Windows installations |
| **Privileges Required (PR)** | Low | Standard user account; no administrative rights required |
| **User Interaction (UI)** | None | No interaction from any other user required |
| **Vulnerable System Confidentiality (VC)** | High | UAF enables arbitrary kernel R/W via dangling pointer |
| **Vulnerable System Integrity (VI)** | High | Reclaimed pointer enables controlled kernel writes |
| **Vulnerable System Availability (VA)** | High | Kernel pool corruption causes BSOD |
| **Subsequent System Confidentiality (SC)** | High | SYSTEM access enables credential harvesting |
| **Subsequent System Integrity (SI)** | High | SYSTEM access enables persistence |
| **Subsequent System Availability (SA)** | High | Full system compromise |

---

## Product Description

`clfs.sys` is the kernel driver implementing the Common Log File System (CLFS). The `FlushLog` function is the kernel-mode implementation of the `FlushLogBuffers` API — it flushes dirty log buffers to disk, managing reference counts and cleanup via `ReleaseFlushRef` and `CompleteFlush`. The function maintains a back-pointer at `this + 0x548` that references a local stack variable (`local_58`) used during the flush operation. This pointer is also accessed from the compiler-generated exception handler (`fin$0`).

---

## Vulnerability Summary

`CClfsLogFcbPhysical::FlushLog` stores a pointer to a local stack variable at `this + 0x548` during flush operations. When the function completes (either normally or via exception), it calls `ReleaseFlushRef` to decrement the flush reference count — but does NOT null out the `this + 0x548` pointer first. After `ReleaseFlushRef`, if the refcount reaches zero, `CompleteFlush` is called. The stack frame holding the pointed-to variable goes out of scope, but the pointer at `this + 0x548` still references the now-invalid stack memory. A concurrent access to `this + 0x548` (from another thread or a subsequent operation) dereferences freed/reused stack memory — a classic use-after-free.

The vulnerability exists in both the normal exit path (`FlushLog` itself) and the exception handling path (`fin$0`), making it exploitable regardless of whether the flush succeeds or throws.

---

## Prerequisites and Constraints

- Local authenticated session (standard user; no administrative rights required)
- CLFS is always present — it is a core Windows kernel component
- BLF files can be created in any user-writable directory via `CreateLogFile` API
- Multi-threaded access to the same log is required to hit the race window
- No special hardware, kernel driver, or pre-existing SYSTEM token required
- Stack reuse is deterministic on Windows kernel stacks

---

## Vulnerability Details

### Vulnerable Code Path

```
User mode:
  Thread 1:
    CreateLogFile()        → opens BLF
    FlushLogBuffers()      → calls FlushLog in kernel
  Thread 2:
    [concurrent operation] → accesses this + 0x548 after Thread 1's stack unwinds

Kernel mode:
  CClfsLogFcbPhysical::FlushLog()
    → stores &local_58 at this + 0x548
    → [flush operations]
    → ReleaseFlushRef()     // decrements refcount
    → [stack frame goes out of scope]
    → this + 0x548 still points to dead stack  *** USE-AFTER-FREE ***

  Exception path:
  FlushLog::fin$0()
    → ReleaseFlushRef()     // same problem on exception path
    → [stack frame goes out of scope]
    → this + 0x548 still points to dead stack  *** USE-AFTER-FREE ***
```

### The Dangling Pointer

In the pre-patch binary, `FlushLog` at address `0x14000ef80`:

1. Stores `&local_58` (a stack variable address) at `this + 0x548`
2. Performs flush operations using `local_58`
3. Calls `ReleaseFlushRef(this)` which decrements the refcount
4. If refcount reaches 0, calls `CompleteFlush(this)`
5. Returns — stack frame goes out of scope, `local_58` is now dead memory
6. But `this + 0x548` still holds the address of the dead `local_58`

Any subsequent code that reads `*(this + 0x548)` dereferences freed stack memory. An attacker who controls what gets placed on the stack after `FlushLog` returns can redirect the dangling pointer to controlled data.

### The Fix (KB5094126, June 2026)

The patch adds a `Feature_3035089211`-gated check in both exit paths. Before calling `ReleaseFlushRef`, the patched code nulls out `this + 0x548`:

**Normal exit path (`FlushLog`):**
```c
if (bVar5) {
    uVar16 = Feature_3035089211__private_IsEnabledDeviceUsageNoInline();
    if ((((int)uVar16 != 0) && (bVar4)) &&
        (*(undefined8 **)(this + 0x548) == &local_58)) {
        *(undefined8 *)(this + 0x548) = 0;   // NULL out dangling pointer
    }
    LOCK();
    pCVar1 = this + 0x51c;
    iVar12 = *(int *)pCVar1;
    *(int *)pCVar1 = *(int *)pCVar1 + -1;    // ReleaseFlushRef
    UNLOCK();
    if (iVar12 == 1) {
        CompleteFlush(this);
    }
}
```

**Exception path (`fin$0`):**
```c
if (*(char *)(param_2 + 0x32) != '\0') {
    uVar1 = Feature_3035089211__private_IsEnabledDeviceUsageNoInline();
    if ((((int)uVar1 != 0) && (*(char *)(param_2 + 0x31) != '\0')) &&
       (*(longlong *)(this + 0x548) == param_2 + 0x50)) {
        *(undefined8 *)(this + 0x548) = 0;   // NULL out dangling pointer
    }
    CClfsLogFcbPhysical::ReleaseFlushRef(this);
    *(undefined1 *)(param_2 + 0x32) = 0;
}
```

The check `*(this + 0x548) == &local_58` confirms the pointer still references the current stack frame before nulling it — preventing false positives where `this + 0x548` has been legitimately updated by another operation.

### Added Functions

Two functions were added to support the feature flag:

| Function | Address | Role |
|---|---|---|
| `Feature_3035089211__private_IsEnabledDeviceUsageNoInline` | `0x1400169e0` | Evaluates the `Feature_3035089211` flag; falls back on cache miss |
| `Feature_3035089211__private_IsEnabledFallback` | `0x140016a1c` | Thin wrapper calling `wil_details_IsEnabledFallback` |

---

## Affected Binary Versions

| **Binary** | **Version** | **Status** |
|---|---|---|
| clfs.sys | ≤ 10.0.28000.2179 (pre-June 2026) | Vulnerable |
| clfs.sys | 10.0.28000.2269 (June 2026, KB5094126) | Fixed, feature-flagged |

---

## Detection Guidance

### YARA Rules

#### Rule 1 — Exploit Binary (memory/disk scan)

```yara
rule CVE_2026_44809_CLFS_UAF_FlushLog_Exploit {
    meta:
        description = "Detects exploit binaries targeting CVE-2026-44809 CLFS FlushLog use-after-free"
        cve         = "CVE-2026-44809"
        severity    = "CRITICAL"
        author      = "OnlyFm252 / STAR Labs SG"
        date        = "2026-07-22"
        filetype    = "PE"

    strings:
        /* CLFS Win32 APIs */
        $api_create  = "CreateLogFile" ascii wide
        $api_add     = "AddLogContainer" ascii wide
        $api_flush   = "FlushLogBuffers" ascii wide
        $api_reserve = "ReserveAndAppendLog" ascii wide

        /* Multi-threaded exploitation */
        $thread_1    = "CreateThread" ascii wide
        $thread_2    = "WaitForSingleObject" ascii wide
        $thread_3    = "WaitForMultipleObjects" ascii wide

        /* BLF file */
        $blf_ext     = ".blf" ascii wide nocase
        $log_prefix  = "LOG:" ascii wide

        /* Stack spray / race indicators */
        $race_1      = "SetEvent" ascii wide
        $race_2      = "ResetEvent" ascii wide

    condition:
        uint16(0) == 0x5A4D
        and $api_create
        and $api_flush
        and $blf_ext
        and 1 of ($thread_*)
        and 1 of ($race_*)
}
```

#### Rule 2 — Multi-threaded CLFS Flush Pattern

```yara
rule CVE_2026_44809_CLFS_Concurrent_Flush {
    meta:
        description = "Detects binaries performing concurrent CLFS flush operations (UAF race trigger)"
        cve         = "CVE-2026-44809"
        severity    = "HIGH"
        author      = "OnlyFm252 / STAR Labs SG"
        date        = "2026-07-22"
        filetype    = "PE"

    strings:
        $api_create  = "CreateLogFile" ascii wide
        $api_flush   = "FlushLogBuffers" ascii wide
        $thread      = "CreateThread" ascii wide
        $blf         = ".blf" ascii wide nocase

        /* Rapid flush loop pattern */
        $loop_flush  = { 8B ?? FF 15 }   /* call [FlushLogBuffers] in a loop */

    condition:
        uint16(0) == 0x5A4D
        and all of ($api_*, $thread, $blf)
}
```

### Sigma Rules

#### Rule 1 — Concurrent CLFS Access

```yaml
title: Concurrent CLFS Log Flush from Non-System Process (CVE-2026-44809)
id: e7f1a5b4-8c9d-4e0f-f1a2-3b4c5d6e7f8a
status: experimental
description: |
    Detects non-system processes that load clfsw32.dll and create multiple
    threads — a pattern consistent with the CVE-2026-44809 race condition
    exploit that requires concurrent FlushLog calls.
references:
    - https://onlyfm252.starlabs.sg/cve/CVE-2026-44809/
author: OnlyFm252 / STAR Labs SG
date: 2026-07-22
tags:
    - attack.privilege_escalation
    - attack.t1068
    - cve.2026.44809
logsource:
    product: windows
    category: image_load
detection:
    selection_dll:
        ImageLoaded|endswith: '\clfsw32.dll'
    filter_system:
        Image|endswith:
            - '\svchost.exe'
            - '\lsass.exe'
            - '\services.exe'
            - '\wininit.exe'
            - '\System'
            - '\smss.exe'
    condition: selection_dll and not filter_system
level: medium
falsepositives:
    - Legitimate applications using CLFS for transactional logging
```

#### Rule 2 — BLF File Creation with Rapid Flush

```yaml
title: Rapid CLFS BLF Operations in User Directory (CVE-2026-44809)
id: f8a2b6c5-9d0e-4f1a-a2b3-4c5d6e7f8a9b
status: experimental
description: |
    Detects creation of BLF files in user-writable directories followed by
    rapid access patterns, consistent with the create-flush-race pattern
    used to exploit CVE-2026-44809.
references:
    - https://onlyfm252.starlabs.sg/cve/CVE-2026-44809/
author: OnlyFm252 / STAR Labs SG
date: 2026-07-22
tags:
    - attack.privilege_escalation
    - attack.t1068
    - cve.2026.44809
logsource:
    product: windows
    category: file_event
detection:
    selection:
        TargetFilename|endswith: '.blf'
        TargetFilename|contains:
            - '\Users\'
            - '\Temp\'
            - '\Public\'
            - '\AppData\'
    filter_legitimate:
        Image|endswith:
            - '\svchost.exe'
            - '\lsass.exe'
    condition: selection and not filter_legitimate
level: high
falsepositives:
    - Custom applications using CLFS for logging in user directories
```

### Sysmon Rules

```xml
<Sysmon schemaversion="4.90">
  <EventFiltering>

    <!-- Event ID 11: BLF file creation in user-writable directories -->
    <FileCreate onmatch="include">
      <Rule name="CVE-2026-44809: BLF file creation" groupRelation="and">
        <TargetFilename condition="end with">.blf</TargetFilename>
        <TargetFilename condition="contains any">\Users\;\Temp\;\Public\;\AppData\</TargetFilename>
      </Rule>
    </FileCreate>

    <!-- Event ID 7: clfsw32.dll loaded by non-system process -->
    <ImageLoad onmatch="include">
      <Rule name="CVE-2026-44809: CLFS DLL load" groupRelation="and">
        <ImageLoaded condition="end with">clfsw32.dll</ImageLoaded>
        <Image condition="excludes">svchost.exe</Image>
        <Image condition="excludes">lsass.exe</Image>
        <Image condition="excludes">services.exe</Image>
        <Image condition="excludes">wininit.exe</Image>
      </Rule>
    </ImageLoad>

    <!-- Event ID 8: CreateRemoteThread — race condition setup -->
    <CreateRemoteThread onmatch="include">
      <Rule name="CVE-2026-44809: Thread creation for race">
        <SourceImage condition="excludes">svchost.exe</SourceImage>
      </Rule>
    </CreateRemoteThread>

    <!-- Event ID 23: BLF file deletion (cleanup after exploitation) -->
    <FileDelete onmatch="include">
      <Rule name="CVE-2026-44809: BLF file cleanup" groupRelation="and">
        <TargetFilename condition="end with">.blf</TargetFilename>
        <TargetFilename condition="contains any">\Users\;\Temp\;\Public\</TargetFilename>
      </Rule>
    </FileDelete>

  </EventFiltering>
</Sysmon>
```

---

## Remediation

1. **Apply KB5094126 (June 2026) immediately** — this is the only patch for CVE-2026-44809.
2. **Verify feature flag activation:** The fix is gated by `Feature_3035089211`. Check flag status via `reg query "HKLM\SYSTEM\CurrentControlSet\Control\FeatureManagement\Overrides"`.
3. **Deploy detection rules:** Use the YARA, Sigma, and Sysmon rules above.
4. **Monitor for multi-threaded CLFS usage:** Legitimate applications rarely perform concurrent flush operations from user directories.
5. **Enable Driver Verifier for clfs.sys** on high-value targets to catch UAF accesses early.

---

## References

- Diff report: [clfs.sys KB5094126 diff (June 2026)](/data/patch_diffs/clfs_sys-kb5094126.md)
- Pre-patch binary: [clfs-2026-05.sys](/data/patch_diffs/binaries/clfs-2026-05.sys) (10.0.28000.2179)
- Post-patch binary: [clfs-2026-06.sys](/data/patch_diffs/binaries/clfs-2026-06.sys) (10.0.28000.2269)
- Related: [CVE-2026-40397](/cve/CVE-2026-40397/) (integer underflow, May 2026 patch)
- Related: [CVE-2026-40407](/cve/CVE-2026-40407/) (heap overflow, May 2026 patch)

<sub>Analysis by OnlyFm252 / STAR Labs SG. Diff source: ghidriff (Ghidra 12.0.4, VersionTrackingDiff engine).</sub>
