CVE-2025-40007
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
20/10/2025
Última modificación:
21/10/2025
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
netfs: fix reference leak<br />
<br />
Commit 20d72b00ca81 ("netfs: Fix the request&#39;s work item to not<br />
require a ref") modified netfs_alloc_request() to initialize the<br />
reference counter to 2 instead of 1. The rationale was that the<br />
requet&#39;s "work" would release the second reference after completion<br />
(via netfs_{read,write}_collection_worker()). That works most of the<br />
time if all goes well.<br />
<br />
However, it leaks this additional reference if the request is released<br />
before the I/O operation has been submitted: the error code path only<br />
decrements the reference counter once and the work item will never be<br />
queued because there will never be a completion.<br />
<br />
This has caused outages of our whole server cluster today because<br />
tasks were blocked in netfs_wait_for_outstanding_io(), leading to<br />
deadlocks in Ceph (another bug that I will address soon in another<br />
patch). This was caused by a netfs_pgpriv2_begin_copy_to_cache() call<br />
which failed in fscache_begin_write_operation(). The leaked<br />
netfs_io_request was never completed, leaving `netfs_inode.io_count`<br />
with a positive value forever.<br />
<br />
All of this is super-fragile code. Finding out which code paths will<br />
lead to an eventual completion and which do not is hard to see:<br />
<br />
- Some functions like netfs_create_write_req() allocate a request, but<br />
will never submit any I/O.<br />
<br />
- netfs_unbuffered_read_iter_locked() calls netfs_unbuffered_read()<br />
and then netfs_put_request(); however, netfs_unbuffered_read() can<br />
also fail early before submitting the I/O request, therefore another<br />
netfs_put_request() call must be added there.<br />
<br />
A rule of thumb is that functions that return a `netfs_io_request` do<br />
not submit I/O, and all of their callers must be checked.<br />
<br />
For my taste, the whole netfs code needs an overhaul to make reference<br />
counting easier to understand and less fragile & obscure. But to fix<br />
this bug here and now and produce a patch that is adequate for a<br />
stable backport, I tried a minimal approach that quickly frees the<br />
request object upon early failure.<br />
<br />
I decided against adding a second netfs_put_request() each time<br />
because that would cause code duplication which obscures the code<br />
further. Instead, I added the function netfs_put_failed_request()<br />
which frees such a failed request synchronously under the assumption<br />
that the reference count is exactly 2 (as initially set by<br />
netfs_alloc_request() and never touched), verified by a<br />
WARN_ON_ONCE(). It then deinitializes the request object (without<br />
going through the "cleanup_work" indirection) and frees the allocation<br />
(with RCU protection to protect against concurrent access by<br />
netfs_requests_seq_start()).<br />
<br />
All code paths that fail early have been changed to call<br />
netfs_put_failed_request() instead of netfs_put_request().<br />
Additionally, I have added a netfs_put_request() call to<br />
netfs_unbuffered_read() as explained above because the<br />
netfs_put_failed_request() approach does not work there.