Skip to content

Commit 8fcd461

Browse files
jtlaytonJ. Bruce Fields
authored andcommitted
nfsd: do nfs4_check_fh in nfs4_check_file instead of nfs4_check_olstateid
Currently, preprocess_stateid_op calls nfs4_check_olstateid which verifies that the open stateid corresponds to the current filehandle in the call by calling nfs4_check_fh. If the stateid is a NFS4_DELEG_STID however, then no such check is done. This could cause incorrect enforcement of permissions, because the nfsd_permission() call in nfs4_check_file uses current the current filehandle, but any subsequent IO operation will use the file descriptor in the stateid. Move the call to nfs4_check_fh into nfs4_check_file instead so that it can be done for all stateid types. Signed-off-by: Jeff Layton <[email protected]> Cc: [email protected] [bfields: moved fh check to avoid NULL deref in special stateid case] Signed-off-by: J. Bruce Fields <[email protected]>
1 parent 1ca4b88 commit 8fcd461

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

fs/nfsd/nfs4state.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4396,9 +4396,9 @@ laundromat_main(struct work_struct *laundry)
43964396
queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
43974397
}
43984398

4399-
static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
4399+
static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stid *stp)
44004400
{
4401-
if (!fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle))
4401+
if (!fh_match(&fhp->fh_handle, &stp->sc_file->fi_fhandle))
44024402
return nfserr_bad_stateid;
44034403
return nfs_ok;
44044404
}
@@ -4601,9 +4601,6 @@ nfs4_check_olstateid(struct svc_fh *fhp, struct nfs4_ol_stateid *ols, int flags)
46014601
{
46024602
__be32 status;
46034603

4604-
status = nfs4_check_fh(fhp, ols);
4605-
if (status)
4606-
return status;
46074604
status = nfsd4_check_openowner_confirmed(ols);
46084605
if (status)
46094606
return status;
@@ -4690,6 +4687,9 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
46904687
status = nfserr_bad_stateid;
46914688
break;
46924689
}
4690+
if (status)
4691+
goto out;
4692+
status = nfs4_check_fh(fhp, s);
46934693

46944694
done:
46954695
if (!status && filpp)
@@ -4798,7 +4798,7 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
47984798
status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
47994799
if (status)
48004800
return status;
4801-
return nfs4_check_fh(current_fh, stp);
4801+
return nfs4_check_fh(current_fh, &stp->st_stid);
48024802
}
48034803

48044804
/*

0 commit comments

Comments
 (0)