CRED: Fix prepare_kernel_cred() to provide a new thread_group_cred struct
Fix prepare_kernel_cred() to provide a new, separate thread_group_cred struct otherwise when using request_key() ____call_usermodehelper() calls umh_keys_init() with the new creds pointing to init_tgcred, which umh_keys_init() then blithely alters. The problem can be demonstrated by: # keyctl request2 user a debug:a @s 249681132 # grep req /proc/keys 079906a5 I--Q-- 1 perm 1f3f0000 0 0 keyring _req.249681132: 1/4 38ef1626 IR---- 1 expd 0b010000 0 0 .request_ key:ee1d4ec pid:4371 ci:1 The keyring _req.XXXX should have gone away, but something (init_tgcred) is pinning it. That key actually requested can then be removed and a new one created: # keyctl unlink 249681132 1 links removed [root@andromeda ~]# grep req /proc/keys 116cecac IR---- 1 expd 0b010000 0 0 .request_ key:eeb4911 pid:4379 ci:1 36d1cbf8 I--Q-- 1 perm 1f3f0000 0 0 keyring _req.250300689: 1/4 which causes the old _req keyring to go away and a new one to take its place. This is a consequence of the changes in: commit879669961b
Author: David Howells <dhowells@redhat.com> Date: Fri Jun 17 11:25:59 2011 +0100 KEYS/DNS: Fix ____call_usermodehelper() to not lose the session keyring and: commit17f60a7da1
Author: Eric Paris <eparis@redhat.com> Date: Fri Apr 1 17:07:50 2011 -0400 capabilites: allow the application of capability limits to usermode helpers After this patch is applied, the _req keyring and the .request_key key are cleaned up. Signed-off-by: David Howells <dhowells@redhat.com> cc: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
6d528b0822
commit
012146d072
|
@ -646,6 +646,9 @@ void __init cred_init(void)
|
||||||
*/
|
*/
|
||||||
struct cred *prepare_kernel_cred(struct task_struct *daemon)
|
struct cred *prepare_kernel_cred(struct task_struct *daemon)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_KEYS
|
||||||
|
struct thread_group_cred *tgcred;
|
||||||
|
#endif
|
||||||
const struct cred *old;
|
const struct cred *old;
|
||||||
struct cred *new;
|
struct cred *new;
|
||||||
|
|
||||||
|
@ -653,6 +656,12 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
|
||||||
if (!new)
|
if (!new)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
|
||||||
|
if (!tgcred) {
|
||||||
|
kmem_cache_free(cred_jar, new);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
kdebug("prepare_kernel_cred() alloc %p", new);
|
kdebug("prepare_kernel_cred() alloc %p", new);
|
||||||
|
|
||||||
if (daemon)
|
if (daemon)
|
||||||
|
@ -669,8 +678,11 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
|
||||||
get_group_info(new->group_info);
|
get_group_info(new->group_info);
|
||||||
|
|
||||||
#ifdef CONFIG_KEYS
|
#ifdef CONFIG_KEYS
|
||||||
atomic_inc(&init_tgcred.usage);
|
atomic_set(&tgcred->usage, 1);
|
||||||
new->tgcred = &init_tgcred;
|
spin_lock_init(&tgcred->lock);
|
||||||
|
tgcred->process_keyring = NULL;
|
||||||
|
tgcred->session_keyring = NULL;
|
||||||
|
new->tgcred = tgcred;
|
||||||
new->request_key_auth = NULL;
|
new->request_key_auth = NULL;
|
||||||
new->thread_keyring = NULL;
|
new->thread_keyring = NULL;
|
||||||
new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
|
new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
|
||||||
|
|
Loading…
Reference in New Issue