[PATCH 5.5 73/80] NFSv4: Ensure the delegation cred is pinned when we call delegreturn

From: Greg Kroah-Hartman
Date: Tue Feb 18 2020 - 15:04:24 EST


From: Trond Myklebust <trondmy@xxxxxxxxx>

commit 5d63944f8206a80636ae8cb4b9107d3b49f43d37 upstream.

Ensure we don't release the delegation cred during the call to
nfs4_proc_delegreturn().

Fixes: ee05f456772d ("NFSv4: Fix races between open and delegreturn")
Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
Signed-off-by: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
fs/nfs/delegation.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -222,13 +222,18 @@ void nfs_inode_reclaim_delegation(struct

static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
{
+ const struct cred *cred;
int res = 0;

- if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
- res = nfs4_proc_delegreturn(inode,
- delegation->cred,
+ if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
+ spin_lock(&delegation->lock);
+ cred = get_cred(delegation->cred);
+ spin_unlock(&delegation->lock);
+ res = nfs4_proc_delegreturn(inode, cred,
&delegation->stateid,
issync);
+ put_cred(cred);
+ }
return res;
}