diff options
author | J. Bruce Fields <bfields@redhat.com> | 2010-09-12 19:55:25 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-09-12 19:55:25 -0400 |
commit | f2d47d02fd84343a3c5452daca6ed12c75618aff (patch) | |
tree | 7f7e70c78070021d28e319bc1124cea283ec1e84 /net | |
parent | 49553c2ef88749dd502687f4eb9c258bb10a4f44 (diff) |
Fix null dereference in call_allocate
In call_allocate we need to reach the auth in order to factor au_cslack
into the allocation.
As of a17c2153d2e271b0cbacae9bed83b0eaa41db7e1 "SUNRPC: Move the bound
cred to struct rpc_rqst", call_allocate attempts to do this by
dereferencing tk_client->cl_auth, however this is not guaranteed to be
defined--cl_auth can be zero in the case of gss context destruction (see
rpc_free_auth).
Reorder the client state machine to bind credentials before allocating,
so that we can instead reach the auth through the cred.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/clnt.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 2388d83b68ff..657aac630fc9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -931,7 +931,7 @@ call_reserveresult(struct rpc_task *task) | |||
931 | task->tk_status = 0; | 931 | task->tk_status = 0; |
932 | if (status >= 0) { | 932 | if (status >= 0) { |
933 | if (task->tk_rqstp) { | 933 | if (task->tk_rqstp) { |
934 | task->tk_action = call_allocate; | 934 | task->tk_action = call_refresh; |
935 | return; | 935 | return; |
936 | } | 936 | } |
937 | 937 | ||
@@ -972,7 +972,7 @@ call_reserveresult(struct rpc_task *task) | |||
972 | static void | 972 | static void |
973 | call_allocate(struct rpc_task *task) | 973 | call_allocate(struct rpc_task *task) |
974 | { | 974 | { |
975 | unsigned int slack = task->tk_client->cl_auth->au_cslack; | 975 | unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; |
976 | struct rpc_rqst *req = task->tk_rqstp; | 976 | struct rpc_rqst *req = task->tk_rqstp; |
977 | struct rpc_xprt *xprt = task->tk_xprt; | 977 | struct rpc_xprt *xprt = task->tk_xprt; |
978 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; | 978 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
@@ -980,7 +980,7 @@ call_allocate(struct rpc_task *task) | |||
980 | dprint_status(task); | 980 | dprint_status(task); |
981 | 981 | ||
982 | task->tk_status = 0; | 982 | task->tk_status = 0; |
983 | task->tk_action = call_refresh; | 983 | task->tk_action = call_bind; |
984 | 984 | ||
985 | if (req->rq_buffer) | 985 | if (req->rq_buffer) |
986 | return; | 986 | return; |
@@ -1042,7 +1042,7 @@ call_refreshresult(struct rpc_task *task) | |||
1042 | dprint_status(task); | 1042 | dprint_status(task); |
1043 | 1043 | ||
1044 | task->tk_status = 0; | 1044 | task->tk_status = 0; |
1045 | task->tk_action = call_bind; | 1045 | task->tk_action = call_allocate; |
1046 | if (status >= 0 && rpcauth_uptodatecred(task)) | 1046 | if (status >= 0 && rpcauth_uptodatecred(task)) |
1047 | return; | 1047 | return; |
1048 | switch (status) { | 1048 | switch (status) { |