nfsd41: access_valid
For nfs41, the open share flags are used also for delegation "wants" and "signals". Check that they are valid. Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
60adfc50de
commit
d87a8ade95
|
@ -910,6 +910,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
|
|||
resp->tag = args->tag;
|
||||
resp->opcnt = 0;
|
||||
resp->rqstp = rqstp;
|
||||
resp->cstate.minorversion = args->minorversion;
|
||||
resp->cstate.replay_owner = NULL;
|
||||
fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
|
||||
fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
|
||||
|
|
|
@ -1943,11 +1943,21 @@ find_file(struct inode *ino)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline int access_valid(u32 x)
|
||||
static inline int access_valid(u32 x, u32 minorversion)
|
||||
{
|
||||
if (x < NFS4_SHARE_ACCESS_READ)
|
||||
if ((x & NFS4_SHARE_ACCESS_MASK) < NFS4_SHARE_ACCESS_READ)
|
||||
return 0;
|
||||
if (x > NFS4_SHARE_ACCESS_BOTH)
|
||||
if ((x & NFS4_SHARE_ACCESS_MASK) > NFS4_SHARE_ACCESS_BOTH)
|
||||
return 0;
|
||||
x &= ~NFS4_SHARE_ACCESS_MASK;
|
||||
if (minorversion && x) {
|
||||
if ((x & NFS4_SHARE_WANT_MASK) > NFS4_SHARE_WANT_CANCEL)
|
||||
return 0;
|
||||
if ((x & NFS4_SHARE_WHEN_MASK) > NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED)
|
||||
return 0;
|
||||
x &= ~(NFS4_SHARE_WANT_MASK | NFS4_SHARE_WHEN_MASK);
|
||||
}
|
||||
if (x)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -2495,7 +2505,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
|||
__be32 status;
|
||||
|
||||
status = nfserr_inval;
|
||||
if (!access_valid(open->op_share_access)
|
||||
if (!access_valid(open->op_share_access, resp->cstate.minorversion)
|
||||
|| !deny_valid(open->op_share_deny))
|
||||
goto out;
|
||||
/*
|
||||
|
@ -3104,7 +3114,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
|
|||
(int)cstate->current_fh.fh_dentry->d_name.len,
|
||||
cstate->current_fh.fh_dentry->d_name.name);
|
||||
|
||||
if (!access_valid(od->od_share_access)
|
||||
if (!access_valid(od->od_share_access, cstate->minorversion)
|
||||
|| !deny_valid(od->od_share_deny))
|
||||
return nfserr_inval;
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ struct nfsd4_compound_state {
|
|||
struct nfsd4_slot *slot;
|
||||
__be32 *statp;
|
||||
size_t iovlen;
|
||||
u32 minorversion;
|
||||
u32 status;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue