Linux network filesystem support library
 help / color / mirror / Atom feed
* [PATCH] netfs: Fix UAF in netfs_unbuffered_write() on failed preparation
@ 2026-05-30  1:14 hongao
  2026-06-23 10:28 ` Christian Brauner
                   ` (2 more replies)
  0 siblings, 3 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 related	[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
  2 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 16:10   ` David Howells
  2026-06-23 14:53 ` David Howells
  2 siblings, 1 reply; 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
  2 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-06-23 11:52 ` ChenXiaoSong
@ 2026-06-23 16:10   ` David Howells
  2026-06-24  1:26     ` ChenXiaoSong
  0 siblings, 1 reply; 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 more replies)
  0 siblings, 3 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@vger.kernel.org

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-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
  2 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@vger.kernel.org

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-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
  2 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@vger.kernel.org

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-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
  2 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@vger.kernel.org

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 related	[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 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
2026-06-23 14:53 ` David Howells

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox