diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-01 09:22:32 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 15:24:52 -0400 |
commit | 8d35301d7db4165f2430c428865f7b0add47615d (patch) | |
tree | a808476a2b38ae440dd66634f776dcd334c13d77 | |
parent | fc931582c260e53ca5ca23bd70ccc9b2265cca9f (diff) |
nfs41: verify session channel attribues
Invalidate the session if the server returns invalid fore or back channel
attributes.
Use a KERN_WARNING to report the fatal session estabishment error.
Signed-off-by: Andy Adamson <andros@netapp.com>
[refactor nfs4_verify_channel_attrs]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7d81d6e57533..4d7a8b9e1291 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -4409,6 +4409,51 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) | |||
4409 | args->bc_attrs.max_reqs); | 4409 | args->bc_attrs.max_reqs); |
4410 | } | 4410 | } |
4411 | 4411 | ||
4412 | static int _verify_channel_attr(char *chan, char *attr_name, u32 sent, u32 rcvd) | ||
4413 | { | ||
4414 | if (rcvd <= sent) | ||
4415 | return 0; | ||
4416 | printk(KERN_WARNING "%s: Session INVALID: %s channel %s increased. " | ||
4417 | "sent=%u rcvd=%u\n", __func__, chan, attr_name, sent, rcvd); | ||
4418 | return -EINVAL; | ||
4419 | } | ||
4420 | |||
4421 | #define _verify_fore_channel_attr(_name_) \ | ||
4422 | _verify_channel_attr("fore", #_name_, \ | ||
4423 | args->fc_attrs._name_, \ | ||
4424 | session->fc_attrs._name_) | ||
4425 | |||
4426 | #define _verify_back_channel_attr(_name_) \ | ||
4427 | _verify_channel_attr("back", #_name_, \ | ||
4428 | args->bc_attrs._name_, \ | ||
4429 | session->bc_attrs._name_) | ||
4430 | |||
4431 | /* | ||
4432 | * The server is not allowed to increase the fore channel header pad size, | ||
4433 | * maximum response size, or maximum number of operations. | ||
4434 | * | ||
4435 | * The back channel attributes are only negotiatied down: We send what the | ||
4436 | * (back channel) server insists upon. | ||
4437 | */ | ||
4438 | static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args, | ||
4439 | struct nfs4_session *session) | ||
4440 | { | ||
4441 | int ret = 0; | ||
4442 | |||
4443 | ret |= _verify_fore_channel_attr(headerpadsz); | ||
4444 | ret |= _verify_fore_channel_attr(max_resp_sz); | ||
4445 | ret |= _verify_fore_channel_attr(max_ops); | ||
4446 | |||
4447 | ret |= _verify_back_channel_attr(headerpadsz); | ||
4448 | ret |= _verify_back_channel_attr(max_rqst_sz); | ||
4449 | ret |= _verify_back_channel_attr(max_resp_sz); | ||
4450 | ret |= _verify_back_channel_attr(max_resp_sz_cached); | ||
4451 | ret |= _verify_back_channel_attr(max_ops); | ||
4452 | ret |= _verify_back_channel_attr(max_reqs); | ||
4453 | |||
4454 | return ret; | ||
4455 | } | ||
4456 | |||
4412 | static int _nfs4_proc_create_session(struct nfs_client *clp) | 4457 | static int _nfs4_proc_create_session(struct nfs_client *clp) |
4413 | { | 4458 | { |
4414 | struct nfs4_session *session = clp->cl_session; | 4459 | struct nfs4_session *session = clp->cl_session; |
@@ -4431,8 +4476,9 @@ static int _nfs4_proc_create_session(struct nfs_client *clp) | |||
4431 | 4476 | ||
4432 | status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0); | 4477 | status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0); |
4433 | 4478 | ||
4434 | /* Set the negotiated values in the session's channel_attrs struct */ | 4479 | if (!status) |
4435 | 4480 | /* Verify the session's negotiated channel_attrs values */ | |
4481 | status = nfs4_verify_channel_attrs(&args, session); | ||
4436 | if (!status) { | 4482 | if (!status) { |
4437 | /* Increment the clientid slot sequence id */ | 4483 | /* Increment the clientid slot sequence id */ |
4438 | clp->cl_seqid++; | 4484 | clp->cl_seqid++; |