Bug 2536407 (CVE-2026-90096)

Summary: CVE-2026-90096 kernel: fuse: invalidate the correct range after O_APPEND direct write
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: akhatavk, aos-team-art-private, asdas, dpaolell, jdelft, jupierce, lgarciaa, mbiarnes, ppalepu, ppostler, prdhamdh, rhel-process-autobot, sghai, sidsharm, suppawar, vlaad, watson-tool-maintainers
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in the Linux kernel's FUSE (Filesystem in Userspace) component. When performing direct writes with the O_APPEND flag, the `fuse_direct_write_iter()` function incorrectly invalidates the page cache. This can lead to data inconsistency, where concurrent readers may access stale data from the page cache instead of the most recent information written to the file.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2026-09-17 17:44:53 UTC
In the Linux kernel, the following vulnerability has been resolved:

fuse: invalidate the correct range after O_APPEND direct write

fuse_direct_write_iter() captures pos before generic_write_checks(),
which moves ki_pos to EOF for O_APPEND writes:

  fuse_direct_write_iter()
  {
      pos = iocb->ki_pos;           /* 0 (user-supplied)       */
      generic_write_checks();       /* ki_pos -> EOF           */
      fuse_direct_io();             /* writes at EOF, correct  */
      invalidate(pos, pos + res);   /* [0, res) -- wrong       */
  }

The post-write invalidation targets a stale range instead of the
actual written range at EOF.

This can cause data inconsistency when the file size is not
page-aligned.  The tail page straddling EOF has a valid portion
before EOF that concurrent readers can fault back in during the
DIO write window:

  Tail page (file size X not page-aligned):

    page_start         X (EOF)   page_end
    |--- valid data ----|-- stale --|

  CPU0 (O_APPEND DIO writer)    CPU1 (buffered reader)
  --------------------------    ----------------------
  invalidate [X, X+len)
    tail page evicted
  FUSE_WRITE in flight ...
                                read [page_start, X)
                                  tail page re-faulted
                                  [X, page_end) = stale
  FUSE_WRITE completes
  i_size = X + len
  invalidate [0, len)  <- WRONG
    tail page still cached
                                read [X, X+len)
                                  hits stale tail page
                                  returns old data

Fix by reading pos back from iocb->ki_pos after generic_write_checks(),
as generic_file_direct_write() does.

Also fix a typo in the comment ("may have" -> "may have competed").