diff options
author | Weston Andros Adamson <dros@netapp.com> | 2012-09-10 14:00:46 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-10-01 18:20:11 -0400 |
commit | 6168f62cbde8dcf4f58255794efbcdb8df603959 (patch) | |
tree | 897bac0b7539172aa171365337d964f7984b1a80 /fs/nfs/nfs4xdr.c | |
parent | 57a51048da742c764b6ce5d028c7f334ae04d363 (diff) |
NFSv4: Add ACCESS operation to OPEN compound
The OPEN operation has no way to differentiate an open for read and an
open for execution - both look like read to the server. This allowed
users to read files that didn't have READ access but did have EXEC access,
which is obviously wrong.
This patch adds an ACCESS call to the OPEN compound to handle the
difference between OPENs for reading and execution. Since we're going
through the trouble of calling ACCESS, we check all possible access bits
and cache the results hopefully avoiding an ACCESS call in the future.
Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 7ab29abb3160..657483c34e28 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -447,12 +447,14 @@ static int nfs4_stat_to_errno(int); | |||
447 | encode_sequence_maxsz + \ | 447 | encode_sequence_maxsz + \ |
448 | encode_putfh_maxsz + \ | 448 | encode_putfh_maxsz + \ |
449 | encode_open_maxsz + \ | 449 | encode_open_maxsz + \ |
450 | encode_access_maxsz + \ | ||
450 | encode_getfh_maxsz + \ | 451 | encode_getfh_maxsz + \ |
451 | encode_getattr_maxsz) | 452 | encode_getattr_maxsz) |
452 | #define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ | 453 | #define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ |
453 | decode_sequence_maxsz + \ | 454 | decode_sequence_maxsz + \ |
454 | decode_putfh_maxsz + \ | 455 | decode_putfh_maxsz + \ |
455 | decode_open_maxsz + \ | 456 | decode_open_maxsz + \ |
457 | decode_access_maxsz + \ | ||
456 | decode_getfh_maxsz + \ | 458 | decode_getfh_maxsz + \ |
457 | decode_getattr_maxsz) | 459 | decode_getattr_maxsz) |
458 | #define NFS4_enc_open_confirm_sz \ | 460 | #define NFS4_enc_open_confirm_sz \ |
@@ -467,11 +469,13 @@ static int nfs4_stat_to_errno(int); | |||
467 | encode_sequence_maxsz + \ | 469 | encode_sequence_maxsz + \ |
468 | encode_putfh_maxsz + \ | 470 | encode_putfh_maxsz + \ |
469 | encode_open_maxsz + \ | 471 | encode_open_maxsz + \ |
472 | encode_access_maxsz + \ | ||
470 | encode_getattr_maxsz) | 473 | encode_getattr_maxsz) |
471 | #define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ | 474 | #define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ |
472 | decode_sequence_maxsz + \ | 475 | decode_sequence_maxsz + \ |
473 | decode_putfh_maxsz + \ | 476 | decode_putfh_maxsz + \ |
474 | decode_open_maxsz + \ | 477 | decode_open_maxsz + \ |
478 | decode_access_maxsz + \ | ||
475 | decode_getattr_maxsz) | 479 | decode_getattr_maxsz) |
476 | #define NFS4_enc_open_downgrade_sz \ | 480 | #define NFS4_enc_open_downgrade_sz \ |
477 | (compound_encode_hdr_maxsz + \ | 481 | (compound_encode_hdr_maxsz + \ |
@@ -2220,6 +2224,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
2220 | encode_putfh(xdr, args->fh, &hdr); | 2224 | encode_putfh(xdr, args->fh, &hdr); |
2221 | encode_open(xdr, args, &hdr); | 2225 | encode_open(xdr, args, &hdr); |
2222 | encode_getfh(xdr, &hdr); | 2226 | encode_getfh(xdr, &hdr); |
2227 | encode_access(xdr, args->access, &hdr); | ||
2223 | encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); | 2228 | encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); |
2224 | encode_nops(&hdr); | 2229 | encode_nops(&hdr); |
2225 | } | 2230 | } |
@@ -2256,6 +2261,7 @@ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, | |||
2256 | encode_sequence(xdr, &args->seq_args, &hdr); | 2261 | encode_sequence(xdr, &args->seq_args, &hdr); |
2257 | encode_putfh(xdr, args->fh, &hdr); | 2262 | encode_putfh(xdr, args->fh, &hdr); |
2258 | encode_open(xdr, args, &hdr); | 2263 | encode_open(xdr, args, &hdr); |
2264 | encode_access(xdr, args->access, &hdr); | ||
2259 | encode_getfattr(xdr, args->bitmask, &hdr); | 2265 | encode_getfattr(xdr, args->bitmask, &hdr); |
2260 | encode_nops(&hdr); | 2266 | encode_nops(&hdr); |
2261 | } | 2267 | } |
@@ -4099,7 +4105,7 @@ out_overflow: | |||
4099 | return -EIO; | 4105 | return -EIO; |
4100 | } | 4106 | } |
4101 | 4107 | ||
4102 | static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) | 4108 | static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) |
4103 | { | 4109 | { |
4104 | __be32 *p; | 4110 | __be32 *p; |
4105 | uint32_t supp, acc; | 4111 | uint32_t supp, acc; |
@@ -4113,8 +4119,8 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) | |||
4113 | goto out_overflow; | 4119 | goto out_overflow; |
4114 | supp = be32_to_cpup(p++); | 4120 | supp = be32_to_cpup(p++); |
4115 | acc = be32_to_cpup(p); | 4121 | acc = be32_to_cpup(p); |
4116 | access->supported = supp; | 4122 | *supported = supp; |
4117 | access->access = acc; | 4123 | *access = acc; |
4118 | return 0; | 4124 | return 0; |
4119 | out_overflow: | 4125 | out_overflow: |
4120 | print_overflow_msg(__func__, xdr); | 4126 | print_overflow_msg(__func__, xdr); |
@@ -5892,7 +5898,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5892 | status = decode_putfh(xdr); | 5898 | status = decode_putfh(xdr); |
5893 | if (status != 0) | 5899 | if (status != 0) |
5894 | goto out; | 5900 | goto out; |
5895 | status = decode_access(xdr, res); | 5901 | status = decode_access(xdr, &res->supported, &res->access); |
5896 | if (status != 0) | 5902 | if (status != 0) |
5897 | goto out; | 5903 | goto out; |
5898 | decode_getfattr(xdr, res->fattr, res->server); | 5904 | decode_getfattr(xdr, res->fattr, res->server); |
@@ -6233,6 +6239,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6233 | status = decode_getfh(xdr, &res->fh); | 6239 | status = decode_getfh(xdr, &res->fh); |
6234 | if (status) | 6240 | if (status) |
6235 | goto out; | 6241 | goto out; |
6242 | decode_access(xdr, &res->access_supported, &res->access_result); | ||
6236 | decode_getfattr(xdr, res->f_attr, res->server); | 6243 | decode_getfattr(xdr, res->f_attr, res->server); |
6237 | out: | 6244 | out: |
6238 | return status; | 6245 | return status; |
@@ -6281,6 +6288,7 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, | |||
6281 | status = decode_open(xdr, res); | 6288 | status = decode_open(xdr, res); |
6282 | if (status) | 6289 | if (status) |
6283 | goto out; | 6290 | goto out; |
6291 | decode_access(xdr, &res->access_supported, &res->access_result); | ||
6284 | decode_getfattr(xdr, res->f_attr, res->server); | 6292 | decode_getfattr(xdr, res->f_attr, res->server); |
6285 | out: | 6293 | out: |
6286 | return status; | 6294 | return status; |