All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid()
@ 2024-11-08 22:13 trondmy
  2024-11-08 22:13 ` [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open() trondmy
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: trondmy @ 2024-11-08 22:13 UTC (permalink / raw)
  To: Yang Erkun; +Cc: linux-nfs

From: Trond Myklebust <trond.myklebust@hammerspace.com>

There is no need to wake up another waiter on the seqid list unless the
seqid being removed is at the head of the list, and so is relinquishing
control of the sequence counter to the next entry.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
 fs/nfs/nfs4state.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index dafd61186557..9a9f60a2291b 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1083,14 +1083,12 @@ void nfs_release_seqid(struct nfs_seqid *seqid)
 		return;
 	sequence = seqid->sequence;
 	spin_lock(&sequence->lock);
-	list_del_init(&seqid->list);
-	if (!list_empty(&sequence->list)) {
-		struct nfs_seqid *next;
-
-		next = list_first_entry(&sequence->list,
-				struct nfs_seqid, list);
+	if (list_is_first(&seqid->list, &sequence->list) &&
+	    !list_is_singular(&sequence->list)) {
+		struct nfs_seqid *next = list_next_entry(seqid, list);
 		rpc_wake_up_queued_task(&sequence->wait, next->task);
 	}
+	list_del_init(&seqid->list);
 	spin_unlock(&sequence->lock);
 }
 
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open()
  2024-11-08 22:13 [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() trondmy
@ 2024-11-08 22:13 ` trondmy
  2024-11-09  2:25   ` yangerkun
  2024-12-26  1:21   ` Sasha Levin
  2024-11-09  2:24 ` [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() yangerkun
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 8+ messages in thread
From: trondmy @ 2024-11-08 22:13 UTC (permalink / raw)
  To: Yang Erkun; +Cc: linux-nfs

From: Trond Myklebust <trond.myklebust@hammerspace.com>

Yang Erkun reports that when two threads are opening files at the same
time, and are forced to abort before a reply is seen, then the call to
nfs_release_seqid() in nfs4_opendata_free() can result in a
use-after-free of the pointer to the defunct rpc task of the other
thread.
The fix is to ensure that if the RPC call is aborted before the call to
nfs_wait_on_sequence() is complete, then we must call nfs_release_seqid()
in nfs4_open_release() before the rpc_task is freed.

Reported-by: Yang Erkun <yangerkun@huawei.com>
Fixes: 24ac23ab88df ("NFSv4: Convert open() into an asynchronous RPC call")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
 fs/nfs/nfs4proc.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9d40319e063d..405f17e6e0b4 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2603,12 +2603,14 @@ static void nfs4_open_release(void *calldata)
 	struct nfs4_opendata *data = calldata;
 	struct nfs4_state *state = NULL;
 
+	/* In case of error, no cleanup! */
+	if (data->rpc_status != 0 || !data->rpc_done) {
+		nfs_release_seqid(data->o_arg.seqid);
+		goto out_free;
+	}
 	/* If this request hasn't been cancelled, do nothing */
 	if (!data->cancelled)
 		goto out_free;
-	/* In case of error, no cleanup! */
-	if (data->rpc_status != 0 || !data->rpc_done)
-		goto out_free;
 	/* In case we need an open_confirm, no cleanup! */
 	if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
 		goto out_free;
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid()
  2024-11-08 22:13 [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() trondmy
  2024-11-08 22:13 ` [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open() trondmy
@ 2024-11-09  2:24 ` yangerkun
  2024-12-25  2:50 ` Li Lingfeng
  2024-12-26  1:21 ` Sasha Levin
  3 siblings, 0 replies; 8+ messages in thread
From: yangerkun @ 2024-11-09  2:24 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs

LGTM

Reviewed-by: Yang Erkun <yangerkun@huawei.com>

在 2024/11/9 6:13, trondmy@kernel.org 写道:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
> 
> There is no need to wake up another waiter on the seqid list unless the
> seqid being removed is at the head of the list, and so is relinquishing
> control of the sequence counter to the next entry.
> 
> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
> ---
>   fs/nfs/nfs4state.c | 10 ++++------
>   1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
> index dafd61186557..9a9f60a2291b 100644
> --- a/fs/nfs/nfs4state.c
> +++ b/fs/nfs/nfs4state.c
> @@ -1083,14 +1083,12 @@ void nfs_release_seqid(struct nfs_seqid *seqid)
>   		return;
>   	sequence = seqid->sequence;
>   	spin_lock(&sequence->lock);
> -	list_del_init(&seqid->list);
> -	if (!list_empty(&sequence->list)) {
> -		struct nfs_seqid *next;
> -
> -		next = list_first_entry(&sequence->list,
> -				struct nfs_seqid, list);
> +	if (list_is_first(&seqid->list, &sequence->list) &&
> +	    !list_is_singular(&sequence->list)) {
> +		struct nfs_seqid *next = list_next_entry(seqid, list);
>   		rpc_wake_up_queued_task(&sequence->wait, next->task);
>   	}
> +	list_del_init(&seqid->list);
>   	spin_unlock(&sequence->lock);
>   }
>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open()
  2024-11-08 22:13 ` [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open() trondmy
@ 2024-11-09  2:25   ` yangerkun
  2024-12-26  1:21   ` Sasha Levin
  1 sibling, 0 replies; 8+ messages in thread
From: yangerkun @ 2024-11-09  2:25 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs

LGTM

Reviewed-by: Yang Erkun <yangerkun@huawei.com>

在 2024/11/9 6:13, trondmy@kernel.org 写道:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
> 
> Yang Erkun reports that when two threads are opening files at the same
> time, and are forced to abort before a reply is seen, then the call to
> nfs_release_seqid() in nfs4_opendata_free() can result in a
> use-after-free of the pointer to the defunct rpc task of the other
> thread.
> The fix is to ensure that if the RPC call is aborted before the call to
> nfs_wait_on_sequence() is complete, then we must call nfs_release_seqid()
> in nfs4_open_release() before the rpc_task is freed.
> 
> Reported-by: Yang Erkun <yangerkun@huawei.com>
> Fixes: 24ac23ab88df ("NFSv4: Convert open() into an asynchronous RPC call")
> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
> ---
>   fs/nfs/nfs4proc.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 9d40319e063d..405f17e6e0b4 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -2603,12 +2603,14 @@ static void nfs4_open_release(void *calldata)
>   	struct nfs4_opendata *data = calldata;
>   	struct nfs4_state *state = NULL;
>   
> +	/* In case of error, no cleanup! */
> +	if (data->rpc_status != 0 || !data->rpc_done) {
> +		nfs_release_seqid(data->o_arg.seqid);
> +		goto out_free;
> +	}
>   	/* If this request hasn't been cancelled, do nothing */
>   	if (!data->cancelled)
>   		goto out_free;
> -	/* In case of error, no cleanup! */
> -	if (data->rpc_status != 0 || !data->rpc_done)
> -		goto out_free;
>   	/* In case we need an open_confirm, no cleanup! */
>   	if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
>   		goto out_free;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid()
  2024-11-08 22:13 [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() trondmy
  2024-11-08 22:13 ` [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open() trondmy
  2024-11-09  2:24 ` [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() yangerkun
@ 2024-12-25  2:50 ` Li Lingfeng
  2024-12-25  3:21   ` yangerkun
  2024-12-26  1:21 ` Sasha Levin
  3 siblings, 1 reply; 8+ messages in thread
From: Li Lingfeng @ 2024-12-25  2:50 UTC (permalink / raw)
  To: trondmy, Yang Erkun; +Cc: linux-nfs

Hi, I noticed that [PATCH 2] has been applied to the stable, but [PATCH 1]
has not.
Based on 6.6 where [PATCH 2] was merged, I can still reproduce the
original issue, and [PATCH 1] needs to be applied as well to resolve it.
It may be better to push [PATCH 1] to the stable as well.
Thanks.

在 2024/11/9 6:13, trondmy@kernel.org 写道:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
>
> There is no need to wake up another waiter on the seqid list unless the
> seqid being removed is at the head of the list, and so is relinquishing
> control of the sequence counter to the next entry.
>
> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
> ---
>   fs/nfs/nfs4state.c | 10 ++++------
>   1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
> index dafd61186557..9a9f60a2291b 100644
> --- a/fs/nfs/nfs4state.c
> +++ b/fs/nfs/nfs4state.c
> @@ -1083,14 +1083,12 @@ void nfs_release_seqid(struct nfs_seqid *seqid)
>   		return;
>   	sequence = seqid->sequence;
>   	spin_lock(&sequence->lock);
> -	list_del_init(&seqid->list);
> -	if (!list_empty(&sequence->list)) {
> -		struct nfs_seqid *next;
> -
> -		next = list_first_entry(&sequence->list,
> -				struct nfs_seqid, list);
> +	if (list_is_first(&seqid->list, &sequence->list) &&
> +	    !list_is_singular(&sequence->list)) {
> +		struct nfs_seqid *next = list_next_entry(seqid, list);
>   		rpc_wake_up_queued_task(&sequence->wait, next->task);
>   	}
> +	list_del_init(&seqid->list);
>   	spin_unlock(&sequence->lock);
>   }
>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid()
  2024-12-25  2:50 ` Li Lingfeng
@ 2024-12-25  3:21   ` yangerkun
  0 siblings, 0 replies; 8+ messages in thread
From: yangerkun @ 2024-12-25  3:21 UTC (permalink / raw)
  To: Li Lingfeng, trondmy, Greg KH; +Cc: linux-nfs, linux-stable

You need cc stable.

在 2024/12/25 10:50, Li Lingfeng 写道:
> Hi, I noticed that [PATCH 2] has been applied to the stable, but [PATCH 1]
> has not.
> Based on 6.6 where [PATCH 2] was merged, I can still reproduce the
> original issue, and [PATCH 1] needs to be applied as well to resolve it.
> It may be better to push [PATCH 1] to the stable as well.
> Thanks.
> 
> 在 2024/11/9 6:13, trondmy@kernel.org 写道:
>> From: Trond Myklebust <trond.myklebust@hammerspace.com>
>>
>> There is no need to wake up another waiter on the seqid list unless the
>> seqid being removed is at the head of the list, and so is relinquishing
>> control of the sequence counter to the next entry.
>>
>> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
>> ---
>>   fs/nfs/nfs4state.c | 10 ++++------
>>   1 file changed, 4 insertions(+), 6 deletions(-)
>>
>> diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
>> index dafd61186557..9a9f60a2291b 100644
>> --- a/fs/nfs/nfs4state.c
>> +++ b/fs/nfs/nfs4state.c
>> @@ -1083,14 +1083,12 @@ void nfs_release_seqid(struct nfs_seqid *seqid)
>>           return;
>>       sequence = seqid->sequence;
>>       spin_lock(&sequence->lock);
>> -    list_del_init(&seqid->list);
>> -    if (!list_empty(&sequence->list)) {
>> -        struct nfs_seqid *next;
>> -
>> -        next = list_first_entry(&sequence->list,
>> -                struct nfs_seqid, list);
>> +    if (list_is_first(&seqid->list, &sequence->list) &&
>> +        !list_is_singular(&sequence->list)) {
>> +        struct nfs_seqid *next = list_next_entry(seqid, list);
>>           rpc_wake_up_queued_task(&sequence->wait, next->task);
>>       }
>> +    list_del_init(&seqid->list);
>>       spin_unlock(&sequence->lock);
>>   }


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open()
  2024-11-08 22:13 ` [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open() trondmy
  2024-11-09  2:25   ` yangerkun
@ 2024-12-26  1:21   ` Sasha Levin
  1 sibling, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2024-12-26  1:21 UTC (permalink / raw)
  To: stable; +Cc: trondmy, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

Found matching upstream commit: 2fdb05dc0931250574f0cb0ebeb5ed8e20f4a889

WARNING: Author mismatch between patch and found commit:
Backport author: trondmy@kernel.org
Commit author: Trond Myklebust <trond.myklebust@hammerspace.com>


Status in newer kernel trees:
6.12.y | Present (different SHA1: b56ae8e71555)

Note: The patch differs from the upstream commit:
---
Failed to apply patch cleanly, falling back to interdiff...
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.12.y       |  Failed     |  N/A       |
| stable/linux-6.6.y        |  Failed     |  N/A       |
| stable/linux-6.1.y        |  Failed     |  N/A       |
| stable/linux-5.15.y       |  Failed     |  N/A       |
| stable/linux-5.10.y       |  Failed     |  N/A       |
| stable/linux-5.4.y        |  Failed     |  N/A       |

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid()
  2024-11-08 22:13 [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() trondmy
                   ` (2 preceding siblings ...)
  2024-12-25  2:50 ` Li Lingfeng
@ 2024-12-26  1:21 ` Sasha Levin
  3 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2024-12-26  1:21 UTC (permalink / raw)
  To: stable; +Cc: trondmy, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

Found matching upstream commit: c968fd23c68e9929ab6cad4faffc8ea603e98e5d

WARNING: Author mismatch between patch and found commit:
Backport author: trondmy@kernel.org
Commit author: Trond Myklebust <trond.myklebust@hammerspace.com>


Status in newer kernel trees:
6.12.y | Not found

Note: The patch differs from the upstream commit:
---
1:  c968fd23c68e ! 1:  4b6aa0b050af NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid()
    @@ Commit message
         seqid being removed is at the head of the list, and so is relinquishing
         control of the sequence counter to the next entry.
     
    -    Reviewed-by: Yang Erkun <yangerkun@huawei.com>
         Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
     
      ## fs/nfs/nfs4state.c ##
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.12.y       |  Success    |  Success   |
| stable/linux-6.6.y        |  Success    |  Success   |
| stable/linux-6.1.y        |  Success    |  Success   |
| stable/linux-5.15.y       |  Success    |  Success   |
| stable/linux-5.10.y       |  Success    |  Success   |
| stable/linux-5.4.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-12-26  1:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-08 22:13 [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() trondmy
2024-11-08 22:13 ` [PATCH 2/2] NFSv4.0: Fix a use-after-free problem in the asynchronous open() trondmy
2024-11-09  2:25   ` yangerkun
2024-12-26  1:21   ` Sasha Levin
2024-11-09  2:24 ` [PATCH 1/2] NFSv4.0: Fix the wake up of the next waiter in nfs_release_seqid() yangerkun
2024-12-25  2:50 ` Li Lingfeng
2024-12-25  3:21   ` yangerkun
2024-12-26  1:21 ` Sasha Levin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.