* [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation
@ 2026-05-30 1:14 hongao
2026-06-23 10:28 ` Christian Brauner
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: hongao @ 2026-05-30 1:14 UTC (permalink / raw)
To: David Howells
Cc: Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, hongao,
syzbot+3c74b1f0c372e98efc32
If write subrequest preparation fails, netfs_unbuffered_write() calls
netfs_write_subrequest_terminated() and then reads subreq->error to set
wreq->error.
However, netfs_write_subrequest_terminated() consumes a reference to the
subrequest through netfs_put_subrequest(), so the subrequest may be freed
before netfs_unbuffered_write() reads subreq->error again. This can
trigger a slab-use-after-free.
Save the error locally before terminating the subrequest, and use the
saved value afterwards.
Fixes: a0b4c7a49137 ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Reported-by: syzbot+3c74b1f0c372e98efc32@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=3c74b1f0c372e98efc32
Signed-off-by: hongao <hongao@uniontech.com>
---
fs/netfs/direct_write.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index 25f8ceb15fad..2d5361702076 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -115,8 +115,9 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq)
/* Check if (re-)preparation failed. */
if (unlikely(test_bit(NETFS_SREQ_FAILED, &subreq->flags))) {
- netfs_write_subrequest_terminated(subreq, subreq->error);
- wreq->error = subreq->error;
+ ret = subreq->error;
+ wreq->error = ret;
+ netfs_write_subrequest_terminated(subreq, ret);
break;
}
--
2.51.0
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-05-30 1:14 [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation hongao @ 2026-06-23 10:28 ` Christian Brauner 2026-06-23 11:52 ` ChenXiaoSong ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Christian Brauner @ 2026-06-23 10:28 UTC (permalink / raw) To: hongao Cc: David Howells, Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32 On 2026-05-30 09:14 +0800, hongao wrote: > If write subrequest preparation fails, netfs_unbuffered_write() calls > netfs_write_subrequest_terminated() and then reads subreq->error to set > wreq->error. > > However, netfs_write_subrequest_terminated() consumes a reference to the > subrequest through netfs_put_subrequest(), so the subrequest may be freed > before netfs_unbuffered_write() reads subreq->error again. This can > trigger a slab-use-after-free. > > Save the error locally before terminating the subrequest, and use the > saved value afterwards. > > Fixes: a0b4c7a49137 ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") > Reported-by: syzbot+3c74b1f0c372e98efc32@syzkaller.appspotmail.com > Closes: https://syzkaller.appspot.com/bug?extid=3c74b1f0c372e98efc32 > > Signed-off-by: hongao <hongao@uniontech.com> > --- David? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-05-30 1:14 [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation hongao 2026-06-23 10:28 ` Christian Brauner @ 2026-06-23 11:52 ` ChenXiaoSong 2026-06-23 14:53 ` David Howells 2026-06-23 16:10 ` David Howells 3 siblings, 0 replies; 9+ messages in thread From: ChenXiaoSong @ 2026-06-23 11:52 UTC (permalink / raw) To: hongao, David Howells Cc: Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32 Hi hongao and David, After applying this patch, I can still reproduce the use-after-free issue. C reproducer: https://syzkaller.appspot.com/text?tag=ReproC&x=171b697e580000 Note that QEMU should be started with the following virtfs option: -virtfs ...,mount_tag=syz,... On 5/30/26 09:14, hongao wrote: > If write subrequest preparation fails, netfs_unbuffered_write() calls > netfs_write_subrequest_terminated() and then reads subreq->error to set > wreq->error. > > However, netfs_write_subrequest_terminated() consumes a reference to the > subrequest through netfs_put_subrequest(), so the subrequest may be freed > before netfs_unbuffered_write() reads subreq->error again. This can > trigger a slab-use-after-free. > > Save the error locally before terminating the subrequest, and use the > saved value afterwards. > > Fixes: a0b4c7a49137 ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") > Reported-by: syzbot+3c74b1f0c372e98efc32@syzkaller.appspotmail.com > Closes: https://syzkaller.appspot.com/bug?extid=3c74b1f0c372e98efc32 > > Signed-off-by: hongao <hongao@uniontech.com> > --- > fs/netfs/direct_write.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c > index 25f8ceb15fad..2d5361702076 100644 > --- a/fs/netfs/direct_write.c > +++ b/fs/netfs/direct_write.c > @@ -115,8 +115,9 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq) > > /* Check if (re-)preparation failed. */ > if (unlikely(test_bit(NETFS_SREQ_FAILED, &subreq->flags))) { > - netfs_write_subrequest_terminated(subreq, subreq->error); > - wreq->error = subreq->error; > + ret = subreq->error; > + wreq->error = ret; > + netfs_write_subrequest_terminated(subreq, ret); > break; > } > -- ChenXiaoSong <chenxiaosong@chenxiaosong.com> Chinese Homepage: https://chenxiaosong.com English Homepage: https://chenxiaosong.com/en ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-05-30 1:14 [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation hongao 2026-06-23 10:28 ` Christian Brauner 2026-06-23 11:52 ` ChenXiaoSong @ 2026-06-23 14:53 ` David Howells 2026-06-23 16:10 ` David Howells 3 siblings, 0 replies; 9+ messages in thread From: David Howells @ 2026-06-23 14:53 UTC (permalink / raw) To: hongao Cc: dhowells, Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32 hongao <hongao@uniontech.com> wrote: > /* Check if (re-)preparation failed. */ > if (unlikely(test_bit(NETFS_SREQ_FAILED, &subreq->flags))) { > - netfs_write_subrequest_terminated(subreq, subreq->error); > - wreq->error = subreq->error; > + ret = subreq->error; > + wreq->error = ret; > + netfs_write_subrequest_terminated(subreq, ret); > break; > } This shouldn't be effective as all netfs_write_subrequest_terminated() will do is pass control of the subreq struct back to the app thread. David ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-05-30 1:14 [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation hongao ` (2 preceding siblings ...) 2026-06-23 14:53 ` David Howells @ 2026-06-23 16:10 ` David Howells 2026-06-24 1:26 ` ChenXiaoSong ` (3 more replies) 3 siblings, 4 replies; 9+ messages in thread From: David Howells @ 2026-06-23 16:10 UTC (permalink / raw) To: ChenXiaoSong Cc: dhowells, hongao, Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32 ChenXiaoSong <chenxiaosong@chenxiaosong.com> wrote: > After applying this patch, I can still reproduce the use-after-free issue. Can you get some tracing? I have a suspicion it's a refcount bug. The following tracepoints would be useful: echo 1 > /sys/kernel/tracing/events/netfs/netfs_read/enable echo 1 > /sys/kernel/tracing/events/netfs/netfs_write/enable echo 1 > /sys/kernel/tracing/events/netfs/netfs_rreq/enable echo 1 > /sys/kernel/tracing/events/netfs/netfs_sreq/enable echo 1 > /sys/kernel/tracing/events/netfs/netfs_failure/enable echo 1 > /sys/kernel/tracing/events/error_report/enable And if you can capture this, can you compress the resulting trace and send it to me? Thanks, David ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-06-23 16:10 ` David Howells @ 2026-06-24 1:26 ` ChenXiaoSong 2026-06-24 7:36 ` David Howells ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: ChenXiaoSong @ 2026-06-24 1:26 UTC (permalink / raw) To: David Howells, hongao Cc: Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32, Steve French, Namjae Jeon, linux-cifs Hi David and hongao, Please refer to my blog for the tracing log and reproduction steps: https://chenxiaosong.com/en/netfs-uaf-in-netfs_unbuffered_write.html (I will make sure this link is always accessible) I would appreciate it if you could continue debugging and fixing this issue. As I have many SMB features to implement and review tasks to do. On 6/24/26 00:10, David Howells wrote: > ChenXiaoSong <chenxiaosong@chenxiaosong.com> wrote: > >> After applying this patch, I can still reproduce the use-after-free issue. > > Can you get some tracing? I have a suspicion it's a refcount bug. > > The following tracepoints would be useful: > > echo 1 > /sys/kernel/tracing/events/netfs/netfs_read/enable > echo 1 > /sys/kernel/tracing/events/netfs/netfs_write/enable > echo 1 > /sys/kernel/tracing/events/netfs/netfs_rreq/enable > echo 1 > /sys/kernel/tracing/events/netfs/netfs_sreq/enable > echo 1 > /sys/kernel/tracing/events/netfs/netfs_failure/enable > echo 1 > /sys/kernel/tracing/events/error_report/enable > > And if you can capture this, can you compress the resulting trace and send it > to me? > > Thanks, > David > -- ChenXiaoSong <chenxiaosong@chenxiaosong.com> Chinese Homepage: https://chenxiaosong.com English Homepage: https://chenxiaosong.com/en ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-06-23 16:10 ` David Howells 2026-06-24 1:26 ` ChenXiaoSong @ 2026-06-24 7:36 ` David Howells 2026-06-24 10:59 ` David Howells 2026-06-24 11:02 ` David Howells 3 siblings, 0 replies; 9+ messages in thread From: David Howells @ 2026-06-24 7:36 UTC (permalink / raw) To: ChenXiaoSong Cc: dhowells, hongao, Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32, Steve French, Namjae Jeon, linux-cifs This excerpt would seem to show how the problem comes about: a.out-717 : netfs_sreq: R=00000001[13] UPLD PREP f=000 s=240000 0/0 s=192 e=0 a.out-717 : netfs_sreq: R=00000001[13] UPLD SUBMT f=100 s=240000 0/20000 s=192 e=0 a.out-717 : netfs_sreq: R=00000001[13] UPLD TERM f=310 s=240000 1fac0/20000 s=160 e=0 a.out-717 : netfs_rreq: R=00000001 UW WAKE-Q f=1801 a.out-717 : netfs_rreq: R=00000001 UW DONE-QUIESCE f=1801 a.out-717 : netfs_sreq: R=00000001[13] UPLD RETRY f=210 s=240000 1fac0/20000 s=160 e=-11 a.out-717 : netfs_sreq: R=00000001[13] UPLD SUBMT f=100 s=240000 0/dbfac0 s=192 e=0 a.out-717 : netfs_failure: R=00000001[13] UPLD f=500 s=240000 0/dbfac0 write e=-5 It looks like there are two issues: firstly, why does the upload stop short? Presumably that's forced by the test. Secondly, I think it has miscalculated the subreq size in the retry, hence the EIO. David ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-06-23 16:10 ` David Howells 2026-06-24 1:26 ` ChenXiaoSong 2026-06-24 7:36 ` David Howells @ 2026-06-24 10:59 ` David Howells 2026-06-24 11:02 ` David Howells 3 siblings, 0 replies; 9+ messages in thread From: David Howells @ 2026-06-24 10:59 UTC (permalink / raw) To: ChenXiaoSong Cc: dhowells, hongao, Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32, Steve French, Namjae Jeon, linux-cifs Actually, this shows what happened: a.out-717 : netfs_sreq: R=00000001[13] UPLD RETRY f=210 s=240000 1fac0/20000 s=160 e=-11 a.out-717 : netfs_sreq: R=00000001[13] UPLD SUBMT f=100 s=240000 0/dbfac0 s=192 e=0 a.out-717 : netfs_failure: R=00000001[13] UPLD f=500 s=240000 0/dbfac0 write e=-5 a.out-717 : netfs_rreq: R=00000001 UW PAUSE f=1801 a.out-717 : netfs_sreq: R=00000001[13] UPLD TERM f=500 s=240000 0/dbfac0 s=192 e=-5 a.out-717 : netfs_rreq: R=00000001 UW WAKE-Q f=1805 a.out-717 : netfs_failure: R=00000001[13] UPLD f=400 s=240000 0/dbfac0 write e=-5 a.out-717 : netfs_rreq: R=00000001 UW PAUSE f=1805 a.out-717 : netfs_sreq: R=00000001[13] UPLD TERM f=400 s=240000 0/dbfac0 s=192 e=-5 a.out-717 : netfs_rreq: R=00000001 UW WAKE-Q f=1805 a.out-717 : netfs_sreq: R=00000001[13] UPLD FREE f=400 s=240000 0/dbfac0 s=192 e=-5 There are two calls to netfs_write_subrequest_terminated(). You can see the IN_PROGRESS bit has been cleared by the second one (f=500 -> f=400). David ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation 2026-06-23 16:10 ` David Howells ` (2 preceding siblings ...) 2026-06-24 10:59 ` David Howells @ 2026-06-24 11:02 ` David Howells 3 siblings, 0 replies; 9+ messages in thread From: David Howells @ 2026-06-24 11:02 UTC (permalink / raw) To: ChenXiaoSong Cc: dhowells, hongao, Paulo Alcantara, netfs, linux-fsdevel, linux-kernel, syzbot+3c74b1f0c372e98efc32, Steve French, Namjae Jeon, linux-cifs I suspect the issue is this bit in netfs_unbuffered_write(): for (;;) { ... netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit); if (stream->prepare_write) { stream->prepare_write(subreq); __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags); netfs_stat(&netfs_n_wh_retry_write_subreq); } else { struct iov_iter source; netfs_reset_iter(subreq); source = subreq->io_iter; netfs_reissue_write(stream, subreq, &source); <---- } } This doesn't happen with AFS because it has a ->prepare_write() method. Does this change fix the problem for you? diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c index 25f8ceb15fad..9f6258da45d6 100644 --- a/fs/netfs/direct_write.c +++ b/fs/netfs/direct_write.c @@ -190,12 +190,6 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq) stream->prepare_write(subreq); __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags); netfs_stat(&netfs_n_wh_retry_write_subreq); - } else { - struct iov_iter source; - - netfs_reset_iter(subreq); - source = subreq->io_iter; - netfs_reissue_write(stream, subreq, &source); } } David ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-06-24 11:03 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-05-30 1:14 [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation hongao 2026-06-23 10:28 ` Christian Brauner 2026-06-23 11:52 ` ChenXiaoSong 2026-06-23 14:53 ` David Howells 2026-06-23 16:10 ` David Howells 2026-06-24 1:26 ` ChenXiaoSong 2026-06-24 7:36 ` David Howells 2026-06-24 10:59 ` David Howells 2026-06-24 11:02 ` David Howells
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®