aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4proc.c1
-rw-r--r--fs/nfsd/nfs4state.c20
2 files changed, 16 insertions, 5 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 3fdcca53212a..db208dd8fdca 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -910,6 +910,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
910 resp->tag = args->tag; 910 resp->tag = args->tag;
911 resp->opcnt = 0; 911 resp->opcnt = 0;
912 resp->rqstp = rqstp; 912 resp->rqstp = rqstp;
913 resp->cstate.minorversion = args->minorversion;
913 resp->cstate.replay_owner = NULL; 914 resp->cstate.replay_owner = NULL;
914 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); 915 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
915 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); 916 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d227f85b5ed2..374aaf3808e8 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1943,11 +1943,21 @@ find_file(struct inode *ino)
1943 return NULL; 1943 return NULL;
1944} 1944}
1945 1945
1946static inline int access_valid(u32 x) 1946static inline int access_valid(u32 x, u32 minorversion)
1947{ 1947{
1948 if (x < NFS4_SHARE_ACCESS_READ) 1948 if ((x & NFS4_SHARE_ACCESS_MASK) < NFS4_SHARE_ACCESS_READ)
1949 return 0; 1949 return 0;
1950 if (x > NFS4_SHARE_ACCESS_BOTH) 1950 if ((x & NFS4_SHARE_ACCESS_MASK) > NFS4_SHARE_ACCESS_BOTH)
1951 return 0;
1952 x &= ~NFS4_SHARE_ACCESS_MASK;
1953 if (minorversion && x) {
1954 if ((x & NFS4_SHARE_WANT_MASK) > NFS4_SHARE_WANT_CANCEL)
1955 return 0;
1956 if ((x & NFS4_SHARE_WHEN_MASK) > NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED)
1957 return 0;
1958 x &= ~(NFS4_SHARE_WANT_MASK | NFS4_SHARE_WHEN_MASK);
1959 }
1960 if (x)
1951 return 0; 1961 return 0;
1952 return 1; 1962 return 1;
1953} 1963}
@@ -2495,7 +2505,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2495 __be32 status; 2505 __be32 status;
2496 2506
2497 status = nfserr_inval; 2507 status = nfserr_inval;
2498 if (!access_valid(open->op_share_access) 2508 if (!access_valid(open->op_share_access, resp->cstate.minorversion)
2499 || !deny_valid(open->op_share_deny)) 2509 || !deny_valid(open->op_share_deny))
2500 goto out; 2510 goto out;
2501 /* 2511 /*
@@ -3104,7 +3114,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3104 (int)cstate->current_fh.fh_dentry->d_name.len, 3114 (int)cstate->current_fh.fh_dentry->d_name.len,
3105 cstate->current_fh.fh_dentry->d_name.name); 3115 cstate->current_fh.fh_dentry->d_name.name);
3106 3116
3107 if (!access_valid(od->od_share_access) 3117 if (!access_valid(od->od_share_access, cstate->minorversion)
3108 || !deny_valid(od->od_share_deny)) 3118 || !deny_valid(od->od_share_deny))
3109 return nfserr_inval; 3119 return nfserr_inval;
3110 3120