aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/compat.c50
-rw-r--r--security/keys/encrypted.c3
-rw-r--r--security/keys/internal.h8
-rw-r--r--security/keys/key.c27
-rw-r--r--security/keys/keyctl.c143
-rw-r--r--security/keys/keyring.c4
-rw-r--r--security/keys/request_key.c2
-rw-r--r--security/keys/trusted.c3
-rw-r--r--security/keys/user_defined.c3
9 files changed, 217 insertions, 26 deletions
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 07a5f35e397..338b510e902 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -12,9 +12,52 @@
12#include <linux/syscalls.h> 12#include <linux/syscalls.h>
13#include <linux/keyctl.h> 13#include <linux/keyctl.h>
14#include <linux/compat.h> 14#include <linux/compat.h>
15#include <linux/slab.h>
15#include "internal.h" 16#include "internal.h"
16 17
17/* 18/*
19 * Instantiate a key with the specified compatibility multipart payload and
20 * link the key into the destination keyring if one is given.
21 *
22 * The caller must have the appropriate instantiation permit set for this to
23 * work (see keyctl_assume_authority). No other permissions are required.
24 *
25 * If successful, 0 will be returned.
26 */
27long compat_keyctl_instantiate_key_iov(
28 key_serial_t id,
29 const struct compat_iovec __user *_payload_iov,
30 unsigned ioc,
31 key_serial_t ringid)
32{
33 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
34 long ret;
35
36 if (_payload_iov == 0 || ioc == 0)
37 goto no_payload;
38
39 ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc,
40 ARRAY_SIZE(iovstack),
41 iovstack, &iov);
42 if (ret < 0)
43 return ret;
44 if (ret == 0)
45 goto no_payload_free;
46
47 ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
48
49 if (iov != iovstack)
50 kfree(iov);
51 return ret;
52
53no_payload_free:
54 if (iov != iovstack)
55 kfree(iov);
56no_payload:
57 return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid);
58}
59
60/*
18 * The key control system call, 32-bit compatibility version for 64-bit archs 61 * The key control system call, 32-bit compatibility version for 64-bit archs
19 * 62 *
20 * This should only be called if the 64-bit arch uses weird pointers in 32-bit 63 * This should only be called if the 64-bit arch uses weird pointers in 32-bit
@@ -85,6 +128,13 @@ asmlinkage long compat_sys_keyctl(u32 option,
85 case KEYCTL_SESSION_TO_PARENT: 128 case KEYCTL_SESSION_TO_PARENT:
86 return keyctl_session_to_parent(); 129 return keyctl_session_to_parent();
87 130
131 case KEYCTL_REJECT:
132 return keyctl_reject_key(arg2, arg3, arg4, arg5);
133
134 case KEYCTL_INSTANTIATE_IOV:
135 return compat_keyctl_instantiate_key_iov(
136 arg2, compat_ptr(arg3), arg4, arg5);
137
88 default: 138 default:
89 return -EOPNOTSUPP; 139 return -EOPNOTSUPP;
90 } 140 }
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index 9e7e4ce3fae..69907a58a68 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -765,8 +765,7 @@ static long encrypted_read(const struct key *key, char __user *buffer,
765 size_t asciiblob_len; 765 size_t asciiblob_len;
766 int ret; 766 int ret;
767 767
768 epayload = rcu_dereference_protected(key->payload.data, 768 epayload = rcu_dereference_key(key);
769 rwsem_is_locked(&((struct key *)key)->sem));
770 769
771 /* returns the hex encoded iv, encrypted-data, and hmac as ascii */ 770 /* returns the hex encoded iv, encrypted-data, and hmac as ascii */
772 asciiblob_len = epayload->datablob_len + ivsize + 1 771 asciiblob_len = epayload->datablob_len + ivsize + 1
diff --git a/security/keys/internal.h b/security/keys/internal.h
index a52aa7c88b4..07a025f8190 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -214,6 +214,14 @@ extern long keyctl_assume_authority(key_serial_t);
214extern long keyctl_get_security(key_serial_t keyid, char __user *buffer, 214extern long keyctl_get_security(key_serial_t keyid, char __user *buffer,
215 size_t buflen); 215 size_t buflen);
216extern long keyctl_session_to_parent(void); 216extern long keyctl_session_to_parent(void);
217extern long keyctl_reject_key(key_serial_t, unsigned, unsigned, key_serial_t);
218extern long keyctl_instantiate_key_iov(key_serial_t,
219 const struct iovec __user *,
220 unsigned, key_serial_t);
221
222extern long keyctl_instantiate_key_common(key_serial_t,
223 const struct iovec __user *,
224 unsigned, size_t, key_serial_t);
217 225
218/* 226/*
219 * Debugging key validation 227 * Debugging key validation
diff --git a/security/keys/key.c b/security/keys/key.c
index 1c2d43dc510..f7f9d93f08d 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -249,6 +249,14 @@ struct key *key_alloc(struct key_type *type, const char *desc,
249 if (!desc || !*desc) 249 if (!desc || !*desc)
250 goto error; 250 goto error;
251 251
252 if (type->vet_description) {
253 ret = type->vet_description(desc);
254 if (ret < 0) {
255 key = ERR_PTR(ret);
256 goto error;
257 }
258 }
259
252 desclen = strlen(desc) + 1; 260 desclen = strlen(desc) + 1;
253 quotalen = desclen + type->def_datalen; 261 quotalen = desclen + type->def_datalen;
254 262
@@ -503,26 +511,29 @@ int key_instantiate_and_link(struct key *key,
503EXPORT_SYMBOL(key_instantiate_and_link); 511EXPORT_SYMBOL(key_instantiate_and_link);
504 512
505/** 513/**
506 * key_negate_and_link - Negatively instantiate a key and link it into the keyring. 514 * key_reject_and_link - Negatively instantiate a key and link it into the keyring.
507 * @key: The key to instantiate. 515 * @key: The key to instantiate.
508 * @timeout: The timeout on the negative key. 516 * @timeout: The timeout on the negative key.
517 * @error: The error to return when the key is hit.
509 * @keyring: Keyring to create a link in on success (or NULL). 518 * @keyring: Keyring to create a link in on success (or NULL).
510 * @authkey: The authorisation token permitting instantiation. 519 * @authkey: The authorisation token permitting instantiation.
511 * 520 *
512 * Negatively instantiate a key that's in the uninstantiated state and, if 521 * Negatively instantiate a key that's in the uninstantiated state and, if
513 * successful, set its timeout and link it in to the destination keyring if one 522 * successful, set its timeout and stored error and link it in to the
514 * is supplied. The key and any links to the key will be automatically garbage 523 * destination keyring if one is supplied. The key and any links to the key
515 * collected after the timeout expires. 524 * will be automatically garbage collected after the timeout expires.
516 * 525 *
517 * Negative keys are used to rate limit repeated request_key() calls by causing 526 * Negative keys are used to rate limit repeated request_key() calls by causing
518 * them to return -ENOKEY until the negative key expires. 527 * them to return the stored error code (typically ENOKEY) until the negative
528 * key expires.
519 * 529 *
520 * If successful, 0 is returned, the authorisation token is revoked and anyone 530 * If successful, 0 is returned, the authorisation token is revoked and anyone
521 * waiting for the key is woken up. If the key was already instantiated, 531 * waiting for the key is woken up. If the key was already instantiated,
522 * -EBUSY will be returned. 532 * -EBUSY will be returned.
523 */ 533 */
524int key_negate_and_link(struct key *key, 534int key_reject_and_link(struct key *key,
525 unsigned timeout, 535 unsigned timeout,
536 unsigned error,
526 struct key *keyring, 537 struct key *keyring,
527 struct key *authkey) 538 struct key *authkey)
528{ 539{
@@ -548,6 +559,7 @@ int key_negate_and_link(struct key *key,
548 atomic_inc(&key->user->nikeys); 559 atomic_inc(&key->user->nikeys);
549 set_bit(KEY_FLAG_NEGATIVE, &key->flags); 560 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
550 set_bit(KEY_FLAG_INSTANTIATED, &key->flags); 561 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
562 key->type_data.reject_error = -error;
551 now = current_kernel_time(); 563 now = current_kernel_time();
552 key->expiry = now.tv_sec + timeout; 564 key->expiry = now.tv_sec + timeout;
553 key_schedule_gc(key->expiry + key_gc_delay); 565 key_schedule_gc(key->expiry + key_gc_delay);
@@ -577,8 +589,7 @@ int key_negate_and_link(struct key *key,
577 589
578 return ret == 0 ? link_ret : ret; 590 return ret == 0 ? link_ret : ret;
579} 591}
580 592EXPORT_SYMBOL(key_reject_and_link);
581EXPORT_SYMBOL(key_negate_and_link);
582 593
583/* 594/*
584 * Garbage collect keys in process context so that we don't have to disable 595 * Garbage collect keys in process context so that we don't have to disable
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 31a0fd8189f..427fddcaeb1 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -913,6 +913,21 @@ static int keyctl_change_reqkey_auth(struct key *key)
913} 913}
914 914
915/* 915/*
916 * Copy the iovec data from userspace
917 */
918static long copy_from_user_iovec(void *buffer, const struct iovec *iov,
919 unsigned ioc)
920{
921 for (; ioc > 0; ioc--) {
922 if (copy_from_user(buffer, iov->iov_base, iov->iov_len) != 0)
923 return -EFAULT;
924 buffer += iov->iov_len;
925 iov++;
926 }
927 return 0;
928}
929
930/*
916 * Instantiate a key with the specified payload and link the key into the 931 * Instantiate a key with the specified payload and link the key into the
917 * destination keyring if one is given. 932 * destination keyring if one is given.
918 * 933 *
@@ -921,10 +936,11 @@ static int keyctl_change_reqkey_auth(struct key *key)
921 * 936 *
922 * If successful, 0 will be returned. 937 * If successful, 0 will be returned.
923 */ 938 */
924long keyctl_instantiate_key(key_serial_t id, 939long keyctl_instantiate_key_common(key_serial_t id,
925 const void __user *_payload, 940 const struct iovec *payload_iov,
926 size_t plen, 941 unsigned ioc,
927 key_serial_t ringid) 942 size_t plen,
943 key_serial_t ringid)
928{ 944{
929 const struct cred *cred = current_cred(); 945 const struct cred *cred = current_cred();
930 struct request_key_auth *rka; 946 struct request_key_auth *rka;
@@ -953,7 +969,7 @@ long keyctl_instantiate_key(key_serial_t id,
953 /* pull the payload in if one was supplied */ 969 /* pull the payload in if one was supplied */
954 payload = NULL; 970 payload = NULL;
955 971
956 if (_payload) { 972 if (payload_iov) {
957 ret = -ENOMEM; 973 ret = -ENOMEM;
958 payload = kmalloc(plen, GFP_KERNEL); 974 payload = kmalloc(plen, GFP_KERNEL);
959 if (!payload) { 975 if (!payload) {
@@ -965,8 +981,8 @@ long keyctl_instantiate_key(key_serial_t id,
965 goto error; 981 goto error;
966 } 982 }
967 983
968 ret = -EFAULT; 984 ret = copy_from_user_iovec(payload, payload_iov, ioc);
969 if (copy_from_user(payload, _payload, plen) != 0) 985 if (ret < 0)
970 goto error2; 986 goto error2;
971 } 987 }
972 988
@@ -997,6 +1013,72 @@ error:
997} 1013}
998 1014
999/* 1015/*
1016 * Instantiate a key with the specified payload and link the key into the
1017 * destination keyring if one is given.
1018 *
1019 * The caller must have the appropriate instantiation permit set for this to
1020 * work (see keyctl_assume_authority). No other permissions are required.
1021 *
1022 * If successful, 0 will be returned.
1023 */
1024long keyctl_instantiate_key(key_serial_t id,
1025 const void __user *_payload,
1026 size_t plen,
1027 key_serial_t ringid)
1028{
1029 if (_payload && plen) {
1030 struct iovec iov[1] = {
1031 [0].iov_base = (void __user *)_payload,
1032 [0].iov_len = plen
1033 };
1034
1035 return keyctl_instantiate_key_common(id, iov, 1, plen, ringid);
1036 }
1037
1038 return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid);
1039}
1040
1041/*
1042 * Instantiate a key with the specified multipart payload and link the key into
1043 * the destination keyring if one is given.
1044 *
1045 * The caller must have the appropriate instantiation permit set for this to
1046 * work (see keyctl_assume_authority). No other permissions are required.
1047 *
1048 * If successful, 0 will be returned.
1049 */
1050long keyctl_instantiate_key_iov(key_serial_t id,
1051 const struct iovec __user *_payload_iov,
1052 unsigned ioc,
1053 key_serial_t ringid)
1054{
1055 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
1056 long ret;
1057
1058 if (_payload_iov == 0 || ioc == 0)
1059 goto no_payload;
1060
1061 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,
1062 ARRAY_SIZE(iovstack), iovstack, &iov);
1063 if (ret < 0)
1064 return ret;
1065 if (ret == 0)
1066 goto no_payload_free;
1067
1068 ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
1069
1070 if (iov != iovstack)
1071 kfree(iov);
1072 return ret;
1073
1074no_payload_free:
1075 if (iov != iovstack)
1076 kfree(iov);
1077no_payload:
1078 return keyctl_instantiate_key_common(id, NULL, 0, 0, ringid);
1079}
1080
1081/*
1000 * Negatively instantiate the key with the given timeout (in seconds) and link 1082 * Negatively instantiate the key with the given timeout (in seconds) and link
1001 * the key into the destination keyring if one is given. 1083 * the key into the destination keyring if one is given.
1002 * 1084 *
@@ -1013,12 +1095,42 @@ error:
1013 */ 1095 */
1014long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 1096long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
1015{ 1097{
1098 return keyctl_reject_key(id, timeout, ENOKEY, ringid);
1099}
1100
1101/*
1102 * Negatively instantiate the key with the given timeout (in seconds) and error
1103 * code and link the key into the destination keyring if one is given.
1104 *
1105 * The caller must have the appropriate instantiation permit set for this to
1106 * work (see keyctl_assume_authority). No other permissions are required.
1107 *
1108 * The key and any links to the key will be automatically garbage collected
1109 * after the timeout expires.
1110 *
1111 * Negative keys are used to rate limit repeated request_key() calls by causing
1112 * them to return the specified error code until the negative key expires.
1113 *
1114 * If successful, 0 will be returned.
1115 */
1116long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error,
1117 key_serial_t ringid)
1118{
1016 const struct cred *cred = current_cred(); 1119 const struct cred *cred = current_cred();
1017 struct request_key_auth *rka; 1120 struct request_key_auth *rka;
1018 struct key *instkey, *dest_keyring; 1121 struct key *instkey, *dest_keyring;
1019 long ret; 1122 long ret;
1020 1123
1021 kenter("%d,%u,%d", id, timeout, ringid); 1124 kenter("%d,%u,%u,%d", id, timeout, error, ringid);
1125
1126 /* must be a valid error code and mustn't be a kernel special */
1127 if (error <= 0 ||
1128 error >= MAX_ERRNO ||
1129 error == ERESTARTSYS ||
1130 error == ERESTARTNOINTR ||
1131 error == ERESTARTNOHAND ||
1132 error == ERESTART_RESTARTBLOCK)
1133 return -EINVAL;
1022 1134
1023 /* the appropriate instantiation authorisation key must have been 1135 /* the appropriate instantiation authorisation key must have been
1024 * assumed before calling this */ 1136 * assumed before calling this */
@@ -1038,7 +1150,7 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
1038 goto error; 1150 goto error;
1039 1151
1040 /* instantiate the key and link it into a keyring */ 1152 /* instantiate the key and link it into a keyring */
1041 ret = key_negate_and_link(rka->target_key, timeout, 1153 ret = key_reject_and_link(rka->target_key, timeout, error,
1042 dest_keyring, instkey); 1154 dest_keyring, instkey);
1043 1155
1044 key_put(dest_keyring); 1156 key_put(dest_keyring);
@@ -1492,6 +1604,19 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
1492 case KEYCTL_SESSION_TO_PARENT: 1604 case KEYCTL_SESSION_TO_PARENT:
1493 return keyctl_session_to_parent(); 1605 return keyctl_session_to_parent();
1494 1606
1607 case KEYCTL_REJECT:
1608 return keyctl_reject_key((key_serial_t) arg2,
1609 (unsigned) arg3,
1610 (unsigned) arg4,
1611 (key_serial_t) arg5);
1612
1613 case KEYCTL_INSTANTIATE_IOV:
1614 return keyctl_instantiate_key_iov(
1615 (key_serial_t) arg2,
1616 (const struct iovec __user *) arg3,
1617 (unsigned) arg4,
1618 (key_serial_t) arg5);
1619
1495 default: 1620 default:
1496 return -EOPNOTSUPP; 1621 return -EOPNOTSUPP;
1497 } 1622 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 5620f084ded..cdd2f3f88c8 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -352,7 +352,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
352 goto error_2; 352 goto error_2;
353 if (key->expiry && now.tv_sec >= key->expiry) 353 if (key->expiry && now.tv_sec >= key->expiry)
354 goto error_2; 354 goto error_2;
355 key_ref = ERR_PTR(-ENOKEY); 355 key_ref = ERR_PTR(key->type_data.reject_error);
356 if (kflags & (1 << KEY_FLAG_NEGATIVE)) 356 if (kflags & (1 << KEY_FLAG_NEGATIVE))
357 goto error_2; 357 goto error_2;
358 goto found; 358 goto found;
@@ -401,7 +401,7 @@ descend:
401 401
402 /* we set a different error code if we pass a negative key */ 402 /* we set a different error code if we pass a negative key */
403 if (kflags & (1 << KEY_FLAG_NEGATIVE)) { 403 if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
404 err = -ENOKEY; 404 err = key->type_data.reject_error;
405 continue; 405 continue;
406 } 406 }
407 407
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index a3dc0d460de..df3c0417ee4 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -585,7 +585,7 @@ int wait_for_key_construction(struct key *key, bool intr)
585 if (ret < 0) 585 if (ret < 0)
586 return ret; 586 return ret;
587 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 587 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
588 return -ENOKEY; 588 return key->type_data.reject_error;
589 return key_validate(key); 589 return key_validate(key);
590} 590}
591EXPORT_SYMBOL(wait_for_key_construction); 591EXPORT_SYMBOL(wait_for_key_construction);
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 83fc92e297c..c99b9368368 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -1076,8 +1076,7 @@ static long trusted_read(const struct key *key, char __user *buffer,
1076 char *bufp; 1076 char *bufp;
1077 int i; 1077 int i;
1078 1078
1079 p = rcu_dereference_protected(key->payload.data, 1079 p = rcu_dereference_key(key);
1080 rwsem_is_locked(&((struct key *)key)->sem));
1081 if (!p) 1080 if (!p)
1082 return -EINVAL; 1081 return -EINVAL;
1083 if (!buffer || buflen <= 0) 1082 if (!buffer || buflen <= 0)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 02807fb1634..c6ca8662a46 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -184,8 +184,7 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
184 struct user_key_payload *upayload; 184 struct user_key_payload *upayload;
185 long ret; 185 long ret;
186 186
187 upayload = rcu_dereference_protected( 187 upayload = rcu_dereference_key(key);
188 key->payload.data, rwsem_is_locked(&((struct key *)key)->sem));
189 ret = upayload->datalen; 188 ret = upayload->datalen;
190 189
191 /* we can return the data as is */ 190 /* we can return the data as is */