aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/idmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r--fs/nfs/idmap.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 864c51e4b400..b701358c39c3 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -52,8 +52,6 @@
52 52
53#define NFS_UINT_MAXLEN 11 53#define NFS_UINT_MAXLEN 11
54 54
55/* Default cache timeout is 10 minutes */
56unsigned int nfs_idmap_cache_timeout = 600;
57static const struct cred *id_resolver_cache; 55static const struct cred *id_resolver_cache;
58static struct key_type key_type_id_resolver_legacy; 56static struct key_type key_type_id_resolver_legacy;
59 57
@@ -205,12 +203,18 @@ static int nfs_idmap_init_keyring(void)
205 if (ret < 0) 203 if (ret < 0)
206 goto failed_put_key; 204 goto failed_put_key;
207 205
206 ret = register_key_type(&key_type_id_resolver_legacy);
207 if (ret < 0)
208 goto failed_reg_legacy;
209
208 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); 210 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
209 cred->thread_keyring = keyring; 211 cred->thread_keyring = keyring;
210 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 212 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
211 id_resolver_cache = cred; 213 id_resolver_cache = cred;
212 return 0; 214 return 0;
213 215
216failed_reg_legacy:
217 unregister_key_type(&key_type_id_resolver);
214failed_put_key: 218failed_put_key:
215 key_put(keyring); 219 key_put(keyring);
216failed_put_cred: 220failed_put_cred:
@@ -222,6 +226,7 @@ static void nfs_idmap_quit_keyring(void)
222{ 226{
223 key_revoke(id_resolver_cache->thread_keyring); 227 key_revoke(id_resolver_cache->thread_keyring);
224 unregister_key_type(&key_type_id_resolver); 228 unregister_key_type(&key_type_id_resolver);
229 unregister_key_type(&key_type_id_resolver_legacy);
225 put_cred(id_resolver_cache); 230 put_cred(id_resolver_cache);
226} 231}
227 232
@@ -359,7 +364,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
359} 364}
360 365
361/* idmap classic begins here */ 366/* idmap classic begins here */
362module_param(nfs_idmap_cache_timeout, int, 0644);
363 367
364enum { 368enum {
365 Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err 369 Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err
@@ -385,7 +389,7 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {
385}; 389};
386 390
387static struct key_type key_type_id_resolver_legacy = { 391static struct key_type key_type_id_resolver_legacy = {
388 .name = "id_resolver", 392 .name = "id_legacy",
389 .instantiate = user_instantiate, 393 .instantiate = user_instantiate,
390 .match = user_match, 394 .match = user_match,
391 .revoke = user_revoke, 395 .revoke = user_revoke,
@@ -674,6 +678,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
674 if (ret < 0) 678 if (ret < 0)
675 goto out2; 679 goto out2;
676 680
681 BUG_ON(idmap->idmap_key_cons != NULL);
677 idmap->idmap_key_cons = cons; 682 idmap->idmap_key_cons = cons;
678 683
679 ret = rpc_queue_upcall(idmap->idmap_pipe, msg); 684 ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
@@ -687,8 +692,7 @@ out2:
687out1: 692out1:
688 kfree(msg); 693 kfree(msg);
689out0: 694out0:
690 key_revoke(cons->key); 695 complete_request_key(cons, ret);
691 key_revoke(cons->authkey);
692 return ret; 696 return ret;
693} 697}
694 698
@@ -722,11 +726,18 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
722{ 726{
723 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); 727 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
724 struct idmap *idmap = (struct idmap *)rpci->private; 728 struct idmap *idmap = (struct idmap *)rpci->private;
725 struct key_construction *cons = idmap->idmap_key_cons; 729 struct key_construction *cons;
726 struct idmap_msg im; 730 struct idmap_msg im;
727 size_t namelen_in; 731 size_t namelen_in;
728 int ret; 732 int ret;
729 733
734 /* If instantiation is successful, anyone waiting for key construction
735 * will have been woken up and someone else may now have used
736 * idmap_key_cons - so after this point we may no longer touch it.
737 */
738 cons = ACCESS_ONCE(idmap->idmap_key_cons);
739 idmap->idmap_key_cons = NULL;
740
730 if (mlen != sizeof(im)) { 741 if (mlen != sizeof(im)) {
731 ret = -ENOSPC; 742 ret = -ENOSPC;
732 goto out; 743 goto out;
@@ -739,7 +750,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
739 750
740 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { 751 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
741 ret = mlen; 752 ret = mlen;
742 complete_request_key(idmap->idmap_key_cons, -ENOKEY); 753 complete_request_key(cons, -ENOKEY);
743 goto out_incomplete; 754 goto out_incomplete;
744 } 755 }
745 756
@@ -756,7 +767,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
756 } 767 }
757 768
758out: 769out:
759 complete_request_key(idmap->idmap_key_cons, ret); 770 complete_request_key(cons, ret);
760out_incomplete: 771out_incomplete:
761 return ret; 772 return ret;
762} 773}