diff options
-rw-r--r-- | include/linux/key.h | 16 | ||||
-rw-r--r-- | include/linux/keyctl.h | 4 | ||||
-rw-r--r-- | kernel/kmod.c | 2 | ||||
-rw-r--r-- | security/keys/internal.h | 12 | ||||
-rw-r--r-- | security/keys/keyctl.c | 118 | ||||
-rw-r--r-- | security/keys/process_keys.c | 88 | ||||
-rw-r--r-- | security/keys/request_key.c | 75 | ||||
-rw-r--r-- | security/keys/request_key_auth.c | 5 |
8 files changed, 199 insertions, 121 deletions
diff --git a/include/linux/key.h b/include/linux/key.h index 1b70e35a71e3..df709e1af3cd 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -287,11 +287,11 @@ extern void key_fsuid_changed(struct task_struct *tsk); | |||
287 | extern void key_fsgid_changed(struct task_struct *tsk); | 287 | extern void key_fsgid_changed(struct task_struct *tsk); |
288 | extern void key_init(void); | 288 | extern void key_init(void); |
289 | 289 | ||
290 | #define __install_session_keyring(tsk, keyring) \ | 290 | #define __install_session_keyring(keyring) \ |
291 | ({ \ | 291 | ({ \ |
292 | struct key *old_session = tsk->signal->session_keyring; \ | 292 | struct key *old_session = current->signal->session_keyring; \ |
293 | tsk->signal->session_keyring = keyring; \ | 293 | current->signal->session_keyring = keyring; \ |
294 | old_session; \ | 294 | old_session; \ |
295 | }) | 295 | }) |
296 | 296 | ||
297 | #else /* CONFIG_KEYS */ | 297 | #else /* CONFIG_KEYS */ |
@@ -302,11 +302,11 @@ extern void key_init(void); | |||
302 | #define key_revoke(k) do { } while(0) | 302 | #define key_revoke(k) do { } while(0) |
303 | #define key_put(k) do { } while(0) | 303 | #define key_put(k) do { } while(0) |
304 | #define key_ref_put(k) do { } while(0) | 304 | #define key_ref_put(k) do { } while(0) |
305 | #define make_key_ref(k, p) ({ NULL; }) | 305 | #define make_key_ref(k, p) NULL |
306 | #define key_ref_to_ptr(k) ({ NULL; }) | 306 | #define key_ref_to_ptr(k) NULL |
307 | #define is_key_possessed(k) 0 | 307 | #define is_key_possessed(k) 0 |
308 | #define switch_uid_keyring(u) do { } while(0) | 308 | #define switch_uid_keyring(u) do { } while(0) |
309 | #define __install_session_keyring(t, k) ({ NULL; }) | 309 | #define __install_session_keyring(k) ({ NULL; }) |
310 | #define copy_keys(f,t) 0 | 310 | #define copy_keys(f,t) 0 |
311 | #define copy_thread_group_keys(t) 0 | 311 | #define copy_thread_group_keys(t) 0 |
312 | #define exit_keys(t) do { } while(0) | 312 | #define exit_keys(t) do { } while(0) |
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h index 656ee6b77a4a..c0688eb72093 100644 --- a/include/linux/keyctl.h +++ b/include/linux/keyctl.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* keyctl.h: keyctl command IDs | 1 | /* keyctl.h: keyctl command IDs |
2 | * | 2 | * |
3 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2004, 2008 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
@@ -20,6 +20,7 @@ | |||
20 | #define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ | 20 | #define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ |
21 | #define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */ | 21 | #define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */ |
22 | #define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */ | 22 | #define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */ |
23 | #define KEY_SPEC_REQUESTOR_KEYRING -8 /* - key ID for request_key() dest keyring */ | ||
23 | 24 | ||
24 | /* request-key default keyrings */ | 25 | /* request-key default keyrings */ |
25 | #define KEY_REQKEY_DEFL_NO_CHANGE -1 | 26 | #define KEY_REQKEY_DEFL_NO_CHANGE -1 |
@@ -30,6 +31,7 @@ | |||
30 | #define KEY_REQKEY_DEFL_USER_KEYRING 4 | 31 | #define KEY_REQKEY_DEFL_USER_KEYRING 4 |
31 | #define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 | 32 | #define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 |
32 | #define KEY_REQKEY_DEFL_GROUP_KEYRING 6 | 33 | #define KEY_REQKEY_DEFL_GROUP_KEYRING 6 |
34 | #define KEY_REQKEY_DEFL_REQUESTOR_KEYRING 7 | ||
33 | 35 | ||
34 | /* keyctl commands */ | 36 | /* keyctl commands */ |
35 | #define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ | 37 | #define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 3d3c3ea3a023..f044f8f57703 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -140,7 +140,7 @@ static int ____call_usermodehelper(void *data) | |||
140 | /* Unblock all signals and set the session keyring. */ | 140 | /* Unblock all signals and set the session keyring. */ |
141 | new_session = key_get(sub_info->ring); | 141 | new_session = key_get(sub_info->ring); |
142 | spin_lock_irq(¤t->sighand->siglock); | 142 | spin_lock_irq(¤t->sighand->siglock); |
143 | old_session = __install_session_keyring(current, new_session); | 143 | old_session = __install_session_keyring(new_session); |
144 | flush_signal_handlers(current, 1); | 144 | flush_signal_handlers(current, 1); |
145 | sigemptyset(¤t->blocked); | 145 | sigemptyset(¤t->blocked); |
146 | recalc_sigpending(); | 146 | recalc_sigpending(); |
diff --git a/security/keys/internal.h b/security/keys/internal.h index a60c68138b4d..d1586c629788 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -109,8 +109,9 @@ extern key_ref_t search_process_keyrings(struct key_type *type, | |||
109 | 109 | ||
110 | extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); | 110 | extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); |
111 | 111 | ||
112 | extern int install_thread_keyring(struct task_struct *tsk); | 112 | extern int install_user_keyrings(void); |
113 | extern int install_process_keyring(struct task_struct *tsk); | 113 | extern int install_thread_keyring(void); |
114 | extern int install_process_keyring(void); | ||
114 | 115 | ||
115 | extern struct key *request_key_and_link(struct key_type *type, | 116 | extern struct key *request_key_and_link(struct key_type *type, |
116 | const char *description, | 117 | const char *description, |
@@ -120,8 +121,7 @@ extern struct key *request_key_and_link(struct key_type *type, | |||
120 | struct key *dest_keyring, | 121 | struct key *dest_keyring, |
121 | unsigned long flags); | 122 | unsigned long flags); |
122 | 123 | ||
123 | extern key_ref_t lookup_user_key(struct task_struct *context, | 124 | extern key_ref_t lookup_user_key(key_serial_t id, int create, int partial, |
124 | key_serial_t id, int create, int partial, | ||
125 | key_perm_t perm); | 125 | key_perm_t perm); |
126 | 126 | ||
127 | extern long join_session_keyring(const char *name); | 127 | extern long join_session_keyring(const char *name); |
@@ -152,6 +152,7 @@ static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) | |||
152 | */ | 152 | */ |
153 | struct request_key_auth { | 153 | struct request_key_auth { |
154 | struct key *target_key; | 154 | struct key *target_key; |
155 | struct key *dest_keyring; | ||
155 | struct task_struct *context; | 156 | struct task_struct *context; |
156 | void *callout_info; | 157 | void *callout_info; |
157 | size_t callout_len; | 158 | size_t callout_len; |
@@ -161,7 +162,8 @@ struct request_key_auth { | |||
161 | extern struct key_type key_type_request_key_auth; | 162 | extern struct key_type key_type_request_key_auth; |
162 | extern struct key *request_key_auth_new(struct key *target, | 163 | extern struct key *request_key_auth_new(struct key *target, |
163 | const void *callout_info, | 164 | const void *callout_info, |
164 | size_t callout_len); | 165 | size_t callout_len, |
166 | struct key *dest_keyring); | ||
165 | 167 | ||
166 | extern struct key *key_get_instantiation_authkey(key_serial_t target_id); | 168 | extern struct key *key_get_instantiation_authkey(key_serial_t target_id); |
167 | 169 | ||
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 3f09e5b2a784..fcce331eca72 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -103,7 +103,7 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /* find the target keyring (which must be writable) */ | 105 | /* find the target keyring (which must be writable) */ |
106 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 106 | keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); |
107 | if (IS_ERR(keyring_ref)) { | 107 | if (IS_ERR(keyring_ref)) { |
108 | ret = PTR_ERR(keyring_ref); | 108 | ret = PTR_ERR(keyring_ref); |
109 | goto error3; | 109 | goto error3; |
@@ -185,7 +185,7 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
185 | /* get the destination keyring if specified */ | 185 | /* get the destination keyring if specified */ |
186 | dest_ref = NULL; | 186 | dest_ref = NULL; |
187 | if (destringid) { | 187 | if (destringid) { |
188 | dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); | 188 | dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE); |
189 | if (IS_ERR(dest_ref)) { | 189 | if (IS_ERR(dest_ref)) { |
190 | ret = PTR_ERR(dest_ref); | 190 | ret = PTR_ERR(dest_ref); |
191 | goto error3; | 191 | goto error3; |
@@ -235,7 +235,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create) | |||
235 | key_ref_t key_ref; | 235 | key_ref_t key_ref; |
236 | long ret; | 236 | long ret; |
237 | 237 | ||
238 | key_ref = lookup_user_key(NULL, id, create, 0, KEY_SEARCH); | 238 | key_ref = lookup_user_key(id, create, 0, KEY_SEARCH); |
239 | if (IS_ERR(key_ref)) { | 239 | if (IS_ERR(key_ref)) { |
240 | ret = PTR_ERR(key_ref); | 240 | ret = PTR_ERR(key_ref); |
241 | goto error; | 241 | goto error; |
@@ -308,7 +308,7 @@ long keyctl_update_key(key_serial_t id, | |||
308 | } | 308 | } |
309 | 309 | ||
310 | /* find the target key (which must be writable) */ | 310 | /* find the target key (which must be writable) */ |
311 | key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); | 311 | key_ref = lookup_user_key(id, 0, 0, KEY_WRITE); |
312 | if (IS_ERR(key_ref)) { | 312 | if (IS_ERR(key_ref)) { |
313 | ret = PTR_ERR(key_ref); | 313 | ret = PTR_ERR(key_ref); |
314 | goto error2; | 314 | goto error2; |
@@ -336,7 +336,7 @@ long keyctl_revoke_key(key_serial_t id) | |||
336 | key_ref_t key_ref; | 336 | key_ref_t key_ref; |
337 | long ret; | 337 | long ret; |
338 | 338 | ||
339 | key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); | 339 | key_ref = lookup_user_key(id, 0, 0, KEY_WRITE); |
340 | if (IS_ERR(key_ref)) { | 340 | if (IS_ERR(key_ref)) { |
341 | ret = PTR_ERR(key_ref); | 341 | ret = PTR_ERR(key_ref); |
342 | goto error; | 342 | goto error; |
@@ -362,7 +362,7 @@ long keyctl_keyring_clear(key_serial_t ringid) | |||
362 | key_ref_t keyring_ref; | 362 | key_ref_t keyring_ref; |
363 | long ret; | 363 | long ret; |
364 | 364 | ||
365 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 365 | keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); |
366 | if (IS_ERR(keyring_ref)) { | 366 | if (IS_ERR(keyring_ref)) { |
367 | ret = PTR_ERR(keyring_ref); | 367 | ret = PTR_ERR(keyring_ref); |
368 | goto error; | 368 | goto error; |
@@ -388,13 +388,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) | |||
388 | key_ref_t keyring_ref, key_ref; | 388 | key_ref_t keyring_ref, key_ref; |
389 | long ret; | 389 | long ret; |
390 | 390 | ||
391 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 391 | keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); |
392 | if (IS_ERR(keyring_ref)) { | 392 | if (IS_ERR(keyring_ref)) { |
393 | ret = PTR_ERR(keyring_ref); | 393 | ret = PTR_ERR(keyring_ref); |
394 | goto error; | 394 | goto error; |
395 | } | 395 | } |
396 | 396 | ||
397 | key_ref = lookup_user_key(NULL, id, 1, 0, KEY_LINK); | 397 | key_ref = lookup_user_key(id, 1, 0, KEY_LINK); |
398 | if (IS_ERR(key_ref)) { | 398 | if (IS_ERR(key_ref)) { |
399 | ret = PTR_ERR(key_ref); | 399 | ret = PTR_ERR(key_ref); |
400 | goto error2; | 400 | goto error2; |
@@ -422,13 +422,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) | |||
422 | key_ref_t keyring_ref, key_ref; | 422 | key_ref_t keyring_ref, key_ref; |
423 | long ret; | 423 | long ret; |
424 | 424 | ||
425 | keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE); | 425 | keyring_ref = lookup_user_key(ringid, 0, 0, KEY_WRITE); |
426 | if (IS_ERR(keyring_ref)) { | 426 | if (IS_ERR(keyring_ref)) { |
427 | ret = PTR_ERR(keyring_ref); | 427 | ret = PTR_ERR(keyring_ref); |
428 | goto error; | 428 | goto error; |
429 | } | 429 | } |
430 | 430 | ||
431 | key_ref = lookup_user_key(NULL, id, 0, 0, 0); | 431 | key_ref = lookup_user_key(id, 0, 0, 0); |
432 | if (IS_ERR(key_ref)) { | 432 | if (IS_ERR(key_ref)) { |
433 | ret = PTR_ERR(key_ref); | 433 | ret = PTR_ERR(key_ref); |
434 | goto error2; | 434 | goto error2; |
@@ -464,7 +464,7 @@ long keyctl_describe_key(key_serial_t keyid, | |||
464 | char *tmpbuf; | 464 | char *tmpbuf; |
465 | long ret; | 465 | long ret; |
466 | 466 | ||
467 | key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); | 467 | key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW); |
468 | if (IS_ERR(key_ref)) { | 468 | if (IS_ERR(key_ref)) { |
469 | /* viewing a key under construction is permitted if we have the | 469 | /* viewing a key under construction is permitted if we have the |
470 | * authorisation token handy */ | 470 | * authorisation token handy */ |
@@ -472,7 +472,7 @@ long keyctl_describe_key(key_serial_t keyid, | |||
472 | instkey = key_get_instantiation_authkey(keyid); | 472 | instkey = key_get_instantiation_authkey(keyid); |
473 | if (!IS_ERR(instkey)) { | 473 | if (!IS_ERR(instkey)) { |
474 | key_put(instkey); | 474 | key_put(instkey); |
475 | key_ref = lookup_user_key(NULL, keyid, | 475 | key_ref = lookup_user_key(keyid, |
476 | 0, 1, 0); | 476 | 0, 1, 0); |
477 | if (!IS_ERR(key_ref)) | 477 | if (!IS_ERR(key_ref)) |
478 | goto okay; | 478 | goto okay; |
@@ -557,7 +557,7 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
557 | } | 557 | } |
558 | 558 | ||
559 | /* get the keyring at which to begin the search */ | 559 | /* get the keyring at which to begin the search */ |
560 | keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); | 560 | keyring_ref = lookup_user_key(ringid, 0, 0, KEY_SEARCH); |
561 | if (IS_ERR(keyring_ref)) { | 561 | if (IS_ERR(keyring_ref)) { |
562 | ret = PTR_ERR(keyring_ref); | 562 | ret = PTR_ERR(keyring_ref); |
563 | goto error2; | 563 | goto error2; |
@@ -566,7 +566,7 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
566 | /* get the destination keyring if specified */ | 566 | /* get the destination keyring if specified */ |
567 | dest_ref = NULL; | 567 | dest_ref = NULL; |
568 | if (destringid) { | 568 | if (destringid) { |
569 | dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); | 569 | dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE); |
570 | if (IS_ERR(dest_ref)) { | 570 | if (IS_ERR(dest_ref)) { |
571 | ret = PTR_ERR(dest_ref); | 571 | ret = PTR_ERR(dest_ref); |
572 | goto error3; | 572 | goto error3; |
@@ -636,7 +636,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) | |||
636 | long ret; | 636 | long ret; |
637 | 637 | ||
638 | /* find the key first */ | 638 | /* find the key first */ |
639 | key_ref = lookup_user_key(NULL, keyid, 0, 0, 0); | 639 | key_ref = lookup_user_key(keyid, 0, 0, 0); |
640 | if (IS_ERR(key_ref)) { | 640 | if (IS_ERR(key_ref)) { |
641 | ret = -ENOKEY; | 641 | ret = -ENOKEY; |
642 | goto error; | 642 | goto error; |
@@ -699,7 +699,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
699 | if (uid == (uid_t) -1 && gid == (gid_t) -1) | 699 | if (uid == (uid_t) -1 && gid == (gid_t) -1) |
700 | goto error; | 700 | goto error; |
701 | 701 | ||
702 | key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); | 702 | key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); |
703 | if (IS_ERR(key_ref)) { | 703 | if (IS_ERR(key_ref)) { |
704 | ret = PTR_ERR(key_ref); | 704 | ret = PTR_ERR(key_ref); |
705 | goto error; | 705 | goto error; |
@@ -804,7 +804,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) | |||
804 | if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) | 804 | if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) |
805 | goto error; | 805 | goto error; |
806 | 806 | ||
807 | key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); | 807 | key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); |
808 | if (IS_ERR(key_ref)) { | 808 | if (IS_ERR(key_ref)) { |
809 | ret = PTR_ERR(key_ref); | 809 | ret = PTR_ERR(key_ref); |
810 | goto error; | 810 | goto error; |
@@ -829,6 +829,43 @@ error: | |||
829 | 829 | ||
830 | } /* end keyctl_setperm_key() */ | 830 | } /* end keyctl_setperm_key() */ |
831 | 831 | ||
832 | /* | ||
833 | * get the destination keyring for instantiation | ||
834 | */ | ||
835 | static long get_instantiation_keyring(key_serial_t ringid, | ||
836 | struct request_key_auth *rka, | ||
837 | struct key **_dest_keyring) | ||
838 | { | ||
839 | key_ref_t dkref; | ||
840 | |||
841 | /* just return a NULL pointer if we weren't asked to make a link */ | ||
842 | if (ringid == 0) { | ||
843 | *_dest_keyring = NULL; | ||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | /* if a specific keyring is nominated by ID, then use that */ | ||
848 | if (ringid > 0) { | ||
849 | dkref = lookup_user_key(ringid, 1, 0, KEY_WRITE); | ||
850 | if (IS_ERR(dkref)) | ||
851 | return PTR_ERR(dkref); | ||
852 | *_dest_keyring = key_ref_to_ptr(dkref); | ||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | if (ringid == KEY_SPEC_REQKEY_AUTH_KEY) | ||
857 | return -EINVAL; | ||
858 | |||
859 | /* otherwise specify the destination keyring recorded in the | ||
860 | * authorisation key (any KEY_SPEC_*_KEYRING) */ | ||
861 | if (ringid >= KEY_SPEC_REQUESTOR_KEYRING) { | ||
862 | *_dest_keyring = rka->dest_keyring; | ||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | return -ENOKEY; | ||
867 | } | ||
868 | |||
832 | /*****************************************************************************/ | 869 | /*****************************************************************************/ |
833 | /* | 870 | /* |
834 | * instantiate the key with the specified payload, and, if one is given, link | 871 | * instantiate the key with the specified payload, and, if one is given, link |
@@ -840,8 +877,7 @@ long keyctl_instantiate_key(key_serial_t id, | |||
840 | key_serial_t ringid) | 877 | key_serial_t ringid) |
841 | { | 878 | { |
842 | struct request_key_auth *rka; | 879 | struct request_key_auth *rka; |
843 | struct key *instkey; | 880 | struct key *instkey, *dest_keyring; |
844 | key_ref_t keyring_ref; | ||
845 | void *payload; | 881 | void *payload; |
846 | long ret; | 882 | long ret; |
847 | bool vm = false; | 883 | bool vm = false; |
@@ -883,21 +919,15 @@ long keyctl_instantiate_key(key_serial_t id, | |||
883 | 919 | ||
884 | /* find the destination keyring amongst those belonging to the | 920 | /* find the destination keyring amongst those belonging to the |
885 | * requesting task */ | 921 | * requesting task */ |
886 | keyring_ref = NULL; | 922 | ret = get_instantiation_keyring(ringid, rka, &dest_keyring); |
887 | if (ringid) { | 923 | if (ret < 0) |
888 | keyring_ref = lookup_user_key(rka->context, ringid, 1, 0, | 924 | goto error2; |
889 | KEY_WRITE); | ||
890 | if (IS_ERR(keyring_ref)) { | ||
891 | ret = PTR_ERR(keyring_ref); | ||
892 | goto error2; | ||
893 | } | ||
894 | } | ||
895 | 925 | ||
896 | /* instantiate the key and link it into a keyring */ | 926 | /* instantiate the key and link it into a keyring */ |
897 | ret = key_instantiate_and_link(rka->target_key, payload, plen, | 927 | ret = key_instantiate_and_link(rka->target_key, payload, plen, |
898 | key_ref_to_ptr(keyring_ref), instkey); | 928 | dest_keyring, instkey); |
899 | 929 | ||
900 | key_ref_put(keyring_ref); | 930 | key_put(dest_keyring); |
901 | 931 | ||
902 | /* discard the assumed authority if it's just been disabled by | 932 | /* discard the assumed authority if it's just been disabled by |
903 | * instantiation of the key */ | 933 | * instantiation of the key */ |
@@ -924,8 +954,7 @@ error: | |||
924 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | 954 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) |
925 | { | 955 | { |
926 | struct request_key_auth *rka; | 956 | struct request_key_auth *rka; |
927 | struct key *instkey; | 957 | struct key *instkey, *dest_keyring; |
928 | key_ref_t keyring_ref; | ||
929 | long ret; | 958 | long ret; |
930 | 959 | ||
931 | /* the appropriate instantiation authorisation key must have been | 960 | /* the appropriate instantiation authorisation key must have been |
@@ -941,20 +970,15 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | |||
941 | 970 | ||
942 | /* find the destination keyring if present (which must also be | 971 | /* find the destination keyring if present (which must also be |
943 | * writable) */ | 972 | * writable) */ |
944 | keyring_ref = NULL; | 973 | ret = get_instantiation_keyring(ringid, rka, &dest_keyring); |
945 | if (ringid) { | 974 | if (ret < 0) |
946 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 975 | goto error; |
947 | if (IS_ERR(keyring_ref)) { | ||
948 | ret = PTR_ERR(keyring_ref); | ||
949 | goto error; | ||
950 | } | ||
951 | } | ||
952 | 976 | ||
953 | /* instantiate the key and link it into a keyring */ | 977 | /* instantiate the key and link it into a keyring */ |
954 | ret = key_negate_and_link(rka->target_key, timeout, | 978 | ret = key_negate_and_link(rka->target_key, timeout, |
955 | key_ref_to_ptr(keyring_ref), instkey); | 979 | dest_keyring, instkey); |
956 | 980 | ||
957 | key_ref_put(keyring_ref); | 981 | key_put(dest_keyring); |
958 | 982 | ||
959 | /* discard the assumed authority if it's just been disabled by | 983 | /* discard the assumed authority if it's just been disabled by |
960 | * instantiation of the key */ | 984 | * instantiation of the key */ |
@@ -979,13 +1003,13 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) | |||
979 | 1003 | ||
980 | switch (reqkey_defl) { | 1004 | switch (reqkey_defl) { |
981 | case KEY_REQKEY_DEFL_THREAD_KEYRING: | 1005 | case KEY_REQKEY_DEFL_THREAD_KEYRING: |
982 | ret = install_thread_keyring(current); | 1006 | ret = install_thread_keyring(); |
983 | if (ret < 0) | 1007 | if (ret < 0) |
984 | return ret; | 1008 | return ret; |
985 | goto set; | 1009 | goto set; |
986 | 1010 | ||
987 | case KEY_REQKEY_DEFL_PROCESS_KEYRING: | 1011 | case KEY_REQKEY_DEFL_PROCESS_KEYRING: |
988 | ret = install_process_keyring(current); | 1012 | ret = install_process_keyring(); |
989 | if (ret < 0) | 1013 | if (ret < 0) |
990 | return ret; | 1014 | return ret; |
991 | 1015 | ||
@@ -1018,7 +1042,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) | |||
1018 | time_t expiry; | 1042 | time_t expiry; |
1019 | long ret; | 1043 | long ret; |
1020 | 1044 | ||
1021 | key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); | 1045 | key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); |
1022 | if (IS_ERR(key_ref)) { | 1046 | if (IS_ERR(key_ref)) { |
1023 | ret = PTR_ERR(key_ref); | 1047 | ret = PTR_ERR(key_ref); |
1024 | goto error; | 1048 | goto error; |
@@ -1105,7 +1129,7 @@ long keyctl_get_security(key_serial_t keyid, | |||
1105 | char *context; | 1129 | char *context; |
1106 | long ret; | 1130 | long ret; |
1107 | 1131 | ||
1108 | key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); | 1132 | key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW); |
1109 | if (IS_ERR(key_ref)) { | 1133 | if (IS_ERR(key_ref)) { |
1110 | if (PTR_ERR(key_ref) != -EACCES) | 1134 | if (PTR_ERR(key_ref) != -EACCES) |
1111 | return PTR_ERR(key_ref); | 1135 | return PTR_ERR(key_ref); |
@@ -1117,7 +1141,7 @@ long keyctl_get_security(key_serial_t keyid, | |||
1117 | return PTR_ERR(key_ref); | 1141 | return PTR_ERR(key_ref); |
1118 | key_put(instkey); | 1142 | key_put(instkey); |
1119 | 1143 | ||
1120 | key_ref = lookup_user_key(NULL, keyid, 0, 1, 0); | 1144 | key_ref = lookup_user_key(keyid, 0, 1, 0); |
1121 | if (IS_ERR(key_ref)) | 1145 | if (IS_ERR(key_ref)) |
1122 | return PTR_ERR(key_ref); | 1146 | return PTR_ERR(key_ref); |
1123 | } | 1147 | } |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 5be6d018759a..1c793b7090a7 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -40,9 +40,9 @@ struct key_user root_key_user = { | |||
40 | /* | 40 | /* |
41 | * install user and user session keyrings for a particular UID | 41 | * install user and user session keyrings for a particular UID |
42 | */ | 42 | */ |
43 | static int install_user_keyrings(struct task_struct *tsk) | 43 | int install_user_keyrings(void) |
44 | { | 44 | { |
45 | struct user_struct *user = tsk->user; | 45 | struct user_struct *user = current->user; |
46 | struct key *uid_keyring, *session_keyring; | 46 | struct key *uid_keyring, *session_keyring; |
47 | char buf[20]; | 47 | char buf[20]; |
48 | int ret; | 48 | int ret; |
@@ -67,7 +67,7 @@ static int install_user_keyrings(struct task_struct *tsk) | |||
67 | uid_keyring = find_keyring_by_name(buf, true); | 67 | uid_keyring = find_keyring_by_name(buf, true); |
68 | if (IS_ERR(uid_keyring)) { | 68 | if (IS_ERR(uid_keyring)) { |
69 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, | 69 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, |
70 | tsk, KEY_ALLOC_IN_QUOTA, | 70 | current, KEY_ALLOC_IN_QUOTA, |
71 | NULL); | 71 | NULL); |
72 | if (IS_ERR(uid_keyring)) { | 72 | if (IS_ERR(uid_keyring)) { |
73 | ret = PTR_ERR(uid_keyring); | 73 | ret = PTR_ERR(uid_keyring); |
@@ -83,7 +83,8 @@ static int install_user_keyrings(struct task_struct *tsk) | |||
83 | if (IS_ERR(session_keyring)) { | 83 | if (IS_ERR(session_keyring)) { |
84 | session_keyring = | 84 | session_keyring = |
85 | keyring_alloc(buf, user->uid, (gid_t) -1, | 85 | keyring_alloc(buf, user->uid, (gid_t) -1, |
86 | tsk, KEY_ALLOC_IN_QUOTA, NULL); | 86 | current, KEY_ALLOC_IN_QUOTA, |
87 | NULL); | ||
87 | if (IS_ERR(session_keyring)) { | 88 | if (IS_ERR(session_keyring)) { |
88 | ret = PTR_ERR(session_keyring); | 89 | ret = PTR_ERR(session_keyring); |
89 | goto error_release; | 90 | goto error_release; |
@@ -146,8 +147,9 @@ void switch_uid_keyring(struct user_struct *new_user) | |||
146 | /* | 147 | /* |
147 | * install a fresh thread keyring, discarding the old one | 148 | * install a fresh thread keyring, discarding the old one |
148 | */ | 149 | */ |
149 | int install_thread_keyring(struct task_struct *tsk) | 150 | int install_thread_keyring(void) |
150 | { | 151 | { |
152 | struct task_struct *tsk = current; | ||
151 | struct key *keyring, *old; | 153 | struct key *keyring, *old; |
152 | char buf[20]; | 154 | char buf[20]; |
153 | int ret; | 155 | int ret; |
@@ -178,8 +180,9 @@ error: | |||
178 | /* | 180 | /* |
179 | * make sure a process keyring is installed | 181 | * make sure a process keyring is installed |
180 | */ | 182 | */ |
181 | int install_process_keyring(struct task_struct *tsk) | 183 | int install_process_keyring(void) |
182 | { | 184 | { |
185 | struct task_struct *tsk = current; | ||
183 | struct key *keyring; | 186 | struct key *keyring; |
184 | char buf[20]; | 187 | char buf[20]; |
185 | int ret; | 188 | int ret; |
@@ -218,9 +221,9 @@ error: | |||
218 | * install a session keyring, discarding the old one | 221 | * install a session keyring, discarding the old one |
219 | * - if a keyring is not supplied, an empty one is invented | 222 | * - if a keyring is not supplied, an empty one is invented |
220 | */ | 223 | */ |
221 | static int install_session_keyring(struct task_struct *tsk, | 224 | static int install_session_keyring(struct key *keyring) |
222 | struct key *keyring) | ||
223 | { | 225 | { |
226 | struct task_struct *tsk = current; | ||
224 | unsigned long flags; | 227 | unsigned long flags; |
225 | struct key *old; | 228 | struct key *old; |
226 | char buf[20]; | 229 | char buf[20]; |
@@ -572,93 +575,91 @@ static int lookup_user_key_possessed(const struct key *key, const void *target) | |||
572 | * - don't create special keyrings unless so requested | 575 | * - don't create special keyrings unless so requested |
573 | * - partially constructed keys aren't found unless requested | 576 | * - partially constructed keys aren't found unless requested |
574 | */ | 577 | */ |
575 | key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | 578 | key_ref_t lookup_user_key(key_serial_t id, int create, int partial, |
576 | int create, int partial, key_perm_t perm) | 579 | key_perm_t perm) |
577 | { | 580 | { |
581 | struct request_key_auth *rka; | ||
582 | struct task_struct *t = current; | ||
578 | key_ref_t key_ref, skey_ref; | 583 | key_ref_t key_ref, skey_ref; |
579 | struct key *key; | 584 | struct key *key; |
580 | int ret; | 585 | int ret; |
581 | 586 | ||
582 | if (!context) | ||
583 | context = current; | ||
584 | |||
585 | key_ref = ERR_PTR(-ENOKEY); | 587 | key_ref = ERR_PTR(-ENOKEY); |
586 | 588 | ||
587 | switch (id) { | 589 | switch (id) { |
588 | case KEY_SPEC_THREAD_KEYRING: | 590 | case KEY_SPEC_THREAD_KEYRING: |
589 | if (!context->thread_keyring) { | 591 | if (!t->thread_keyring) { |
590 | if (!create) | 592 | if (!create) |
591 | goto error; | 593 | goto error; |
592 | 594 | ||
593 | ret = install_thread_keyring(context); | 595 | ret = install_thread_keyring(); |
594 | if (ret < 0) { | 596 | if (ret < 0) { |
595 | key = ERR_PTR(ret); | 597 | key = ERR_PTR(ret); |
596 | goto error; | 598 | goto error; |
597 | } | 599 | } |
598 | } | 600 | } |
599 | 601 | ||
600 | key = context->thread_keyring; | 602 | key = t->thread_keyring; |
601 | atomic_inc(&key->usage); | 603 | atomic_inc(&key->usage); |
602 | key_ref = make_key_ref(key, 1); | 604 | key_ref = make_key_ref(key, 1); |
603 | break; | 605 | break; |
604 | 606 | ||
605 | case KEY_SPEC_PROCESS_KEYRING: | 607 | case KEY_SPEC_PROCESS_KEYRING: |
606 | if (!context->signal->process_keyring) { | 608 | if (!t->signal->process_keyring) { |
607 | if (!create) | 609 | if (!create) |
608 | goto error; | 610 | goto error; |
609 | 611 | ||
610 | ret = install_process_keyring(context); | 612 | ret = install_process_keyring(); |
611 | if (ret < 0) { | 613 | if (ret < 0) { |
612 | key = ERR_PTR(ret); | 614 | key = ERR_PTR(ret); |
613 | goto error; | 615 | goto error; |
614 | } | 616 | } |
615 | } | 617 | } |
616 | 618 | ||
617 | key = context->signal->process_keyring; | 619 | key = t->signal->process_keyring; |
618 | atomic_inc(&key->usage); | 620 | atomic_inc(&key->usage); |
619 | key_ref = make_key_ref(key, 1); | 621 | key_ref = make_key_ref(key, 1); |
620 | break; | 622 | break; |
621 | 623 | ||
622 | case KEY_SPEC_SESSION_KEYRING: | 624 | case KEY_SPEC_SESSION_KEYRING: |
623 | if (!context->signal->session_keyring) { | 625 | if (!t->signal->session_keyring) { |
624 | /* always install a session keyring upon access if one | 626 | /* always install a session keyring upon access if one |
625 | * doesn't exist yet */ | 627 | * doesn't exist yet */ |
626 | ret = install_user_keyrings(context); | 628 | ret = install_user_keyrings(); |
627 | if (ret < 0) | 629 | if (ret < 0) |
628 | goto error; | 630 | goto error; |
629 | ret = install_session_keyring( | 631 | ret = install_session_keyring(t->user->session_keyring); |
630 | context, context->user->session_keyring); | ||
631 | if (ret < 0) | 632 | if (ret < 0) |
632 | goto error; | 633 | goto error; |
633 | } | 634 | } |
634 | 635 | ||
635 | rcu_read_lock(); | 636 | rcu_read_lock(); |
636 | key = rcu_dereference(context->signal->session_keyring); | 637 | key = rcu_dereference(t->signal->session_keyring); |
637 | atomic_inc(&key->usage); | 638 | atomic_inc(&key->usage); |
638 | rcu_read_unlock(); | 639 | rcu_read_unlock(); |
639 | key_ref = make_key_ref(key, 1); | 640 | key_ref = make_key_ref(key, 1); |
640 | break; | 641 | break; |
641 | 642 | ||
642 | case KEY_SPEC_USER_KEYRING: | 643 | case KEY_SPEC_USER_KEYRING: |
643 | if (!context->user->uid_keyring) { | 644 | if (!t->user->uid_keyring) { |
644 | ret = install_user_keyrings(context); | 645 | ret = install_user_keyrings(); |
645 | if (ret < 0) | 646 | if (ret < 0) |
646 | goto error; | 647 | goto error; |
647 | } | 648 | } |
648 | 649 | ||
649 | key = context->user->uid_keyring; | 650 | key = t->user->uid_keyring; |
650 | atomic_inc(&key->usage); | 651 | atomic_inc(&key->usage); |
651 | key_ref = make_key_ref(key, 1); | 652 | key_ref = make_key_ref(key, 1); |
652 | break; | 653 | break; |
653 | 654 | ||
654 | case KEY_SPEC_USER_SESSION_KEYRING: | 655 | case KEY_SPEC_USER_SESSION_KEYRING: |
655 | if (!context->user->session_keyring) { | 656 | if (!t->user->session_keyring) { |
656 | ret = install_user_keyrings(context); | 657 | ret = install_user_keyrings(); |
657 | if (ret < 0) | 658 | if (ret < 0) |
658 | goto error; | 659 | goto error; |
659 | } | 660 | } |
660 | 661 | ||
661 | key = context->user->session_keyring; | 662 | key = t->user->session_keyring; |
662 | atomic_inc(&key->usage); | 663 | atomic_inc(&key->usage); |
663 | key_ref = make_key_ref(key, 1); | 664 | key_ref = make_key_ref(key, 1); |
664 | break; | 665 | break; |
@@ -669,7 +670,7 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
669 | goto error; | 670 | goto error; |
670 | 671 | ||
671 | case KEY_SPEC_REQKEY_AUTH_KEY: | 672 | case KEY_SPEC_REQKEY_AUTH_KEY: |
672 | key = context->request_key_auth; | 673 | key = t->request_key_auth; |
673 | if (!key) | 674 | if (!key) |
674 | goto error; | 675 | goto error; |
675 | 676 | ||
@@ -677,6 +678,25 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
677 | key_ref = make_key_ref(key, 1); | 678 | key_ref = make_key_ref(key, 1); |
678 | break; | 679 | break; |
679 | 680 | ||
681 | case KEY_SPEC_REQUESTOR_KEYRING: | ||
682 | if (!t->request_key_auth) | ||
683 | goto error; | ||
684 | |||
685 | down_read(&t->request_key_auth->sem); | ||
686 | if (t->request_key_auth->flags & KEY_FLAG_REVOKED) { | ||
687 | key_ref = ERR_PTR(-EKEYREVOKED); | ||
688 | key = NULL; | ||
689 | } else { | ||
690 | rka = t->request_key_auth->payload.data; | ||
691 | key = rka->dest_keyring; | ||
692 | atomic_inc(&key->usage); | ||
693 | } | ||
694 | up_read(&t->request_key_auth->sem); | ||
695 | if (!key) | ||
696 | goto error; | ||
697 | key_ref = make_key_ref(key, 1); | ||
698 | break; | ||
699 | |||
680 | default: | 700 | default: |
681 | key_ref = ERR_PTR(-EINVAL); | 701 | key_ref = ERR_PTR(-EINVAL); |
682 | if (id < 1) | 702 | if (id < 1) |
@@ -725,7 +745,7 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
725 | goto invalid_key; | 745 | goto invalid_key; |
726 | 746 | ||
727 | /* check the permissions */ | 747 | /* check the permissions */ |
728 | ret = key_task_permission(key_ref, context, perm); | 748 | ret = key_task_permission(key_ref, t, perm); |
729 | if (ret < 0) | 749 | if (ret < 0) |
730 | goto invalid_key; | 750 | goto invalid_key; |
731 | 751 | ||
@@ -754,7 +774,7 @@ long join_session_keyring(const char *name) | |||
754 | 774 | ||
755 | /* if no name is provided, install an anonymous keyring */ | 775 | /* if no name is provided, install an anonymous keyring */ |
756 | if (!name) { | 776 | if (!name) { |
757 | ret = install_session_keyring(tsk, NULL); | 777 | ret = install_session_keyring(NULL); |
758 | if (ret < 0) | 778 | if (ret < 0) |
759 | goto error; | 779 | goto error; |
760 | 780 | ||
@@ -784,7 +804,7 @@ long join_session_keyring(const char *name) | |||
784 | } | 804 | } |
785 | 805 | ||
786 | /* we've got a keyring - now to install it */ | 806 | /* we've got a keyring - now to install it */ |
787 | ret = install_session_keyring(tsk, keyring); | 807 | ret = install_session_keyring(keyring); |
788 | if (ret < 0) | 808 | if (ret < 0) |
789 | goto error2; | 809 | goto error2; |
790 | 810 | ||
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 91953c814497..8e9d93b4a402 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -76,6 +76,10 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
76 | 76 | ||
77 | kenter("{%d},{%d},%s", key->serial, authkey->serial, op); | 77 | kenter("{%d},{%d},%s", key->serial, authkey->serial, op); |
78 | 78 | ||
79 | ret = install_user_keyrings(); | ||
80 | if (ret < 0) | ||
81 | goto error_alloc; | ||
82 | |||
79 | /* allocate a new session keyring */ | 83 | /* allocate a new session keyring */ |
80 | sprintf(desc, "_req.%u", key->serial); | 84 | sprintf(desc, "_req.%u", key->serial); |
81 | 85 | ||
@@ -165,7 +169,8 @@ error_alloc: | |||
165 | * - we ignore program failure and go on key status instead | 169 | * - we ignore program failure and go on key status instead |
166 | */ | 170 | */ |
167 | static int construct_key(struct key *key, const void *callout_info, | 171 | static int construct_key(struct key *key, const void *callout_info, |
168 | size_t callout_len, void *aux) | 172 | size_t callout_len, void *aux, |
173 | struct key *dest_keyring) | ||
169 | { | 174 | { |
170 | struct key_construction *cons; | 175 | struct key_construction *cons; |
171 | request_key_actor_t actor; | 176 | request_key_actor_t actor; |
@@ -179,7 +184,8 @@ static int construct_key(struct key *key, const void *callout_info, | |||
179 | return -ENOMEM; | 184 | return -ENOMEM; |
180 | 185 | ||
181 | /* allocate an authorisation key */ | 186 | /* allocate an authorisation key */ |
182 | authkey = request_key_auth_new(key, callout_info, callout_len); | 187 | authkey = request_key_auth_new(key, callout_info, callout_len, |
188 | dest_keyring); | ||
183 | if (IS_ERR(authkey)) { | 189 | if (IS_ERR(authkey)) { |
184 | kfree(cons); | 190 | kfree(cons); |
185 | ret = PTR_ERR(authkey); | 191 | ret = PTR_ERR(authkey); |
@@ -207,27 +213,48 @@ static int construct_key(struct key *key, const void *callout_info, | |||
207 | } | 213 | } |
208 | 214 | ||
209 | /* | 215 | /* |
210 | * link a key to the appropriate destination keyring | 216 | * get the appropriate destination keyring for the request |
211 | * - the caller must hold a write lock on the destination keyring | 217 | * - we return whatever keyring we select with an extra reference upon it which |
218 | * the caller must release | ||
212 | */ | 219 | */ |
213 | static void construct_key_make_link(struct key *key, struct key *dest_keyring) | 220 | static void construct_get_dest_keyring(struct key **_dest_keyring) |
214 | { | 221 | { |
222 | struct request_key_auth *rka; | ||
215 | struct task_struct *tsk = current; | 223 | struct task_struct *tsk = current; |
216 | struct key *drop = NULL; | 224 | struct key *dest_keyring = *_dest_keyring, *authkey; |
217 | 225 | ||
218 | kenter("{%d},%p", key->serial, dest_keyring); | 226 | kenter("%p", dest_keyring); |
219 | 227 | ||
220 | /* find the appropriate keyring */ | 228 | /* find the appropriate keyring */ |
221 | if (!dest_keyring) { | 229 | if (dest_keyring) { |
230 | /* the caller supplied one */ | ||
231 | key_get(dest_keyring); | ||
232 | } else { | ||
233 | /* use a default keyring; falling through the cases until we | ||
234 | * find one that we actually have */ | ||
222 | switch (tsk->jit_keyring) { | 235 | switch (tsk->jit_keyring) { |
223 | case KEY_REQKEY_DEFL_DEFAULT: | 236 | case KEY_REQKEY_DEFL_DEFAULT: |
237 | case KEY_REQKEY_DEFL_REQUESTOR_KEYRING: | ||
238 | if (tsk->request_key_auth) { | ||
239 | authkey = tsk->request_key_auth; | ||
240 | down_read(&authkey->sem); | ||
241 | rka = authkey->payload.data; | ||
242 | if (!test_bit(KEY_FLAG_REVOKED, | ||
243 | &authkey->flags)) | ||
244 | dest_keyring = | ||
245 | key_get(rka->dest_keyring); | ||
246 | up_read(&authkey->sem); | ||
247 | if (dest_keyring) | ||
248 | break; | ||
249 | } | ||
250 | |||
224 | case KEY_REQKEY_DEFL_THREAD_KEYRING: | 251 | case KEY_REQKEY_DEFL_THREAD_KEYRING: |
225 | dest_keyring = tsk->thread_keyring; | 252 | dest_keyring = key_get(tsk->thread_keyring); |
226 | if (dest_keyring) | 253 | if (dest_keyring) |
227 | break; | 254 | break; |
228 | 255 | ||
229 | case KEY_REQKEY_DEFL_PROCESS_KEYRING: | 256 | case KEY_REQKEY_DEFL_PROCESS_KEYRING: |
230 | dest_keyring = tsk->signal->process_keyring; | 257 | dest_keyring = key_get(tsk->signal->process_keyring); |
231 | if (dest_keyring) | 258 | if (dest_keyring) |
232 | break; | 259 | break; |
233 | 260 | ||
@@ -236,17 +263,16 @@ static void construct_key_make_link(struct key *key, struct key *dest_keyring) | |||
236 | dest_keyring = key_get( | 263 | dest_keyring = key_get( |
237 | rcu_dereference(tsk->signal->session_keyring)); | 264 | rcu_dereference(tsk->signal->session_keyring)); |
238 | rcu_read_unlock(); | 265 | rcu_read_unlock(); |
239 | drop = dest_keyring; | ||
240 | 266 | ||
241 | if (dest_keyring) | 267 | if (dest_keyring) |
242 | break; | 268 | break; |
243 | 269 | ||
244 | case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: | 270 | case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: |
245 | dest_keyring = tsk->user->session_keyring; | 271 | dest_keyring = key_get(tsk->user->session_keyring); |
246 | break; | 272 | break; |
247 | 273 | ||
248 | case KEY_REQKEY_DEFL_USER_KEYRING: | 274 | case KEY_REQKEY_DEFL_USER_KEYRING: |
249 | dest_keyring = tsk->user->uid_keyring; | 275 | dest_keyring = key_get(tsk->user->uid_keyring); |
250 | break; | 276 | break; |
251 | 277 | ||
252 | case KEY_REQKEY_DEFL_GROUP_KEYRING: | 278 | case KEY_REQKEY_DEFL_GROUP_KEYRING: |
@@ -255,10 +281,9 @@ static void construct_key_make_link(struct key *key, struct key *dest_keyring) | |||
255 | } | 281 | } |
256 | } | 282 | } |
257 | 283 | ||
258 | /* and attach the key to it */ | 284 | *_dest_keyring = dest_keyring; |
259 | __key_link(dest_keyring, key); | 285 | kleave(" [dk %d]", key_serial(dest_keyring)); |
260 | key_put(drop); | 286 | return; |
261 | kleave(""); | ||
262 | } | 287 | } |
263 | 288 | ||
264 | /* | 289 | /* |
@@ -288,8 +313,7 @@ static int construct_alloc_key(struct key_type *type, | |||
288 | 313 | ||
289 | set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); | 314 | set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); |
290 | 315 | ||
291 | if (dest_keyring) | 316 | down_write(&dest_keyring->sem); |
292 | down_write(&dest_keyring->sem); | ||
293 | 317 | ||
294 | /* attach the key to the destination keyring under lock, but we do need | 318 | /* attach the key to the destination keyring under lock, but we do need |
295 | * to do another check just in case someone beat us to it whilst we | 319 | * to do another check just in case someone beat us to it whilst we |
@@ -301,12 +325,10 @@ static int construct_alloc_key(struct key_type *type, | |||
301 | if (!IS_ERR(key_ref)) | 325 | if (!IS_ERR(key_ref)) |
302 | goto key_already_present; | 326 | goto key_already_present; |
303 | 327 | ||
304 | if (dest_keyring) | 328 | __key_link(dest_keyring, key); |
305 | construct_key_make_link(key, dest_keyring); | ||
306 | 329 | ||
307 | mutex_unlock(&key_construction_mutex); | 330 | mutex_unlock(&key_construction_mutex); |
308 | if (dest_keyring) | 331 | up_write(&dest_keyring->sem); |
309 | up_write(&dest_keyring->sem); | ||
310 | mutex_unlock(&user->cons_lock); | 332 | mutex_unlock(&user->cons_lock); |
311 | *_key = key; | 333 | *_key = key; |
312 | kleave(" = 0 [%d]", key_serial(key)); | 334 | kleave(" = 0 [%d]", key_serial(key)); |
@@ -348,21 +370,26 @@ static struct key *construct_key_and_link(struct key_type *type, | |||
348 | if (!user) | 370 | if (!user) |
349 | return ERR_PTR(-ENOMEM); | 371 | return ERR_PTR(-ENOMEM); |
350 | 372 | ||
373 | construct_get_dest_keyring(&dest_keyring); | ||
374 | |||
351 | ret = construct_alloc_key(type, description, dest_keyring, flags, user, | 375 | ret = construct_alloc_key(type, description, dest_keyring, flags, user, |
352 | &key); | 376 | &key); |
353 | key_user_put(user); | 377 | key_user_put(user); |
354 | 378 | ||
355 | if (ret == 0) { | 379 | if (ret == 0) { |
356 | ret = construct_key(key, callout_info, callout_len, aux); | 380 | ret = construct_key(key, callout_info, callout_len, aux, |
381 | dest_keyring); | ||
357 | if (ret < 0) | 382 | if (ret < 0) |
358 | goto construction_failed; | 383 | goto construction_failed; |
359 | } | 384 | } |
360 | 385 | ||
386 | key_put(dest_keyring); | ||
361 | return key; | 387 | return key; |
362 | 388 | ||
363 | construction_failed: | 389 | construction_failed: |
364 | key_negate_and_link(key, key_negative_timeout, NULL, NULL); | 390 | key_negate_and_link(key, key_negative_timeout, NULL, NULL); |
365 | key_put(key); | 391 | key_put(key); |
392 | key_put(dest_keyring); | ||
366 | return ERR_PTR(ret); | 393 | return ERR_PTR(ret); |
367 | } | 394 | } |
368 | 395 | ||
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 729156b3485e..1762d44711d5 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -128,6 +128,7 @@ static void request_key_auth_destroy(struct key *key) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | key_put(rka->target_key); | 130 | key_put(rka->target_key); |
131 | key_put(rka->dest_keyring); | ||
131 | kfree(rka->callout_info); | 132 | kfree(rka->callout_info); |
132 | kfree(rka); | 133 | kfree(rka); |
133 | 134 | ||
@@ -139,7 +140,7 @@ static void request_key_auth_destroy(struct key *key) | |||
139 | * access to the caller's security data | 140 | * access to the caller's security data |
140 | */ | 141 | */ |
141 | struct key *request_key_auth_new(struct key *target, const void *callout_info, | 142 | struct key *request_key_auth_new(struct key *target, const void *callout_info, |
142 | size_t callout_len) | 143 | size_t callout_len, struct key *dest_keyring) |
143 | { | 144 | { |
144 | struct request_key_auth *rka, *irka; | 145 | struct request_key_auth *rka, *irka; |
145 | struct key *authkey = NULL; | 146 | struct key *authkey = NULL; |
@@ -188,6 +189,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, | |||
188 | } | 189 | } |
189 | 190 | ||
190 | rka->target_key = key_get(target); | 191 | rka->target_key = key_get(target); |
192 | rka->dest_keyring = key_get(dest_keyring); | ||
191 | memcpy(rka->callout_info, callout_info, callout_len); | 193 | memcpy(rka->callout_info, callout_info, callout_len); |
192 | rka->callout_len = callout_len; | 194 | rka->callout_len = callout_len; |
193 | 195 | ||
@@ -223,6 +225,7 @@ error_inst: | |||
223 | key_put(authkey); | 225 | key_put(authkey); |
224 | error_alloc: | 226 | error_alloc: |
225 | key_put(rka->target_key); | 227 | key_put(rka->target_key); |
228 | key_put(rka->dest_keyring); | ||
226 | kfree(rka->callout_info); | 229 | kfree(rka->callout_info); |
227 | kfree(rka); | 230 | kfree(rka); |
228 | kleave("= %d", ret); | 231 | kleave("= %d", ret); |