CVE-2025-71201
Publication date:
14/02/2026
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
netfs: Fix early read unlock of page with EOF in middle<br />
<br />
The read result collection for buffered reads seems to run ahead of the<br />
completion of subrequests under some circumstances, as can be seen in the<br />
following log snippet:<br />
<br />
9p_client_res: client 18446612686390831168 response P9_TREAD tag 0 err 0<br />
...<br />
netfs_sreq: R=00001b55[1] DOWN TERM f=192 s=0 5fb2/5fb2 s=5 e=0<br />
...<br />
netfs_collect_folio: R=00001b55 ix=00004 r=4000-5000 t=4000/5fb2<br />
netfs_folio: i=157f3 ix=00004-00004 read-done<br />
netfs_folio: i=157f3 ix=00004-00004 read-unlock<br />
netfs_collect_folio: R=00001b55 ix=00005 r=5000-5fb2 t=5000/5fb2<br />
netfs_folio: i=157f3 ix=00005-00005 read-done<br />
netfs_folio: i=157f3 ix=00005-00005 read-unlock<br />
...<br />
netfs_collect_stream: R=00001b55[0:] cto=5fb2 frn=ffffffff<br />
netfs_collect_state: R=00001b55 col=5fb2 cln=6000 n=c<br />
netfs_collect_stream: R=00001b55[0:] cto=5fb2 frn=ffffffff<br />
netfs_collect_state: R=00001b55 col=5fb2 cln=6000 n=8<br />
...<br />
netfs_sreq: R=00001b55[2] ZERO SUBMT f=000 s=5fb2 0/4e s=0 e=0<br />
netfs_sreq: R=00001b55[2] ZERO TERM f=102 s=5fb2 4e/4e s=5 e=0<br />
<br />
The &#39;cto=5fb2&#39; indicates the collected file pos we&#39;ve collected results to<br />
so far - but we still have 0x4e more bytes to go - so we shouldn&#39;t have<br />
collected folio ix=00005 yet. The &#39;ZERO&#39; subreq that clears the tail<br />
happens after we unlock the folio, allowing the application to see the<br />
uncleared tail through mmap.<br />
<br />
The problem is that netfs_read_unlock_folios() will unlock a folio in which<br />
the amount of read results collected hits EOF position - but the ZERO<br />
subreq lies beyond that and so happens after.<br />
<br />
Fix this by changing the end check to always be the end of the folio and<br />
never the end of the file.<br />
<br />
In the future, I should look at clearing to the end of the folio here rather<br />
than adding a ZERO subreq to do this. On the other hand, the ZERO subreq can<br />
run in parallel with an async READ subreq. Further, the ZERO subreq may still<br />
be necessary to, say, handle extents in a ceph file that don&#39;t have any<br />
backing store and are thus implicitly all zeros.<br />
<br />
This can be reproduced by creating a file, the size of which doesn&#39;t align<br />
to a page boundary, e.g. 24998 (0x5fb2) bytes and then doing something<br />
like:<br />
<br />
xfs_io -c "mmap -r 0 0x6000" -c "madvise -d 0 0x6000" \<br />
-c "mread -v 0 0x6000" /xfstest.test/x<br />
<br />
The last 0x4e bytes should all be 00, but if the tail hasn&#39;t been cleared<br />
yet, you may see rubbish there. This can be reproduced with kafs by<br />
modifying the kernel to disable the call to netfs_read_subreq_progress()<br />
and to stop afs_issue_read() from doing the async call for NETFS_READAHEAD.<br />
Reproduction can be made easier by inserting an mdelay(100) in<br />
netfs_issue_read() for the ZERO-subreq case.<br />
<br />
AFS and CIFS are normally unlikely to show this as they dispatch READ ops<br />
asynchronously, which allows the ZERO-subreq to finish first. 9P&#39;s READ op is<br />
completely synchronous, so the ZERO-subreq will always happen after. It isn&#39;t<br />
seen all the time, though, because the collection may be done in a worker<br />
thread.
Severity CVSS v4.0: Pending analysis
Last modification:
14/02/2026