|
@@ -205,12 +205,18 @@ static int nfs_idmap_init_keyring(void)
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
goto failed_put_key;
|
|
goto failed_put_key;
|
|
|
|
|
|
|
|
+ ret = register_key_type(&key_type_id_resolver_legacy);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ goto failed_reg_legacy;
|
|
|
|
+
|
|
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
|
|
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
|
|
cred->thread_keyring = keyring;
|
|
cred->thread_keyring = keyring;
|
|
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
|
|
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
|
|
id_resolver_cache = cred;
|
|
id_resolver_cache = cred;
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+failed_reg_legacy:
|
|
|
|
+ unregister_key_type(&key_type_id_resolver);
|
|
failed_put_key:
|
|
failed_put_key:
|
|
key_put(keyring);
|
|
key_put(keyring);
|
|
failed_put_cred:
|
|
failed_put_cred:
|
|
@@ -222,6 +228,7 @@ static void nfs_idmap_quit_keyring(void)
|
|
{
|
|
{
|
|
key_revoke(id_resolver_cache->thread_keyring);
|
|
key_revoke(id_resolver_cache->thread_keyring);
|
|
unregister_key_type(&key_type_id_resolver);
|
|
unregister_key_type(&key_type_id_resolver);
|
|
|
|
+ unregister_key_type(&key_type_id_resolver_legacy);
|
|
put_cred(id_resolver_cache);
|
|
put_cred(id_resolver_cache);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -385,7 +392,7 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {
|
|
};
|
|
};
|
|
|
|
|
|
static struct key_type key_type_id_resolver_legacy = {
|
|
static struct key_type key_type_id_resolver_legacy = {
|
|
- .name = "id_resolver",
|
|
|
|
|
|
+ .name = "id_legacy",
|
|
.instantiate = user_instantiate,
|
|
.instantiate = user_instantiate,
|
|
.match = user_match,
|
|
.match = user_match,
|
|
.revoke = user_revoke,
|
|
.revoke = user_revoke,
|
|
@@ -674,6 +681,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
goto out2;
|
|
goto out2;
|
|
|
|
|
|
|
|
+ BUG_ON(idmap->idmap_key_cons != NULL);
|
|
idmap->idmap_key_cons = cons;
|
|
idmap->idmap_key_cons = cons;
|
|
|
|
|
|
ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
|
|
ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
|
|
@@ -687,8 +695,7 @@ out2:
|
|
out1:
|
|
out1:
|
|
kfree(msg);
|
|
kfree(msg);
|
|
out0:
|
|
out0:
|
|
- key_revoke(cons->key);
|
|
|
|
- key_revoke(cons->authkey);
|
|
|
|
|
|
+ complete_request_key(cons, ret);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -722,11 +729,18 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
|
{
|
|
{
|
|
struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
|
|
struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
|
|
struct idmap *idmap = (struct idmap *)rpci->private;
|
|
struct idmap *idmap = (struct idmap *)rpci->private;
|
|
- struct key_construction *cons = idmap->idmap_key_cons;
|
|
|
|
|
|
+ struct key_construction *cons;
|
|
struct idmap_msg im;
|
|
struct idmap_msg im;
|
|
size_t namelen_in;
|
|
size_t namelen_in;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
+ /* If instantiation is successful, anyone waiting for key construction
|
|
|
|
+ * will have been woken up and someone else may now have used
|
|
|
|
+ * idmap_key_cons - so after this point we may no longer touch it.
|
|
|
|
+ */
|
|
|
|
+ cons = ACCESS_ONCE(idmap->idmap_key_cons);
|
|
|
|
+ idmap->idmap_key_cons = NULL;
|
|
|
|
+
|
|
if (mlen != sizeof(im)) {
|
|
if (mlen != sizeof(im)) {
|
|
ret = -ENOSPC;
|
|
ret = -ENOSPC;
|
|
goto out;
|
|
goto out;
|
|
@@ -739,7 +753,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
|
|
|
|
|
if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
|
|
if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
|
|
ret = mlen;
|
|
ret = mlen;
|
|
- complete_request_key(idmap->idmap_key_cons, -ENOKEY);
|
|
|
|
|
|
+ complete_request_key(cons, -ENOKEY);
|
|
goto out_incomplete;
|
|
goto out_incomplete;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -756,7 +770,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
|
}
|
|
}
|
|
|
|
|
|
out:
|
|
out:
|
|
- complete_request_key(idmap->idmap_key_cons, ret);
|
|
|
|
|
|
+ complete_request_key(cons, ret);
|
|
out_incomplete:
|
|
out_incomplete:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|