# clfs.sys Patch Diff — CVE-2026-40397

| | |
|---|---|
| Binary | clfs.sys (Windows Common Log File System Driver) |
| Pre-patch version | 10.0.28000.1896 |
| Post-patch version | 10.0.28000.2113 |
| KB | KB5089549 |
| CVE | CVE-2026-40397 — Integer underflow (wrap/wraparound), Elevation of Privilege |
| Diff tool | ghidriff (Ghidra VersionTrackingDiff engine) |
| Functions changed | 1 (code change, refactor) |
| Functions added | 1 |

## Attribution note

This diff job (`clfs-2026-04.sys` vs `clfs-2026-05.sys`) covers the same May
2026 CLFS patch as CVE-2026-40407 (CWE-122, heap-based buffer overflow). Two
new feature flags appear in the post-patch binary, each gating a different
kind of added validation. The function below contains the flag whose check
matches CVE-40397's CWE (an alignment check guarding a subtraction, i.e.
underflow-shaped); the other flag, in `ReadLogBlock`, is covered on
CVE-2026-40407's page instead. **This attribution is inferred from the
semantics of each check, not confirmed against Microsoft's internal change
records** — treat it as well-reasoned static analysis, not ground truth.

## Summary

CVE-2026-40397 is an integer-underflow fix in the log-reservation
accounting path. In the pre-patch binary, the reservation-pointer
arithmetic lived inline inside `UnmarkLogFileContainers`. In the post-patch
binary, that arithmetic has been extracted into a new function,
`CClfsLogFcbPhysical::AdjustReservation`, and a new staged-rollout flag,
`Feature_1201914170`, gates an added alignment check at the very top of it:
if the caller-supplied offset isn't sector-aligned (`offset & 0x1ff != 0`),
the function now bails out immediately instead of proceeding into the
reservation-size subtraction below. That subtraction (`uVar5 - (_Var6 -
_Var7)`, unsigned) has no other underflow guard — an unaligned/crafted
offset could previously drive it negative, wrapping to a huge unsigned
value used as the new reservation size. Because the fix is feature-flagged,
it is currently inert wherever Microsoft hasn't yet flipped
`Feature_1201914170` on for that cohort.

## Functions added

### CClfsLogFcbPhysical::AdjustReservation

| | |
|---|---|
| Address | 14007feb0 |
| Patch flag added | **Yes** — `Feature_1201914170__private_IsEnabledDeviceUsageNoInline` |

This function didn't exist in the pre-patch binary as a standalone symbol —
its logic is the reservation-pointer math that used to run inline inside
`UnmarkLogFileContainers` (see below). The new alignment check sits before
any of that arithmetic runs:

```c
  iVar9 = 0;
  bVar3 = false;
//  >>> patch flag check added here <<<
  uVar5 = Feature_1201914170__private_IsEnabledDeviceUsageNoInline();
  if (((int)uVar5 != 0) && ((*param_2 & 0x1ff) != 0)) {
    return -0x3ffffff3;
  }
  cVar4 = ExAcquireResourceExclusiveLite(this + 200,1);
  _Var2 = *(__uint64 *)(this + 0x1d8);
  uVar5 = *(ulonglong *)(this + 0x1d0);
  _Var8 = *param_2;
  if ((longlong)_Var8 < 0) {
    _Var8 = _Var2 + _Var8;
    if ((longlong)_Var8 < 0) {
      iVar10 = -0x3ffffff3;
      goto LAB_140080095;
    }
    _Var6 = RawSectorAlign(this,_Var8);
    _Var7 = RawSectorAlign(this,_Var2);
    *(__uint64 *)(this + 0x1d8) = _Var8;
//  >>> unguarded subtraction the alignment check above protects <<<
    uVar11 = uVar5 - (_Var6 - _Var7);
    *(ulonglong *)(this + 0x1d0) = uVar11;
  }
```

`0x1ff` is 511 — the check requires the offset to be a multiple of 512
bytes (sector-aligned) before `RawSectorAlign` and the subtraction run.
Without it, an unaligned offset can make `_Var6 < _Var7`, underflowing
`(_Var6 - _Var7)` as unsigned and then underflowing `uVar5 - (...)` again,
producing a huge reservation size from a small/negative input.

### CClfsLogFcbPhysical::UnmarkLogFileContainers (context, no flag)

| | |
|---|---|
| Address | 14006ebc0 -> 14007bcb0 |
| Change type | code, length, calling, called |
| Patch flag added | No |

This function lost its inline reservation arithmetic entirely — it's been
reduced to a refcount decrement that, on reaching zero, calls
`CClfsBaseFilePersisted::UnmarkContainerQ`. It's included here for context
(it's where the vulnerable arithmetic used to live) but carries no flag
check itself, so it isn't the fix site.

---

<sub>Source: ghidriff diff of clfs-2026-04.sys (10.0.28000.1896, pre-patch) vs clfs-2026-05.sys (10.0.28000.2113, post-patch) — [download pre](/data/patch_diffs/binaries/clfs-2026-04.sys) / [download post](/data/patch_diffs/binaries/clfs-2026-05.sys). This report covers only the function(s) attributed to CVE-2026-40397; the same diff job also covers CVE-2026-40407 (see that CVE's own report). Raw ghidriff output (full metadata, decompiler options, mermaid charts) is preserved in diffing/2026-05/clfs-kb5089549/json/clfs-2026-04.sys-clfs-2026-05.sys.ghidriff.json.</sub>
