aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-02-01 12:18:36 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-02-01 12:52:23 -0500
commit8a3177604b729ec3b80e43790ee978863ac7551b (patch)
tree6eeafbdae55e2b0821e524f2c16bca52fa150cdc /net/sunrpc/auth.c
parentaaaa99423b4b1f9cfd33ea5643d9274c25f62491 (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.c17
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 */
185struct rpc_cred * 185struct rpc_cred *
186rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, 186rpcauth_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;
198retry: 198retry:
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
240struct rpc_cred * 240struct rpc_cred *
241rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) 241rpcauth_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