aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/compat.c3
-rw-r--r--security/keys/internal.h4
-rw-r--r--security/keys/keyctl.c107
-rw-r--r--security/keys/keyring.c45
-rw-r--r--security/keys/permission.c32
-rw-r--r--security/keys/process_keys.c71
-rw-r--r--security/keys/request_key.c108
-rw-r--r--security/keys/request_key_auth.c192
8 files changed, 327 insertions, 235 deletions
diff --git a/security/keys/compat.c b/security/keys/compat.c
index e8e7ef4a290c..bcdb28533733 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -77,6 +77,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
77 case KEYCTL_SET_TIMEOUT: 77 case KEYCTL_SET_TIMEOUT:
78 return keyctl_set_timeout(arg2, arg3); 78 return keyctl_set_timeout(arg2, arg3);
79 79
80 case KEYCTL_ASSUME_AUTHORITY:
81 return keyctl_assume_authority(arg2);
82
80 default: 83 default:
81 return -EOPNOTSUPP; 84 return -EOPNOTSUPP;
82 } 85 }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 51f37c0bdb32..e066e6057955 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -107,12 +107,13 @@ extern struct key *request_key_and_link(struct key_type *type,
107struct request_key_auth { 107struct request_key_auth {
108 struct key *target_key; 108 struct key *target_key;
109 struct task_struct *context; 109 struct task_struct *context;
110 const char *callout_info;
110 pid_t pid; 111 pid_t pid;
111}; 112};
112 113
113extern struct key_type key_type_request_key_auth; 114extern struct key_type key_type_request_key_auth;
114extern struct key *request_key_auth_new(struct key *target, 115extern struct key *request_key_auth_new(struct key *target,
115 struct key **_rkakey); 116 const char *callout_info);
116 117
117extern struct key *key_get_instantiation_authkey(key_serial_t target_id); 118extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
118 119
@@ -137,6 +138,7 @@ extern long keyctl_instantiate_key(key_serial_t, const void __user *,
137extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 138extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
138extern long keyctl_set_reqkey_keyring(int); 139extern long keyctl_set_reqkey_keyring(int);
139extern long keyctl_set_timeout(key_serial_t, unsigned); 140extern long keyctl_set_timeout(key_serial_t, unsigned);
141extern long keyctl_assume_authority(key_serial_t);
140 142
141 143
142/* 144/*
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 299f0ae11cf0..3d2ebae029c1 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -834,6 +834,17 @@ long keyctl_instantiate_key(key_serial_t id,
834 if (plen > 32767) 834 if (plen > 32767)
835 goto error; 835 goto error;
836 836
837 /* the appropriate instantiation authorisation key must have been
838 * assumed before calling this */
839 ret = -EPERM;
840 instkey = current->request_key_auth;
841 if (!instkey)
842 goto error;
843
844 rka = instkey->payload.data;
845 if (rka->target_key->serial != id)
846 goto error;
847
837 /* pull the payload in if one was supplied */ 848 /* pull the payload in if one was supplied */
838 payload = NULL; 849 payload = NULL;
839 850
@@ -848,15 +859,6 @@ long keyctl_instantiate_key(key_serial_t id,
848 goto error2; 859 goto error2;
849 } 860 }
850 861
851 /* find the instantiation authorisation key */
852 instkey = key_get_instantiation_authkey(id);
853 if (IS_ERR(instkey)) {
854 ret = PTR_ERR(instkey);
855 goto error2;
856 }
857
858 rka = instkey->payload.data;
859
860 /* find the destination keyring amongst those belonging to the 862 /* find the destination keyring amongst those belonging to the
861 * requesting task */ 863 * requesting task */
862 keyring_ref = NULL; 864 keyring_ref = NULL;
@@ -865,7 +867,7 @@ long keyctl_instantiate_key(key_serial_t id,
865 KEY_WRITE); 867 KEY_WRITE);
866 if (IS_ERR(keyring_ref)) { 868 if (IS_ERR(keyring_ref)) {
867 ret = PTR_ERR(keyring_ref); 869 ret = PTR_ERR(keyring_ref);
868 goto error3; 870 goto error2;
869 } 871 }
870 } 872 }
871 873
@@ -874,11 +876,17 @@ long keyctl_instantiate_key(key_serial_t id,
874 key_ref_to_ptr(keyring_ref), instkey); 876 key_ref_to_ptr(keyring_ref), instkey);
875 877
876 key_ref_put(keyring_ref); 878 key_ref_put(keyring_ref);
877 error3: 879
878 key_put(instkey); 880 /* discard the assumed authority if it's just been disabled by
879 error2: 881 * instantiation of the key */
882 if (ret == 0) {
883 key_put(current->request_key_auth);
884 current->request_key_auth = NULL;
885 }
886
887error2:
880 kfree(payload); 888 kfree(payload);
881 error: 889error:
882 return ret; 890 return ret;
883 891
884} /* end keyctl_instantiate_key() */ 892} /* end keyctl_instantiate_key() */
@@ -895,14 +903,16 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
895 key_ref_t keyring_ref; 903 key_ref_t keyring_ref;
896 long ret; 904 long ret;
897 905
898 /* find the instantiation authorisation key */ 906 /* the appropriate instantiation authorisation key must have been
899 instkey = key_get_instantiation_authkey(id); 907 * assumed before calling this */
900 if (IS_ERR(instkey)) { 908 ret = -EPERM;
901 ret = PTR_ERR(instkey); 909 instkey = current->request_key_auth;
910 if (!instkey)
902 goto error; 911 goto error;
903 }
904 912
905 rka = instkey->payload.data; 913 rka = instkey->payload.data;
914 if (rka->target_key->serial != id)
915 goto error;
906 916
907 /* find the destination keyring if present (which must also be 917 /* find the destination keyring if present (which must also be
908 * writable) */ 918 * writable) */
@@ -911,7 +921,7 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
911 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 921 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
912 if (IS_ERR(keyring_ref)) { 922 if (IS_ERR(keyring_ref)) {
913 ret = PTR_ERR(keyring_ref); 923 ret = PTR_ERR(keyring_ref);
914 goto error2; 924 goto error;
915 } 925 }
916 } 926 }
917 927
@@ -920,9 +930,15 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
920 key_ref_to_ptr(keyring_ref), instkey); 930 key_ref_to_ptr(keyring_ref), instkey);
921 931
922 key_ref_put(keyring_ref); 932 key_ref_put(keyring_ref);
923 error2: 933
924 key_put(instkey); 934 /* discard the assumed authority if it's just been disabled by
925 error: 935 * instantiation of the key */
936 if (ret == 0) {
937 key_put(current->request_key_auth);
938 current->request_key_auth = NULL;
939 }
940
941error:
926 return ret; 942 return ret;
927 943
928} /* end keyctl_negate_key() */ 944} /* end keyctl_negate_key() */
@@ -1007,6 +1023,48 @@ error:
1007 1023
1008/*****************************************************************************/ 1024/*****************************************************************************/
1009/* 1025/*
1026 * assume the authority to instantiate the specified key
1027 */
1028long keyctl_assume_authority(key_serial_t id)
1029{
1030 struct key *authkey;
1031 long ret;
1032
1033 /* special key IDs aren't permitted */
1034 ret = -EINVAL;
1035 if (id < 0)
1036 goto error;
1037
1038 /* we divest ourselves of authority if given an ID of 0 */
1039 if (id == 0) {
1040 key_put(current->request_key_auth);
1041 current->request_key_auth = NULL;
1042 ret = 0;
1043 goto error;
1044 }
1045
1046 /* attempt to assume the authority temporarily granted to us whilst we
1047 * instantiate the specified key
1048 * - the authorisation key must be in the current task's keyrings
1049 * somewhere
1050 */
1051 authkey = key_get_instantiation_authkey(id);
1052 if (IS_ERR(authkey)) {
1053 ret = PTR_ERR(authkey);
1054 goto error;
1055 }
1056
1057 key_put(current->request_key_auth);
1058 current->request_key_auth = authkey;
1059 ret = authkey->serial;
1060
1061error:
1062 return ret;
1063
1064} /* end keyctl_assume_authority() */
1065
1066/*****************************************************************************/
1067/*
1010 * the key control system call 1068 * the key control system call
1011 */ 1069 */
1012asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 1070asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -1082,6 +1140,9 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
1082 return keyctl_set_timeout((key_serial_t) arg2, 1140 return keyctl_set_timeout((key_serial_t) arg2,
1083 (unsigned) arg3); 1141 (unsigned) arg3);
1084 1142
1143 case KEYCTL_ASSUME_AUTHORITY:
1144 return keyctl_assume_authority((key_serial_t) arg2);
1145
1085 default: 1146 default:
1086 return -EOPNOTSUPP; 1147 return -EOPNOTSUPP;
1087 } 1148 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 09d92d52ef75..d65a180f888d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -481,51 +481,6 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
481 481
482/*****************************************************************************/ 482/*****************************************************************************/
483/* 483/*
484 * search for an instantiation authorisation key matching a target key
485 * - the RCU read lock must be held by the caller
486 * - a target_id of zero specifies any valid token
487 */
488struct key *keyring_search_instkey(struct key *keyring,
489 key_serial_t target_id)
490{
491 struct request_key_auth *rka;
492 struct keyring_list *klist;
493 struct key *instkey;
494 int loop;
495
496 klist = rcu_dereference(keyring->payload.subscriptions);
497 if (klist) {
498 for (loop = 0; loop < klist->nkeys; loop++) {
499 instkey = klist->keys[loop];
500
501 if (instkey->type != &key_type_request_key_auth)
502 continue;
503
504 rka = instkey->payload.data;
505 if (target_id && rka->target_key->serial != target_id)
506 continue;
507
508 /* the auth key is revoked during instantiation */
509 if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
510 goto found;
511
512 instkey = ERR_PTR(-EKEYREVOKED);
513 goto error;
514 }
515 }
516
517 instkey = ERR_PTR(-EACCES);
518 goto error;
519
520found:
521 atomic_inc(&instkey->usage);
522error:
523 return instkey;
524
525} /* end keyring_search_instkey() */
526
527/*****************************************************************************/
528/*
529 * find a keyring with the specified name 484 * find a keyring with the specified name
530 * - all named keyrings are searched 485 * - all named keyrings are searched
531 * - only find keyrings with search permission for the process 486 * - only find keyrings with search permission for the process
diff --git a/security/keys/permission.c b/security/keys/permission.c
index e7f579c0eaf5..3b41f9b52537 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -73,3 +73,35 @@ use_these_perms:
73} /* end key_task_permission() */ 73} /* end key_task_permission() */
74 74
75EXPORT_SYMBOL(key_task_permission); 75EXPORT_SYMBOL(key_task_permission);
76
77/*****************************************************************************/
78/*
79 * validate a key
80 */
81int key_validate(struct key *key)
82{
83 struct timespec now;
84 int ret = 0;
85
86 if (key) {
87 /* check it's still accessible */
88 ret = -EKEYREVOKED;
89 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
90 test_bit(KEY_FLAG_DEAD, &key->flags))
91 goto error;
92
93 /* check it hasn't expired */
94 ret = 0;
95 if (key->expiry) {
96 now = current_kernel_time();
97 if (now.tv_sec >= key->expiry)
98 ret = -EKEYEXPIRED;
99 }
100 }
101
102 error:
103 return ret;
104
105} /* end key_validate() */
106
107EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 566b1cc0118a..74cb79eb917e 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -270,9 +270,14 @@ int copy_thread_group_keys(struct task_struct *tsk)
270int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 270int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
271{ 271{
272 key_check(tsk->thread_keyring); 272 key_check(tsk->thread_keyring);
273 key_check(tsk->request_key_auth);
273 274
274 /* no thread keyring yet */ 275 /* no thread keyring yet */
275 tsk->thread_keyring = NULL; 276 tsk->thread_keyring = NULL;
277
278 /* copy the request_key() authorisation for this thread */
279 key_get(tsk->request_key_auth);
280
276 return 0; 281 return 0;
277 282
278} /* end copy_keys() */ 283} /* end copy_keys() */
@@ -290,11 +295,12 @@ void exit_thread_group_keys(struct signal_struct *tg)
290 295
291/*****************************************************************************/ 296/*****************************************************************************/
292/* 297/*
293 * dispose of keys upon thread exit 298 * dispose of per-thread keys upon thread exit
294 */ 299 */
295void exit_keys(struct task_struct *tsk) 300void exit_keys(struct task_struct *tsk)
296{ 301{
297 key_put(tsk->thread_keyring); 302 key_put(tsk->thread_keyring);
303 key_put(tsk->request_key_auth);
298 304
299} /* end exit_keys() */ 305} /* end exit_keys() */
300 306
@@ -382,7 +388,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
382 struct task_struct *context) 388 struct task_struct *context)
383{ 389{
384 struct request_key_auth *rka; 390 struct request_key_auth *rka;
385 key_ref_t key_ref, ret, err, instkey_ref; 391 key_ref_t key_ref, ret, err;
386 392
387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
388 * searchable, but we failed to find a key or we found a negative key; 394 * searchable, but we failed to find a key or we found a negative key;
@@ -461,30 +467,12 @@ key_ref_t search_process_keyrings(struct key_type *type,
461 err = key_ref; 467 err = key_ref;
462 break; 468 break;
463 } 469 }
464 470 }
465 /* if this process has a session keyring and that has an 471 /* or search the user-session keyring */
466 * instantiation authorisation key in the bottom level, then we 472 else {
467 * also search the keyrings of the process mentioned there */ 473 key_ref = keyring_search_aux(
468 if (context != current) 474 make_key_ref(context->user->session_keyring, 1),
469 goto no_key; 475 context, type, description, match);
470
471 rcu_read_lock();
472 instkey_ref = __keyring_search_one(
473 make_key_ref(rcu_dereference(
474 context->signal->session_keyring),
475 1),
476 &key_type_request_key_auth, NULL, 0);
477 rcu_read_unlock();
478
479 if (IS_ERR(instkey_ref))
480 goto no_key;
481
482 rka = key_ref_to_ptr(instkey_ref)->payload.data;
483
484 key_ref = search_process_keyrings(type, description, match,
485 rka->context);
486 key_ref_put(instkey_ref);
487
488 if (!IS_ERR(key_ref)) 476 if (!IS_ERR(key_ref))
489 goto found; 477 goto found;
490 478
@@ -500,11 +488,21 @@ key_ref_t search_process_keyrings(struct key_type *type,
500 break; 488 break;
501 } 489 }
502 } 490 }
503 /* or search the user-session keyring */ 491
504 else { 492 /* if this process has an instantiation authorisation key, then we also
505 key_ref = keyring_search_aux( 493 * search the keyrings of the process mentioned there
506 make_key_ref(context->user->session_keyring, 1), 494 * - we don't permit access to request_key auth keys via this method
507 context, type, description, match); 495 */
496 if (context->request_key_auth &&
497 context == current &&
498 type != &key_type_request_key_auth &&
499 key_validate(context->request_key_auth) == 0
500 ) {
501 rka = context->request_key_auth->payload.data;
502
503 key_ref = search_process_keyrings(type, description, match,
504 rka->context);
505
508 if (!IS_ERR(key_ref)) 506 if (!IS_ERR(key_ref))
509 goto found; 507 goto found;
510 508
@@ -521,8 +519,6 @@ key_ref_t search_process_keyrings(struct key_type *type,
521 } 519 }
522 } 520 }
523 521
524
525no_key:
526 /* no key - decide on the error we're going to go for */ 522 /* no key - decide on the error we're going to go for */
527 key_ref = ret ? ret : err; 523 key_ref = ret ? ret : err;
528 524
@@ -628,6 +624,15 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
628 key = ERR_PTR(-EINVAL); 624 key = ERR_PTR(-EINVAL);
629 goto error; 625 goto error;
630 626
627 case KEY_SPEC_REQKEY_AUTH_KEY:
628 key = context->request_key_auth;
629 if (!key)
630 goto error;
631
632 atomic_inc(&key->usage);
633 key_ref = make_key_ref(key, 1);
634 break;
635
631 default: 636 default:
632 key_ref = ERR_PTR(-EINVAL); 637 key_ref = ERR_PTR(-EINVAL);
633 if (id < 1) 638 if (id < 1)
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 5cc4bba70db6..f030a0ccbb93 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -29,28 +29,36 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
29/*****************************************************************************/ 29/*****************************************************************************/
30/* 30/*
31 * request userspace finish the construction of a key 31 * request userspace finish the construction of a key
32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>" 32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
33 */ 33 */
34static int call_request_key(struct key *key, 34static int call_sbin_request_key(struct key *key,
35 const char *op, 35 struct key *authkey,
36 const char *callout_info) 36 const char *op)
37{ 37{
38 struct task_struct *tsk = current; 38 struct task_struct *tsk = current;
39 key_serial_t prkey, sskey; 39 key_serial_t prkey, sskey;
40 struct key *session_keyring, *rkakey; 40 struct key *keyring;
41 char *argv[10], *envp[3], uid_str[12], gid_str[12]; 41 char *argv[9], *envp[3], uid_str[12], gid_str[12];
42 char key_str[12], keyring_str[3][12]; 42 char key_str[12], keyring_str[3][12];
43 char desc[20];
43 int ret, i; 44 int ret, i;
44 45
45 kenter("{%d},%s,%s", key->serial, op, callout_info); 46 kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
46 47
47 /* generate a new session keyring with an auth key in it */ 48 /* allocate a new session keyring */
48 session_keyring = request_key_auth_new(key, &rkakey); 49 sprintf(desc, "_req.%u", key->serial);
49 if (IS_ERR(session_keyring)) { 50
50 ret = PTR_ERR(session_keyring); 51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
51 goto error; 52 if (IS_ERR(keyring)) {
53 ret = PTR_ERR(keyring);
54 goto error_alloc;
52 } 55 }
53 56
57 /* attach the auth key to the session keyring */
58 ret = __key_link(keyring, authkey);
59 if (ret < 0)
60 goto error_link;
61
54 /* record the UID and GID */ 62 /* record the UID and GID */
55 sprintf(uid_str, "%d", current->fsuid); 63 sprintf(uid_str, "%d", current->fsuid);
56 sprintf(gid_str, "%d", current->fsgid); 64 sprintf(gid_str, "%d", current->fsgid);
@@ -95,22 +103,19 @@ static int call_request_key(struct key *key,
95 argv[i++] = keyring_str[0]; 103 argv[i++] = keyring_str[0];
96 argv[i++] = keyring_str[1]; 104 argv[i++] = keyring_str[1];
97 argv[i++] = keyring_str[2]; 105 argv[i++] = keyring_str[2];
98 argv[i++] = (char *) callout_info;
99 argv[i] = NULL; 106 argv[i] = NULL;
100 107
101 /* do it */ 108 /* do it */
102 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1); 109 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1);
103 110
104 /* dispose of the special keys */ 111error_link:
105 key_revoke(rkakey); 112 key_put(keyring);
106 key_put(rkakey);
107 key_put(session_keyring);
108 113
109 error: 114error_alloc:
110 kleave(" = %d", ret); 115 kleave(" = %d", ret);
111 return ret; 116 return ret;
112 117
113} /* end call_request_key() */ 118} /* end call_sbin_request_key() */
114 119
115/*****************************************************************************/ 120/*****************************************************************************/
116/* 121/*
@@ -122,9 +127,10 @@ static struct key *__request_key_construction(struct key_type *type,
122 const char *description, 127 const char *description,
123 const char *callout_info) 128 const char *callout_info)
124{ 129{
130 request_key_actor_t actor;
125 struct key_construction cons; 131 struct key_construction cons;
126 struct timespec now; 132 struct timespec now;
127 struct key *key; 133 struct key *key, *authkey;
128 int ret, negated; 134 int ret, negated;
129 135
130 kenter("%s,%s,%s", type->name, description, callout_info); 136 kenter("%s,%s,%s", type->name, description, callout_info);
@@ -143,8 +149,19 @@ static struct key *__request_key_construction(struct key_type *type,
143 /* we drop the construction sem here on behalf of the caller */ 149 /* we drop the construction sem here on behalf of the caller */
144 up_write(&key_construction_sem); 150 up_write(&key_construction_sem);
145 151
152 /* allocate an authorisation key */
153 authkey = request_key_auth_new(key, callout_info);
154 if (IS_ERR(authkey)) {
155 ret = PTR_ERR(authkey);
156 authkey = NULL;
157 goto alloc_authkey_failed;
158 }
159
146 /* make the call */ 160 /* make the call */
147 ret = call_request_key(key, "create", callout_info); 161 actor = call_sbin_request_key;
162 if (type->request_key)
163 actor = type->request_key;
164 ret = actor(key, authkey, "create");
148 if (ret < 0) 165 if (ret < 0)
149 goto request_failed; 166 goto request_failed;
150 167
@@ -153,22 +170,29 @@ static struct key *__request_key_construction(struct key_type *type,
153 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 170 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
154 goto request_failed; 171 goto request_failed;
155 172
173 key_revoke(authkey);
174 key_put(authkey);
175
156 down_write(&key_construction_sem); 176 down_write(&key_construction_sem);
157 list_del(&cons.link); 177 list_del(&cons.link);
158 up_write(&key_construction_sem); 178 up_write(&key_construction_sem);
159 179
160 /* also give an error if the key was negatively instantiated */ 180 /* also give an error if the key was negatively instantiated */
161 check_not_negative: 181check_not_negative:
162 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 182 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
163 key_put(key); 183 key_put(key);
164 key = ERR_PTR(-ENOKEY); 184 key = ERR_PTR(-ENOKEY);
165 } 185 }
166 186
167 out: 187out:
168 kleave(" = %p", key); 188 kleave(" = %p", key);
169 return key; 189 return key;
170 190
171 request_failed: 191request_failed:
192 key_revoke(authkey);
193 key_put(authkey);
194
195alloc_authkey_failed:
172 /* it wasn't instantiated 196 /* it wasn't instantiated
173 * - remove from construction queue 197 * - remove from construction queue
174 * - mark the key as dead 198 * - mark the key as dead
@@ -217,7 +241,7 @@ static struct key *__request_key_construction(struct key_type *type,
217 key = ERR_PTR(ret); 241 key = ERR_PTR(ret);
218 goto out; 242 goto out;
219 243
220 alloc_failed: 244alloc_failed:
221 up_write(&key_construction_sem); 245 up_write(&key_construction_sem);
222 goto out; 246 goto out;
223 247
@@ -464,35 +488,3 @@ struct key *request_key(struct key_type *type,
464} /* end request_key() */ 488} /* end request_key() */
465 489
466EXPORT_SYMBOL(request_key); 490EXPORT_SYMBOL(request_key);
467
468/*****************************************************************************/
469/*
470 * validate a key
471 */
472int key_validate(struct key *key)
473{
474 struct timespec now;
475 int ret = 0;
476
477 if (key) {
478 /* check it's still accessible */
479 ret = -EKEYREVOKED;
480 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
481 test_bit(KEY_FLAG_DEAD, &key->flags))
482 goto error;
483
484 /* check it hasn't expired */
485 ret = 0;
486 if (key->expiry) {
487 now = current_kernel_time();
488 if (now.tv_sec >= key->expiry)
489 ret = -EKEYEXPIRED;
490 }
491 }
492
493 error:
494 return ret;
495
496} /* end key_validate() */
497
498EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index a8e4069d48cb..cce6ba6b0323 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -15,11 +15,13 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18#include <asm/uaccess.h>
18#include "internal.h" 19#include "internal.h"
19 20
20static int request_key_auth_instantiate(struct key *, const void *, size_t); 21static int request_key_auth_instantiate(struct key *, const void *, size_t);
21static void request_key_auth_describe(const struct key *, struct seq_file *); 22static void request_key_auth_describe(const struct key *, struct seq_file *);
22static void request_key_auth_destroy(struct key *); 23static void request_key_auth_destroy(struct key *);
24static long request_key_auth_read(const struct key *, char __user *, size_t);
23 25
24/* 26/*
25 * the request-key authorisation key type definition 27 * the request-key authorisation key type definition
@@ -30,51 +32,25 @@ struct key_type key_type_request_key_auth = {
30 .instantiate = request_key_auth_instantiate, 32 .instantiate = request_key_auth_instantiate,
31 .describe = request_key_auth_describe, 33 .describe = request_key_auth_describe,
32 .destroy = request_key_auth_destroy, 34 .destroy = request_key_auth_destroy,
35 .read = request_key_auth_read,
33}; 36};
34 37
35/*****************************************************************************/ 38/*****************************************************************************/
36/* 39/*
37 * instantiate a request-key authorisation record 40 * instantiate a request-key authorisation key
38 */ 41 */
39static int request_key_auth_instantiate(struct key *key, 42static int request_key_auth_instantiate(struct key *key,
40 const void *data, 43 const void *data,
41 size_t datalen) 44 size_t datalen)
42{ 45{
43 struct request_key_auth *rka, *irka; 46 key->payload.data = (struct request_key_auth *) data;
44 struct key *instkey; 47 return 0;
45 int ret;
46
47 ret = -ENOMEM;
48 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
49 if (rka) {
50 /* see if the calling process is already servicing the key
51 * request of another process */
52 instkey = key_get_instantiation_authkey(0);
53 if (!IS_ERR(instkey)) {
54 /* it is - use that instantiation context here too */
55 irka = instkey->payload.data;
56 rka->context = irka->context;
57 rka->pid = irka->pid;
58 key_put(instkey);
59 }
60 else {
61 /* it isn't - use this process as the context */
62 rka->context = current;
63 rka->pid = current->pid;
64 }
65
66 rka->target_key = key_get((struct key *) data);
67 key->payload.data = rka;
68 ret = 0;
69 }
70
71 return ret;
72 48
73} /* end request_key_auth_instantiate() */ 49} /* end request_key_auth_instantiate() */
74 50
75/*****************************************************************************/ 51/*****************************************************************************/
76/* 52/*
77 * 53 * reading a request-key authorisation key retrieves the callout information
78 */ 54 */
79static void request_key_auth_describe(const struct key *key, 55static void request_key_auth_describe(const struct key *key,
80 struct seq_file *m) 56 struct seq_file *m)
@@ -83,12 +59,40 @@ static void request_key_auth_describe(const struct key *key,
83 59
84 seq_puts(m, "key:"); 60 seq_puts(m, "key:");
85 seq_puts(m, key->description); 61 seq_puts(m, key->description);
86 seq_printf(m, " pid:%d", rka->pid); 62 seq_printf(m, " pid:%d ci:%zu", rka->pid, strlen(rka->callout_info));
87 63
88} /* end request_key_auth_describe() */ 64} /* end request_key_auth_describe() */
89 65
90/*****************************************************************************/ 66/*****************************************************************************/
91/* 67/*
68 * read the callout_info data
69 * - the key's semaphore is read-locked
70 */
71static long request_key_auth_read(const struct key *key,
72 char __user *buffer, size_t buflen)
73{
74 struct request_key_auth *rka = key->payload.data;
75 size_t datalen;
76 long ret;
77
78 datalen = strlen(rka->callout_info);
79 ret = datalen;
80
81 /* we can return the data as is */
82 if (buffer && buflen > 0) {
83 if (buflen > datalen)
84 buflen = datalen;
85
86 if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
87 ret = -EFAULT;
88 }
89
90 return ret;
91
92} /* end request_key_auth_read() */
93
94/*****************************************************************************/
95/*
92 * destroy an instantiation authorisation token key 96 * destroy an instantiation authorisation token key
93 */ 97 */
94static void request_key_auth_destroy(struct key *key) 98static void request_key_auth_destroy(struct key *key)
@@ -104,56 +108,89 @@ static void request_key_auth_destroy(struct key *key)
104 108
105/*****************************************************************************/ 109/*****************************************************************************/
106/* 110/*
107 * create a session keyring to be for the invokation of /sbin/request-key and 111 * create an authorisation token for /sbin/request-key or whoever to gain
108 * stick an authorisation token in it 112 * access to the caller's security data
109 */ 113 */
110struct key *request_key_auth_new(struct key *target, struct key **_rkakey) 114struct key *request_key_auth_new(struct key *target, const char *callout_info)
111{ 115{
112 struct key *keyring, *rkakey = NULL; 116 struct request_key_auth *rka, *irka;
117 struct key *authkey = NULL;
113 char desc[20]; 118 char desc[20];
114 int ret; 119 int ret;
115 120
116 kenter("%d,", target->serial); 121 kenter("%d,", target->serial);
117 122
118 /* allocate a new session keyring */ 123 /* allocate a auth record */
119 sprintf(desc, "_req.%u", target->serial); 124 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
125 if (!rka) {
126 kleave(" = -ENOMEM");
127 return ERR_PTR(-ENOMEM);
128 }
120 129
121 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); 130 /* see if the calling process is already servicing the key request of
122 if (IS_ERR(keyring)) { 131 * another process */
123 kleave("= %ld", PTR_ERR(keyring)); 132 if (current->request_key_auth) {
124 return keyring; 133 /* it is - use that instantiation context here too */
134 irka = current->request_key_auth->payload.data;
135 rka->context = irka->context;
136 rka->pid = irka->pid;
125 } 137 }
138 else {
139 /* it isn't - use this process as the context */
140 rka->context = current;
141 rka->pid = current->pid;
142 }
143
144 rka->target_key = key_get(target);
145 rka->callout_info = callout_info;
126 146
127 /* allocate the auth key */ 147 /* allocate the auth key */
128 sprintf(desc, "%x", target->serial); 148 sprintf(desc, "%x", target->serial);
129 149
130 rkakey = key_alloc(&key_type_request_key_auth, desc, 150 authkey = key_alloc(&key_type_request_key_auth, desc,
131 current->fsuid, current->fsgid, 151 current->fsuid, current->fsgid,
132 KEY_POS_VIEW | KEY_USR_VIEW, 1); 152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
133 if (IS_ERR(rkakey)) { 153 KEY_USR_VIEW, 1);
134 key_put(keyring); 154 if (IS_ERR(authkey)) {
135 kleave("= %ld", PTR_ERR(rkakey)); 155 ret = PTR_ERR(authkey);
136 return rkakey; 156 goto error_alloc;
137 } 157 }
138 158
139 /* construct and attach to the keyring */ 159 /* construct and attach to the keyring */
140 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL); 160 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
141 if (ret < 0) { 161 if (ret < 0)
142 key_revoke(rkakey); 162 goto error_inst;
143 key_put(rkakey);
144 key_put(keyring);
145 kleave("= %d", ret);
146 return ERR_PTR(ret);
147 }
148 163
149 *_rkakey = rkakey; 164 kleave(" = {%d})", authkey->serial);
150 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial); 165 return authkey;
151 return keyring; 166
167error_inst:
168 key_revoke(authkey);
169 key_put(authkey);
170error_alloc:
171 key_put(rka->target_key);
172 kfree(rka);
173 kleave("= %d", ret);
174 return ERR_PTR(ret);
152 175
153} /* end request_key_auth_new() */ 176} /* end request_key_auth_new() */
154 177
155/*****************************************************************************/ 178/*****************************************************************************/
156/* 179/*
180 * see if an authorisation key is associated with a particular key
181 */
182static int key_get_instantiation_authkey_match(const struct key *key,
183 const void *_id)
184{
185 struct request_key_auth *rka = key->payload.data;
186 key_serial_t id = (key_serial_t)(unsigned long) _id;
187
188 return rka->target_key->serial == id;
189
190} /* end key_get_instantiation_authkey_match() */
191
192/*****************************************************************************/
193/*
157 * get the authorisation key for instantiation of a specific key if attached to 194 * get the authorisation key for instantiation of a specific key if attached to
158 * the current process's keyrings 195 * the current process's keyrings
159 * - this key is inserted into a keyring and that is set as /sbin/request-key's 196 * - this key is inserted into a keyring and that is set as /sbin/request-key's
@@ -162,22 +199,27 @@ struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
162 */ 199 */
163struct key *key_get_instantiation_authkey(key_serial_t target_id) 200struct key *key_get_instantiation_authkey(key_serial_t target_id)
164{ 201{
165 struct task_struct *tsk = current; 202 struct key *authkey;
166 struct key *instkey; 203 key_ref_t authkey_ref;
167 204
168 /* we must have our own personal session keyring */ 205 authkey_ref = search_process_keyrings(
169 if (!tsk->signal->session_keyring) 206 &key_type_request_key_auth,
170 return ERR_PTR(-EACCES); 207 (void *) (unsigned long) target_id,
171 208 key_get_instantiation_authkey_match,
172 /* and it must contain a suitable request authorisation key 209 current);
173 * - lock RCU against session keyring changing 210
174 */ 211 if (IS_ERR(authkey_ref)) {
175 rcu_read_lock(); 212 authkey = ERR_PTR(PTR_ERR(authkey_ref));
213 goto error;
214 }
176 215
177 instkey = keyring_search_instkey( 216 authkey = key_ref_to_ptr(authkey_ref);
178 rcu_dereference(tsk->signal->session_keyring), target_id); 217 if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
218 key_put(authkey);
219 authkey = ERR_PTR(-EKEYREVOKED);
220 }
179 221
180 rcu_read_unlock(); 222error:
181 return instkey; 223 return authkey;
182 224
183} /* end key_get_instantiation_authkey() */ 225} /* end key_get_instantiation_authkey() */