diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-02-01 12:18:36 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-02-01 12:52:23 -0500 |
commit | 8a3177604b729ec3b80e43790ee978863ac7551b (patch) | |
tree | 6eeafbdae55e2b0821e524f2c16bca52fa150cdc /net/sunrpc/auth.c | |
parent | aaaa99423b4b1f9cfd33ea5643d9274c25f62491 (diff) |
SUNRPC: Fix a lock recursion in the auth_gss downcall
When we look up a new cred in the auth_gss downcall so that we can stuff
the credcache, we do not want that lookup to queue up an upcall in order
to initialise it. To do an upcall here not only redundant, but since we
are already holding the inode->i_mutex, it will trigger a lock recursion.
This patch allows rpcauth cache searches to indicate that they can cope
with uninitialised credentials.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/auth.c')
-rw-r--r-- | net/sunrpc/auth.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 9ac1b8c26c01..1ca89c36da7a 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -184,7 +184,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free) | |||
184 | */ | 184 | */ |
185 | struct rpc_cred * | 185 | struct rpc_cred * |
186 | rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, | 186 | rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, |
187 | int taskflags) | 187 | int flags) |
188 | { | 188 | { |
189 | struct rpc_cred_cache *cache = auth->au_credcache; | 189 | struct rpc_cred_cache *cache = auth->au_credcache; |
190 | HLIST_HEAD(free); | 190 | HLIST_HEAD(free); |
@@ -193,7 +193,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, | |||
193 | *cred = NULL; | 193 | *cred = NULL; |
194 | int nr = 0; | 194 | int nr = 0; |
195 | 195 | ||
196 | if (!(taskflags & RPC_TASK_ROOTCREDS)) | 196 | if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) |
197 | nr = acred->uid & RPC_CREDCACHE_MASK; | 197 | nr = acred->uid & RPC_CREDCACHE_MASK; |
198 | retry: | 198 | retry: |
199 | spin_lock(&rpc_credcache_lock); | 199 | spin_lock(&rpc_credcache_lock); |
@@ -202,7 +202,7 @@ retry: | |||
202 | hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { | 202 | hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { |
203 | struct rpc_cred *entry; | 203 | struct rpc_cred *entry; |
204 | entry = hlist_entry(pos, struct rpc_cred, cr_hash); | 204 | entry = hlist_entry(pos, struct rpc_cred, cr_hash); |
205 | if (entry->cr_ops->crmatch(acred, entry, taskflags)) { | 205 | if (entry->cr_ops->crmatch(acred, entry, flags)) { |
206 | hlist_del(&entry->cr_hash); | 206 | hlist_del(&entry->cr_hash); |
207 | cred = entry; | 207 | cred = entry; |
208 | break; | 208 | break; |
@@ -224,7 +224,7 @@ retry: | |||
224 | rpcauth_destroy_credlist(&free); | 224 | rpcauth_destroy_credlist(&free); |
225 | 225 | ||
226 | if (!cred) { | 226 | if (!cred) { |
227 | new = auth->au_ops->crcreate(auth, acred, taskflags); | 227 | new = auth->au_ops->crcreate(auth, acred, flags); |
228 | if (!IS_ERR(new)) { | 228 | if (!IS_ERR(new)) { |
229 | #ifdef RPC_DEBUG | 229 | #ifdef RPC_DEBUG |
230 | new->cr_magic = RPCAUTH_CRED_MAGIC; | 230 | new->cr_magic = RPCAUTH_CRED_MAGIC; |
@@ -238,7 +238,7 @@ retry: | |||
238 | } | 238 | } |
239 | 239 | ||
240 | struct rpc_cred * | 240 | struct rpc_cred * |
241 | rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) | 241 | rpcauth_lookupcred(struct rpc_auth *auth, int flags) |
242 | { | 242 | { |
243 | struct auth_cred acred = { | 243 | struct auth_cred acred = { |
244 | .uid = current->fsuid, | 244 | .uid = current->fsuid, |
@@ -250,7 +250,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) | |||
250 | dprintk("RPC: looking up %s cred\n", | 250 | dprintk("RPC: looking up %s cred\n", |
251 | auth->au_ops->au_name); | 251 | auth->au_ops->au_name); |
252 | get_group_info(acred.group_info); | 252 | get_group_info(acred.group_info); |
253 | ret = auth->au_ops->lookup_cred(auth, &acred, taskflags); | 253 | ret = auth->au_ops->lookup_cred(auth, &acred, flags); |
254 | put_group_info(acred.group_info); | 254 | put_group_info(acred.group_info); |
255 | return ret; | 255 | return ret; |
256 | } | 256 | } |
@@ -265,11 +265,14 @@ rpcauth_bindcred(struct rpc_task *task) | |||
265 | .group_info = current->group_info, | 265 | .group_info = current->group_info, |
266 | }; | 266 | }; |
267 | struct rpc_cred *ret; | 267 | struct rpc_cred *ret; |
268 | int flags = 0; | ||
268 | 269 | ||
269 | dprintk("RPC: %4d looking up %s cred\n", | 270 | dprintk("RPC: %4d looking up %s cred\n", |
270 | task->tk_pid, task->tk_auth->au_ops->au_name); | 271 | task->tk_pid, task->tk_auth->au_ops->au_name); |
271 | get_group_info(acred.group_info); | 272 | get_group_info(acred.group_info); |
272 | ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags); | 273 | if (task->tk_flags & RPC_TASK_ROOTCREDS) |
274 | flags |= RPCAUTH_LOOKUP_ROOTCREDS; | ||
275 | ret = auth->au_ops->lookup_cred(auth, &acred, flags); | ||
273 | if (!IS_ERR(ret)) | 276 | if (!IS_ERR(ret)) |
274 | task->tk_msg.rpc_cred = ret; | 277 | task->tk_msg.rpc_cred = ret; |
275 | else | 278 | else |