linux/fs/netfs
David Howells a3de58b12c
netfs: Fix unbuffered write error handling
If all the subrequests in an unbuffered write stream fail, the subrequest
collector doesn't update the stream->transferred value and it retains its
initial LONG_MAX value.  Unfortunately, if all active streams fail, then we
take the smallest value of { LONG_MAX, LONG_MAX, ... } as the value to set
in wreq->transferred - which is then returned from ->write_iter().

LONG_MAX was chosen as the initial value so that all the streams can be
quickly assessed by taking the smallest value of all stream->transferred -
but this only works if we've set any of them.

Fix this by adding a flag to indicate whether the value in
stream->transferred is valid and checking that when we integrate the
values.  stream->transferred can then be initialised to zero.

This was found by running the generic/750 xfstest against cifs with
cache=none.  It splices data to the target file.  Once (if) it has used up
all the available scratch space, the writes start failing with ENOSPC.
This causes ->write_iter() to fail.  However, it was returning
wreq->transferred, i.e. LONG_MAX, rather than an error (because it thought
the amount transferred was non-zero) and iter_file_splice_write() would
then try to clean up that amount of pipe bufferage - leading to an oops
when it overran.  The kernel log showed:

    CIFS: VFS: Send error in write = -28

followed by:

    BUG: kernel NULL pointer dereference, address: 0000000000000008

with:

    RIP: 0010:iter_file_splice_write+0x3a4/0x520
    do_splice+0x197/0x4e0

or:

    RIP: 0010:pipe_buf_release (include/linux/pipe_fs_i.h:282)
    iter_file_splice_write (fs/splice.c:755)

Also put a warning check into splice to announce if ->write_iter() returned
that it had written more than it was asked to.

Fixes: 288ace2f57 ("netfs: New writeback implementation")
Reported-by: Xiaoli Feng <fengxiaoli0714@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220445
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/915443.1755207950@warthog.procyon.org.uk
cc: Paulo Alcantara <pc@manguebit.org>
cc: Steve French <sfrench@samba.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: netfs@lists.linux.dev
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-08-15 15:56:49 +02:00
..
buffered_read.c Merge patch series "netfs: Miscellaneous fixes" 2025-05-21 14:35:34 +02:00
buffered_write.c netfs: Merge i_size update functions 2025-07-01 22:37:14 +02:00
direct_read.c netfs: Fix undifferentiation of DIO reads from unbuffered reads 2025-05-23 10:35:03 +02:00
direct_write.c netfs: Update tracepoints in a number of ways 2025-07-01 22:37:14 +02:00
fscache_cache.c netfs: Mark __nonstring lookup tables 2025-04-17 10:13:46 +02:00
fscache_cookie.c netfs: Mark __nonstring lookup tables 2025-04-17 10:13:46 +02:00
fscache_internal.h netfs, fscache: Combine fscache with netfs 2023-12-24 15:08:46 +00:00
fscache_io.c netfs: Fix the request's work item to not require a ref 2025-05-21 14:35:20 +02:00
fscache_main.c fscache: delete fscache_cookie_lru_timer when fscache exits to avoid UAF 2024-09-01 10:30:25 +02:00
fscache_proc.c netfs: Fix proc/fs/fscache symlink to point to "netfs" not "../netfs" 2024-01-04 13:15:32 +00:00
fscache_stats.c netfs: Fix interaction between write-streaming and cachefiles culling 2024-01-05 15:42:25 +00:00
fscache_volume.c netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING 2024-11-11 14:39:38 +01:00
internal.h netfs: Update tracepoints in a number of ways 2025-07-01 22:37:14 +02:00
iterator.c netfs: Speed up buffered reading 2024-09-12 12:20:41 +02:00
Kconfig netfs: clean up after renaming FSCACHE_DEBUG config 2024-08-12 22:03:26 +02:00
locking.c netfs: Downgrade i_rwsem for a buffered write 2024-10-17 15:33:42 +02:00
main.c netfs: Renumber the NETFS_RREQ_* flags to make traces easier to read 2025-07-01 22:37:14 +02:00
Makefile netfs: Add support for caching single monolithic objects such as AFS dirs 2024-12-20 22:34:06 +01:00
misc.c netfs: Update tracepoints in a number of ways 2025-07-01 22:37:14 +02:00
objects.c netfs: Fix undifferentiation of DIO reads from unbuffered reads 2025-05-23 10:35:03 +02:00
read_collect.c netfs: Fix unbuffered write error handling 2025-08-15 15:56:49 +02:00
read_pgpriv2.c netfs: Fix race between cache write completion and ALL_QUEUED being set 2025-07-14 11:05:02 +02:00
read_retry.c netfs: Fix wait/wake to be consistent about the waitqueue used 2025-05-21 14:35:21 +02:00
read_single.c netfs: Fix the request's work item to not require a ref 2025-05-21 14:35:20 +02:00
rolling_buffer.c netfs: Fix rolling_buffer_load_from_ra() to not clear mark bits 2025-03-19 10:04:22 +01:00
stats.c netfs: Add retry stat counters 2025-02-13 16:00:48 +01:00
write_collect.c netfs: Fix unbuffered write error handling 2025-08-15 15:56:49 +02:00
write_issue.c netfs: Fix unbuffered write error handling 2025-08-15 15:56:49 +02:00
write_retry.c netfs: Update tracepoints in a number of ways 2025-07-01 22:37:14 +02:00