Skip to content

Commit 9c65001

Browse files
daimngochucklever
authored andcommitted
NFSD: detect mismatch of file handle and delegation stateid in OPEN op
When the client sends an OPEN with claim type CLAIM_DELEG_CUR_FH or CLAIM_DELEGATION_CUR, the delegation stateid and the file handle must belong to the same file, otherwise return NFS4ERR_INVAL. Note that RFC8881, section 8.2.4, mandates the server to return NFS4ERR_BAD_STATEID if the selected table entry does not match the current filehandle. However returning NFS4ERR_BAD_STATEID in the OPEN causes the client to retry the operation and therefor get the client into a loop. To avoid this situation we return NFS4ERR_INVAL instead. Reported-by: Petro Pavlov <petro.pavlov@vastdata.com> Fixes: c44c5ee ("[PATCH] nfsd4: add open state code for CLAIM_DELEGATE_CUR") Cc: stable@vger.kernel.org Signed-off-by: Dai Ngo <dai.ngo@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 908e4ea commit 9c65001

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

fs/nfsd/nfs4state.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6361,6 +6361,20 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
63616361
status = nfs4_check_deleg(cl, open, &dp);
63626362
if (status)
63636363
goto out;
6364+
if (dp && nfsd4_is_deleg_cur(open) &&
6365+
(dp->dl_stid.sc_file != fp)) {
6366+
/*
6367+
* RFC8881 section 8.2.4 mandates the server to return
6368+
* NFS4ERR_BAD_STATEID if the selected table entry does
6369+
* not match the current filehandle. However returning
6370+
* NFS4ERR_BAD_STATEID in the OPEN can cause the client
6371+
* to repeatedly retry the operation with the same
6372+
* stateid, since the stateid itself is valid. To avoid
6373+
* this situation NFSD returns NFS4ERR_INVAL instead.
6374+
*/
6375+
status = nfserr_inval;
6376+
goto out;
6377+
}
63646378
stp = nfsd4_find_and_lock_existing_open(fp, open);
63656379
} else {
63666380
open->op_file = NULL;

0 commit comments

Comments
 (0)