2023-01-11 16:28:36

by Xingyuan Mo

[permalink] [raw]
Subject: [PATCH] NFSD: fix use-after-free in nfsd4_ssc_setup_dul()

If signal_pending() returns true, schedule_timeout() will not be executed,
causing the waiting task to remain in the wait queue.
Fixed by adding a call to finish_wait(), which ensures that the waiting
task will always be removed from the wait queue.

Reported-by: Xingyuan Mo <[email protected]>
Signed-off-by: Xingyuan Mo <[email protected]>
---
fs/nfsd/nfs4proc.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index bd880d55f565..3fa819e29b3f 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1318,6 +1318,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
/* allow 20secs for mount/unmount for now - revisit */
if (signal_pending(current) ||
(schedule_timeout(20*HZ) == 0)) {
+ finish_wait(&nn->nfsd_ssc_waitq, &wait);
kfree(work);
return nfserr_eagain;
}
--
2.34.1


2023-01-11 16:37:18

by Jeff Layton

[permalink] [raw]
Subject: Re: [PATCH] NFSD: fix use-after-free in nfsd4_ssc_setup_dul()

On Thu, 2023-01-12 at 00:24 +0800, Xingyuan Mo wrote:
> If signal_pending() returns true, schedule_timeout() will not be executed,
> causing the waiting task to remain in the wait queue.
> Fixed by adding a call to finish_wait(), which ensures that the waiting
> task will always be removed from the wait queue.
>
> Reported-by: Xingyuan Mo <[email protected]>
> Signed-off-by: Xingyuan Mo <[email protected]>
> ---
> fs/nfsd/nfs4proc.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index bd880d55f565..3fa819e29b3f 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -1318,6 +1318,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
> /* allow 20secs for mount/unmount for now - revisit */
> if (signal_pending(current) ||
> (schedule_timeout(20*HZ) == 0)) {
> + finish_wait(&nn->nfsd_ssc_waitq, &wait);
> kfree(work);
> return nfserr_eagain;
> }

Nice catch.

Reviewed-by: Jeff Layton <[email protected]>

2023-01-12 02:40:01

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH] NFSD: fix use-after-free in nfsd4_ssc_setup_dul()



> On Jan 11, 2023, at 11:24 AM, Xingyuan Mo <[email protected]> wrote:
>
> If signal_pending() returns true, schedule_timeout() will not be executed,
> causing the waiting task to remain in the wait queue.
> Fixed by adding a call to finish_wait(), which ensures that the waiting
> task will always be removed from the wait queue.
>
> Reported-by: Xingyuan Mo <[email protected]>
> Signed-off-by: Xingyuan Mo <[email protected]>

Hello, applied to nfsd's for-rc, thanks! I expect to send a PR for to Linus
in a few days.


> ---
> fs/nfsd/nfs4proc.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index bd880d55f565..3fa819e29b3f 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -1318,6 +1318,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
> /* allow 20secs for mount/unmount for now - revisit */
> if (signal_pending(current) ||
> (schedule_timeout(20*HZ) == 0)) {
> + finish_wait(&nn->nfsd_ssc_waitq, &wait);
> kfree(work);
> return nfserr_eagain;
> }
> --
> 2.34.1
>

--
Chuck Lever