aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:20 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:20 -0500
commitbb952bb98a7e479262c7eb25d5592545a3af147d (patch)
tree9a2158c07a22a5fbddcec412944d2e7534eecc8f
parent275bb41e9d058fbb327e7642f077e1beaeac162e (diff)
CRED: Separate per-task-group keyrings from signal_struct
Separate per-task-group keyrings from signal_struct and dangle their anchor from the cred struct rather than the signal_struct. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: James Morris <jmorris@namei.org> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--include/linux/cred.h16
-rw-r--r--include/linux/key.h8
-rw-r--r--include/linux/sched.h6
-rw-r--r--kernel/cred.c63
-rw-r--r--kernel/fork.c7
-rw-r--r--security/keys/process_keys.c100
-rw-r--r--security/keys/request_key.c34
7 files changed, 135 insertions, 99 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 166ce4ddba64..62b9e532422d 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -72,6 +72,21 @@ extern int in_group_p(gid_t);
72extern int in_egroup_p(gid_t); 72extern int in_egroup_p(gid_t);
73 73
74/* 74/*
75 * The common credentials for a thread group
76 * - shared by CLONE_THREAD
77 */
78#ifdef CONFIG_KEYS
79struct thread_group_cred {
80 atomic_t usage;
81 pid_t tgid; /* thread group process ID */
82 spinlock_t lock;
83 struct key *session_keyring; /* keyring inherited over fork */
84 struct key *process_keyring; /* keyring private to this process */
85 struct rcu_head rcu; /* RCU deletion hook */
86};
87#endif
88
89/*
75 * The security context of a task 90 * The security context of a task
76 * 91 *
77 * The parts of the context break down into two categories: 92 * The parts of the context break down into two categories:
@@ -114,6 +129,7 @@ struct cred {
114 * keys to */ 129 * keys to */
115 struct key *thread_keyring; /* keyring private to this thread */ 130 struct key *thread_keyring; /* keyring private to this thread */
116 struct key *request_key_auth; /* assumed request_key authority */ 131 struct key *request_key_auth; /* assumed request_key authority */
132 struct thread_group_cred *tgcred; /* thread-group shared credentials */
117#endif 133#endif
118#ifdef CONFIG_SECURITY 134#ifdef CONFIG_SECURITY
119 void *security; /* subjective LSM security */ 135 void *security; /* subjective LSM security */
diff --git a/include/linux/key.h b/include/linux/key.h
index df709e1af3cd..0836cc838b0c 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -278,9 +278,7 @@ extern ctl_table key_sysctls[];
278 */ 278 */
279extern void switch_uid_keyring(struct user_struct *new_user); 279extern void switch_uid_keyring(struct user_struct *new_user);
280extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk); 280extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk);
281extern int copy_thread_group_keys(struct task_struct *tsk);
282extern void exit_keys(struct task_struct *tsk); 281extern void exit_keys(struct task_struct *tsk);
283extern void exit_thread_group_keys(struct signal_struct *tg);
284extern int suid_keys(struct task_struct *tsk); 282extern int suid_keys(struct task_struct *tsk);
285extern int exec_keys(struct task_struct *tsk); 283extern int exec_keys(struct task_struct *tsk);
286extern void key_fsuid_changed(struct task_struct *tsk); 284extern void key_fsuid_changed(struct task_struct *tsk);
@@ -289,8 +287,8 @@ extern void key_init(void);
289 287
290#define __install_session_keyring(keyring) \ 288#define __install_session_keyring(keyring) \
291({ \ 289({ \
292 struct key *old_session = current->signal->session_keyring; \ 290 struct key *old_session = current->cred->tgcred->session_keyring; \
293 current->signal->session_keyring = keyring; \ 291 current->cred->tgcred->session_keyring = keyring; \
294 old_session; \ 292 old_session; \
295}) 293})
296 294
@@ -308,9 +306,7 @@ extern void key_init(void);
308#define switch_uid_keyring(u) do { } while(0) 306#define switch_uid_keyring(u) do { } while(0)
309#define __install_session_keyring(k) ({ NULL; }) 307#define __install_session_keyring(k) ({ NULL; })
310#define copy_keys(f,t) 0 308#define copy_keys(f,t) 0
311#define copy_thread_group_keys(t) 0
312#define exit_keys(t) do { } while(0) 309#define exit_keys(t) do { } while(0)
313#define exit_thread_group_keys(tg) do { } while(0)
314#define suid_keys(t) do { } while(0) 310#define suid_keys(t) do { } while(0)
315#define exec_keys(t) do { } while(0) 311#define exec_keys(t) do { } while(0)
316#define key_fsuid_changed(t) do { } while(0) 312#define key_fsuid_changed(t) do { } while(0)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 740cf946c8cc..2913252989b3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -571,12 +571,6 @@ struct signal_struct {
571 */ 571 */
572 struct rlimit rlim[RLIM_NLIMITS]; 572 struct rlimit rlim[RLIM_NLIMITS];
573 573
574 /* keep the process-shared keyrings here so that they do the right
575 * thing in threads created with CLONE_THREAD */
576#ifdef CONFIG_KEYS
577 struct key *session_keyring; /* keyring inherited over fork */
578 struct key *process_keyring; /* keyring private to this process */
579#endif
580#ifdef CONFIG_BSD_PROCESS_ACCT 574#ifdef CONFIG_BSD_PROCESS_ACCT
581 struct pacct_struct pacct; /* per-process accounting information */ 575 struct pacct_struct pacct; /* per-process accounting information */
582#endif 576#endif
diff --git a/kernel/cred.c b/kernel/cred.c
index 833244a7cb05..ac73e3617684 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -17,6 +17,17 @@
17#include <linux/security.h> 17#include <linux/security.h>
18 18
19/* 19/*
20 * The common credentials for the initial task's thread group
21 */
22#ifdef CONFIG_KEYS
23static struct thread_group_cred init_tgcred = {
24 .usage = ATOMIC_INIT(2),
25 .tgid = 0,
26 .lock = SPIN_LOCK_UNLOCKED,
27};
28#endif
29
30/*
20 * The initial credentials for the initial task 31 * The initial credentials for the initial task
21 */ 32 */
22struct cred init_cred = { 33struct cred init_cred = {
@@ -28,9 +39,42 @@ struct cred init_cred = {
28 .cap_bset = CAP_INIT_BSET, 39 .cap_bset = CAP_INIT_BSET,
29 .user = INIT_USER, 40 .user = INIT_USER,
30 .group_info = &init_groups, 41 .group_info = &init_groups,
42#ifdef CONFIG_KEYS
43 .tgcred = &init_tgcred,
44#endif
31}; 45};
32 46
33/* 47/*
48 * Dispose of the shared task group credentials
49 */
50#ifdef CONFIG_KEYS
51static void release_tgcred_rcu(struct rcu_head *rcu)
52{
53 struct thread_group_cred *tgcred =
54 container_of(rcu, struct thread_group_cred, rcu);
55
56 BUG_ON(atomic_read(&tgcred->usage) != 0);
57
58 key_put(tgcred->session_keyring);
59 key_put(tgcred->process_keyring);
60 kfree(tgcred);
61}
62#endif
63
64/*
65 * Release a set of thread group credentials.
66 */
67static void release_tgcred(struct cred *cred)
68{
69#ifdef CONFIG_KEYS
70 struct thread_group_cred *tgcred = cred->tgcred;
71
72 if (atomic_dec_and_test(&tgcred->usage))
73 call_rcu(&tgcred->rcu, release_tgcred_rcu);
74#endif
75}
76
77/*
34 * The RCU callback to actually dispose of a set of credentials 78 * The RCU callback to actually dispose of a set of credentials
35 */ 79 */
36static void put_cred_rcu(struct rcu_head *rcu) 80static void put_cred_rcu(struct rcu_head *rcu)
@@ -41,6 +85,7 @@ static void put_cred_rcu(struct rcu_head *rcu)
41 85
42 key_put(cred->thread_keyring); 86 key_put(cred->thread_keyring);
43 key_put(cred->request_key_auth); 87 key_put(cred->request_key_auth);
88 release_tgcred(cred);
44 put_group_info(cred->group_info); 89 put_group_info(cred->group_info);
45 free_uid(cred->user); 90 free_uid(cred->user);
46 security_cred_free(cred); 91 security_cred_free(cred);
@@ -71,12 +116,30 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
71 if (!pcred) 116 if (!pcred)
72 return -ENOMEM; 117 return -ENOMEM;
73 118
119#ifdef CONFIG_KEYS
120 if (clone_flags & CLONE_THREAD) {
121 atomic_inc(&pcred->tgcred->usage);
122 } else {
123 pcred->tgcred = kmalloc(sizeof(struct cred), GFP_KERNEL);
124 if (!pcred->tgcred) {
125 kfree(pcred);
126 return -ENOMEM;
127 }
128 atomic_set(&pcred->tgcred->usage, 1);
129 spin_lock_init(&pcred->tgcred->lock);
130 pcred->tgcred->process_keyring = NULL;
131 pcred->tgcred->session_keyring =
132 key_get(p->cred->tgcred->session_keyring);
133 }
134#endif
135
74#ifdef CONFIG_SECURITY 136#ifdef CONFIG_SECURITY
75 pcred->security = NULL; 137 pcred->security = NULL;
76#endif 138#endif
77 139
78 ret = security_cred_alloc(pcred); 140 ret = security_cred_alloc(pcred);
79 if (ret < 0) { 141 if (ret < 0) {
142 release_tgcred(pcred);
80 kfree(pcred); 143 kfree(pcred);
81 return ret; 144 return ret;
82 } 145 }
diff --git a/kernel/fork.c b/kernel/fork.c
index c932e283ddfc..ded1972672a3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -802,12 +802,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
802 if (!sig) 802 if (!sig)
803 return -ENOMEM; 803 return -ENOMEM;
804 804
805 ret = copy_thread_group_keys(tsk);
806 if (ret < 0) {
807 kmem_cache_free(signal_cachep, sig);
808 return ret;
809 }
810
811 atomic_set(&sig->count, 1); 805 atomic_set(&sig->count, 1);
812 atomic_set(&sig->live, 1); 806 atomic_set(&sig->live, 1);
813 init_waitqueue_head(&sig->wait_chldexit); 807 init_waitqueue_head(&sig->wait_chldexit);
@@ -852,7 +846,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
852void __cleanup_signal(struct signal_struct *sig) 846void __cleanup_signal(struct signal_struct *sig)
853{ 847{
854 thread_group_cputime_free(sig); 848 thread_group_cputime_free(sig);
855 exit_thread_group_keys(sig);
856 tty_kref_put(sig->tty); 849 tty_kref_put(sig->tty);
857 kmem_cache_free(signal_cachep, sig); 850 kmem_cache_free(signal_cachep, sig);
858} 851}
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 212601ebaa46..70ee93406f30 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -189,7 +189,7 @@ int install_process_keyring(void)
189 189
190 might_sleep(); 190 might_sleep();
191 191
192 if (!tsk->signal->process_keyring) { 192 if (!tsk->cred->tgcred->process_keyring) {
193 sprintf(buf, "_pid.%u", tsk->tgid); 193 sprintf(buf, "_pid.%u", tsk->tgid);
194 194
195 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk, 195 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk,
@@ -200,12 +200,12 @@ int install_process_keyring(void)
200 } 200 }
201 201
202 /* attach keyring */ 202 /* attach keyring */
203 spin_lock_irq(&tsk->sighand->siglock); 203 spin_lock_irq(&tsk->cred->tgcred->lock);
204 if (!tsk->signal->process_keyring) { 204 if (!tsk->cred->tgcred->process_keyring) {
205 tsk->signal->process_keyring = keyring; 205 tsk->cred->tgcred->process_keyring = keyring;
206 keyring = NULL; 206 keyring = NULL;
207 } 207 }
208 spin_unlock_irq(&tsk->sighand->siglock); 208 spin_unlock_irq(&tsk->cred->tgcred->lock);
209 209
210 key_put(keyring); 210 key_put(keyring);
211 } 211 }
@@ -235,11 +235,11 @@ static int install_session_keyring(struct key *keyring)
235 sprintf(buf, "_ses.%u", tsk->tgid); 235 sprintf(buf, "_ses.%u", tsk->tgid);
236 236
237 flags = KEY_ALLOC_QUOTA_OVERRUN; 237 flags = KEY_ALLOC_QUOTA_OVERRUN;
238 if (tsk->signal->session_keyring) 238 if (tsk->cred->tgcred->session_keyring)
239 flags = KEY_ALLOC_IN_QUOTA; 239 flags = KEY_ALLOC_IN_QUOTA;
240 240
241 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk, 241 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid,
242 flags, NULL); 242 tsk, flags, NULL);
243 if (IS_ERR(keyring)) 243 if (IS_ERR(keyring))
244 return PTR_ERR(keyring); 244 return PTR_ERR(keyring);
245 } 245 }
@@ -248,10 +248,10 @@ static int install_session_keyring(struct key *keyring)
248 } 248 }
249 249
250 /* install the keyring */ 250 /* install the keyring */
251 spin_lock_irq(&tsk->sighand->siglock); 251 spin_lock_irq(&tsk->cred->tgcred->lock);
252 old = tsk->signal->session_keyring; 252 old = tsk->cred->tgcred->session_keyring;
253 rcu_assign_pointer(tsk->signal->session_keyring, keyring); 253 rcu_assign_pointer(tsk->cred->tgcred->session_keyring, keyring);
254 spin_unlock_irq(&tsk->sighand->siglock); 254 spin_unlock_irq(&tsk->cred->tgcred->lock);
255 255
256 /* we're using RCU on the pointer, but there's no point synchronising 256 /* we're using RCU on the pointer, but there's no point synchronising
257 * on it if it didn't previously point to anything */ 257 * on it if it didn't previously point to anything */
@@ -266,28 +266,6 @@ static int install_session_keyring(struct key *keyring)
266 266
267/*****************************************************************************/ 267/*****************************************************************************/
268/* 268/*
269 * copy the keys in a thread group for fork without CLONE_THREAD
270 */
271int copy_thread_group_keys(struct task_struct *tsk)
272{
273 key_check(current->thread_group->session_keyring);
274 key_check(current->thread_group->process_keyring);
275
276 /* no process keyring yet */
277 tsk->signal->process_keyring = NULL;
278
279 /* same session keyring */
280 rcu_read_lock();
281 tsk->signal->session_keyring =
282 key_get(rcu_dereference(current->signal->session_keyring));
283 rcu_read_unlock();
284
285 return 0;
286
287} /* end copy_thread_group_keys() */
288
289/*****************************************************************************/
290/*
291 * copy the keys for fork 269 * copy the keys for fork
292 */ 270 */
293int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 271int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
@@ -307,17 +285,6 @@ int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
307 285
308/*****************************************************************************/ 286/*****************************************************************************/
309/* 287/*
310 * dispose of thread group keys upon thread group destruction
311 */
312void exit_thread_group_keys(struct signal_struct *tg)
313{
314 key_put(tg->session_keyring);
315 key_put(tg->process_keyring);
316
317} /* end exit_thread_group_keys() */
318
319/*****************************************************************************/
320/*
321 * dispose of per-thread keys upon thread exit 288 * dispose of per-thread keys upon thread exit
322 */ 289 */
323void exit_keys(struct task_struct *tsk) 290void exit_keys(struct task_struct *tsk)
@@ -344,10 +311,10 @@ int exec_keys(struct task_struct *tsk)
344 key_put(old); 311 key_put(old);
345 312
346 /* discard the process keyring from a newly exec'd task */ 313 /* discard the process keyring from a newly exec'd task */
347 spin_lock_irq(&tsk->sighand->siglock); 314 spin_lock_irq(&tsk->cred->tgcred->lock);
348 old = tsk->signal->process_keyring; 315 old = tsk->cred->tgcred->process_keyring;
349 tsk->signal->process_keyring = NULL; 316 tsk->cred->tgcred->process_keyring = NULL;
350 spin_unlock_irq(&tsk->sighand->siglock); 317 spin_unlock_irq(&tsk->cred->tgcred->lock);
351 318
352 key_put(old); 319 key_put(old);
353 320
@@ -452,9 +419,9 @@ key_ref_t search_process_keyrings(struct key_type *type,
452 } 419 }
453 420
454 /* search the process keyring second */ 421 /* search the process keyring second */
455 if (context->signal->process_keyring) { 422 if (cred->tgcred->process_keyring) {
456 key_ref = keyring_search_aux( 423 key_ref = keyring_search_aux(
457 make_key_ref(context->signal->process_keyring, 1), 424 make_key_ref(cred->tgcred->process_keyring, 1),
458 context, type, description, match); 425 context, type, description, match);
459 if (!IS_ERR(key_ref)) 426 if (!IS_ERR(key_ref))
460 goto found; 427 goto found;
@@ -473,11 +440,11 @@ key_ref_t search_process_keyrings(struct key_type *type,
473 } 440 }
474 441
475 /* search the session keyring */ 442 /* search the session keyring */
476 if (context->signal->session_keyring) { 443 if (cred->tgcred->session_keyring) {
477 rcu_read_lock(); 444 rcu_read_lock();
478 key_ref = keyring_search_aux( 445 key_ref = keyring_search_aux(
479 make_key_ref(rcu_dereference( 446 make_key_ref(rcu_dereference(
480 context->signal->session_keyring), 447 cred->tgcred->session_keyring),
481 1), 448 1),
482 context, type, description, match); 449 context, type, description, match);
483 rcu_read_unlock(); 450 rcu_read_unlock();
@@ -586,11 +553,13 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
586{ 553{
587 struct request_key_auth *rka; 554 struct request_key_auth *rka;
588 struct task_struct *t = current; 555 struct task_struct *t = current;
589 struct cred *cred = current_cred(); 556 struct cred *cred;
590 struct key *key; 557 struct key *key;
591 key_ref_t key_ref, skey_ref; 558 key_ref_t key_ref, skey_ref;
592 int ret; 559 int ret;
593 560
561try_again:
562 cred = get_current_cred();
594 key_ref = ERR_PTR(-ENOKEY); 563 key_ref = ERR_PTR(-ENOKEY);
595 564
596 switch (id) { 565 switch (id) {
@@ -604,6 +573,7 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
604 key = ERR_PTR(ret); 573 key = ERR_PTR(ret);
605 goto error; 574 goto error;
606 } 575 }
576 goto reget_creds;
607 } 577 }
608 578
609 key = cred->thread_keyring; 579 key = cred->thread_keyring;
@@ -612,7 +582,7 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
612 break; 582 break;
613 583
614 case KEY_SPEC_PROCESS_KEYRING: 584 case KEY_SPEC_PROCESS_KEYRING:
615 if (!t->signal->process_keyring) { 585 if (!cred->tgcred->process_keyring) {
616 if (!create) 586 if (!create)
617 goto error; 587 goto error;
618 588
@@ -621,15 +591,16 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
621 key = ERR_PTR(ret); 591 key = ERR_PTR(ret);
622 goto error; 592 goto error;
623 } 593 }
594 goto reget_creds;
624 } 595 }
625 596
626 key = t->signal->process_keyring; 597 key = cred->tgcred->process_keyring;
627 atomic_inc(&key->usage); 598 atomic_inc(&key->usage);
628 key_ref = make_key_ref(key, 1); 599 key_ref = make_key_ref(key, 1);
629 break; 600 break;
630 601
631 case KEY_SPEC_SESSION_KEYRING: 602 case KEY_SPEC_SESSION_KEYRING:
632 if (!t->signal->session_keyring) { 603 if (!cred->tgcred->session_keyring) {
633 /* always install a session keyring upon access if one 604 /* always install a session keyring upon access if one
634 * doesn't exist yet */ 605 * doesn't exist yet */
635 ret = install_user_keyrings(); 606 ret = install_user_keyrings();
@@ -639,10 +610,11 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
639 cred->user->session_keyring); 610 cred->user->session_keyring);
640 if (ret < 0) 611 if (ret < 0)
641 goto error; 612 goto error;
613 goto reget_creds;
642 } 614 }
643 615
644 rcu_read_lock(); 616 rcu_read_lock();
645 key = rcu_dereference(t->signal->session_keyring); 617 key = rcu_dereference(cred->tgcred->session_keyring);
646 atomic_inc(&key->usage); 618 atomic_inc(&key->usage);
647 rcu_read_unlock(); 619 rcu_read_unlock();
648 key_ref = make_key_ref(key, 1); 620 key_ref = make_key_ref(key, 1);
@@ -758,6 +730,7 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
758 goto invalid_key; 730 goto invalid_key;
759 731
760error: 732error:
733 put_cred(cred);
761 return key_ref; 734 return key_ref;
762 735
763invalid_key: 736invalid_key:
@@ -765,6 +738,12 @@ invalid_key:
765 key_ref = ERR_PTR(ret); 738 key_ref = ERR_PTR(ret);
766 goto error; 739 goto error;
767 740
741 /* if we attempted to install a keyring, then it may have caused new
742 * creds to be installed */
743reget_creds:
744 put_cred(cred);
745 goto try_again;
746
768} /* end lookup_user_key() */ 747} /* end lookup_user_key() */
769 748
770/*****************************************************************************/ 749/*****************************************************************************/
@@ -777,6 +756,7 @@ invalid_key:
777long join_session_keyring(const char *name) 756long join_session_keyring(const char *name)
778{ 757{
779 struct task_struct *tsk = current; 758 struct task_struct *tsk = current;
759 struct cred *cred = current->cred;
780 struct key *keyring; 760 struct key *keyring;
781 long ret; 761 long ret;
782 762
@@ -787,7 +767,7 @@ long join_session_keyring(const char *name)
787 goto error; 767 goto error;
788 768
789 rcu_read_lock(); 769 rcu_read_lock();
790 ret = rcu_dereference(tsk->signal->session_keyring)->serial; 770 ret = rcu_dereference(cred->tgcred->session_keyring)->serial;
791 rcu_read_unlock(); 771 rcu_read_unlock();
792 goto error; 772 goto error;
793 } 773 }
@@ -799,7 +779,7 @@ long join_session_keyring(const char *name)
799 keyring = find_keyring_by_name(name, false); 779 keyring = find_keyring_by_name(name, false);
800 if (PTR_ERR(keyring) == -ENOKEY) { 780 if (PTR_ERR(keyring) == -ENOKEY) {
801 /* not found - try and create a new one */ 781 /* not found - try and create a new one */
802 keyring = keyring_alloc(name, tsk->cred->uid, tsk->cred->gid, tsk, 782 keyring = keyring_alloc(name, cred->uid, cred->gid, tsk,
803 KEY_ALLOC_IN_QUOTA, NULL); 783 KEY_ALLOC_IN_QUOTA, NULL);
804 if (IS_ERR(keyring)) { 784 if (IS_ERR(keyring)) {
805 ret = PTR_ERR(keyring); 785 ret = PTR_ERR(keyring);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 0488b0af5bd6..3d12558362df 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -66,7 +66,6 @@ static int call_sbin_request_key(struct key_construction *cons,
66 const char *op, 66 const char *op,
67 void *aux) 67 void *aux)
68{ 68{
69 struct task_struct *tsk = current;
70 const struct cred *cred = current_cred(); 69 const struct cred *cred = current_cred();
71 key_serial_t prkey, sskey; 70 key_serial_t prkey, sskey;
72 struct key *key = cons->key, *authkey = cons->authkey, *keyring; 71 struct key *key = cons->key, *authkey = cons->authkey, *keyring;
@@ -109,18 +108,13 @@ static int call_sbin_request_key(struct key_construction *cons,
109 cred->thread_keyring->serial : 0); 108 cred->thread_keyring->serial : 0);
110 109
111 prkey = 0; 110 prkey = 0;
112 if (tsk->signal->process_keyring) 111 if (cred->tgcred->process_keyring)
113 prkey = tsk->signal->process_keyring->serial; 112 prkey = cred->tgcred->process_keyring->serial;
114 113
115 sprintf(keyring_str[1], "%d", prkey); 114 if (cred->tgcred->session_keyring)
116 115 sskey = rcu_dereference(cred->tgcred->session_keyring)->serial;
117 if (tsk->signal->session_keyring) { 116 else
118 rcu_read_lock();
119 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
120 rcu_read_unlock();
121 } else {
122 sskey = cred->user->session_keyring->serial; 117 sskey = cred->user->session_keyring->serial;
123 }
124 118
125 sprintf(keyring_str[2], "%d", sskey); 119 sprintf(keyring_str[2], "%d", sskey);
126 120
@@ -222,7 +216,7 @@ static int construct_key(struct key *key, const void *callout_info,
222static void construct_get_dest_keyring(struct key **_dest_keyring) 216static void construct_get_dest_keyring(struct key **_dest_keyring)
223{ 217{
224 struct request_key_auth *rka; 218 struct request_key_auth *rka;
225 struct task_struct *tsk = current; 219 const struct cred *cred = current_cred();
226 struct key *dest_keyring = *_dest_keyring, *authkey; 220 struct key *dest_keyring = *_dest_keyring, *authkey;
227 221
228 kenter("%p", dest_keyring); 222 kenter("%p", dest_keyring);
@@ -234,11 +228,11 @@ static void construct_get_dest_keyring(struct key **_dest_keyring)
234 } else { 228 } else {
235 /* use a default keyring; falling through the cases until we 229 /* use a default keyring; falling through the cases until we
236 * find one that we actually have */ 230 * find one that we actually have */
237 switch (tsk->cred->jit_keyring) { 231 switch (cred->jit_keyring) {
238 case KEY_REQKEY_DEFL_DEFAULT: 232 case KEY_REQKEY_DEFL_DEFAULT:
239 case KEY_REQKEY_DEFL_REQUESTOR_KEYRING: 233 case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
240 if (tsk->cred->request_key_auth) { 234 if (cred->request_key_auth) {
241 authkey = tsk->cred->request_key_auth; 235 authkey = cred->request_key_auth;
242 down_read(&authkey->sem); 236 down_read(&authkey->sem);
243 rka = authkey->payload.data; 237 rka = authkey->payload.data;
244 if (!test_bit(KEY_FLAG_REVOKED, 238 if (!test_bit(KEY_FLAG_REVOKED,
@@ -251,19 +245,19 @@ static void construct_get_dest_keyring(struct key **_dest_keyring)
251 } 245 }
252 246
253 case KEY_REQKEY_DEFL_THREAD_KEYRING: 247 case KEY_REQKEY_DEFL_THREAD_KEYRING:
254 dest_keyring = key_get(tsk->cred->thread_keyring); 248 dest_keyring = key_get(cred->thread_keyring);
255 if (dest_keyring) 249 if (dest_keyring)
256 break; 250 break;
257 251
258 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 252 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
259 dest_keyring = key_get(tsk->signal->process_keyring); 253 dest_keyring = key_get(cred->tgcred->process_keyring);
260 if (dest_keyring) 254 if (dest_keyring)
261 break; 255 break;
262 256
263 case KEY_REQKEY_DEFL_SESSION_KEYRING: 257 case KEY_REQKEY_DEFL_SESSION_KEYRING:
264 rcu_read_lock(); 258 rcu_read_lock();
265 dest_keyring = key_get( 259 dest_keyring = key_get(
266 rcu_dereference(tsk->signal->session_keyring)); 260 rcu_dereference(cred->tgcred->session_keyring));
267 rcu_read_unlock(); 261 rcu_read_unlock();
268 262
269 if (dest_keyring) 263 if (dest_keyring)
@@ -271,11 +265,11 @@ static void construct_get_dest_keyring(struct key **_dest_keyring)
271 265
272 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 266 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
273 dest_keyring = 267 dest_keyring =
274 key_get(tsk->cred->user->session_keyring); 268 key_get(cred->user->session_keyring);
275 break; 269 break;
276 270
277 case KEY_REQKEY_DEFL_USER_KEYRING: 271 case KEY_REQKEY_DEFL_USER_KEYRING:
278 dest_keyring = key_get(tsk->cred->user->uid_keyring); 272 dest_keyring = key_get(cred->user->uid_keyring);
279 break; 273 break;
280 274
281 case KEY_REQKEY_DEFL_GROUP_KEYRING: 275 case KEY_REQKEY_DEFL_GROUP_KEYRING: