Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

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&amp;#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&amp;#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 &amp; 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.

Impacto