aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-07-24 07:36:19 -0400
committerJames Morris <james.l.morris@oracle.com>2014-07-24 07:36:19 -0400
commit4ca332e11df42604e784bd7da9e483160636d05e (patch)
tree82e6ba6dff978edc2132e751c19197de50218c7e /security
parent6d6f3328422a3bc56b0d8dd026a5de845d2abfa7 (diff)
parent633706a2ee81637be37b6bc02c5336950cc163b5 (diff)
Merge tag 'keys-next-20140722' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into next
Diffstat (limited to 'security')
-rw-r--r--security/integrity/digsig.c28
-rw-r--r--security/integrity/ima/Kconfig10
-rw-r--r--security/integrity/ima/ima.h12
-rw-r--r--security/integrity/ima/ima_main.c10
-rw-r--r--security/integrity/integrity.h5
-rw-r--r--security/keys/big_key.c41
-rw-r--r--security/keys/encrypted-keys/encrypted.c2
-rw-r--r--security/keys/key.c49
-rw-r--r--security/keys/keyctl.c21
-rw-r--r--security/keys/keyring.c34
-rw-r--r--security/keys/request_key_auth.c13
-rw-r--r--security/keys/user_defined.c41
12 files changed, 209 insertions, 57 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index b4af4ebc5be2..8d4fbff8b87c 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -13,7 +13,9 @@
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 14
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/sched.h>
16#include <linux/rbtree.h> 17#include <linux/rbtree.h>
18#include <linux/cred.h>
17#include <linux/key-type.h> 19#include <linux/key-type.h>
18#include <linux/digsig.h> 20#include <linux/digsig.h>
19 21
@@ -24,7 +26,11 @@ static struct key *keyring[INTEGRITY_KEYRING_MAX];
24static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { 26static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
25 "_evm", 27 "_evm",
26 "_module", 28 "_module",
29#ifndef CONFIG_IMA_TRUSTED_KEYRING
27 "_ima", 30 "_ima",
31#else
32 ".ima",
33#endif
28}; 34};
29 35
30int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 36int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
@@ -56,3 +62,25 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
56 62
57 return -EOPNOTSUPP; 63 return -EOPNOTSUPP;
58} 64}
65
66int integrity_init_keyring(const unsigned int id)
67{
68 const struct cred *cred = current_cred();
69 int err = 0;
70
71 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
72 KGIDT_INIT(0), cred,
73 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
74 KEY_USR_VIEW | KEY_USR_READ |
75 KEY_USR_WRITE | KEY_USR_SEARCH),
76 KEY_ALLOC_NOT_IN_QUOTA, NULL);
77 if (!IS_ERR(keyring[id]))
78 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags);
79 else {
80 err = PTR_ERR(keyring[id]);
81 pr_info("Can't allocate %s keyring (%d)\n",
82 keyring_name[id], err);
83 keyring[id] = NULL;
84 }
85 return err;
86}
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 81a27971d884..08758fbd496f 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -123,3 +123,13 @@ config IMA_APPRAISE
123 For more information on integrity appraisal refer to: 123 For more information on integrity appraisal refer to:
124 <http://linux-ima.sourceforge.net> 124 <http://linux-ima.sourceforge.net>
125 If unsure, say N. 125 If unsure, say N.
126
127config IMA_TRUSTED_KEYRING
128 bool "Require all keys on the .ima keyring be signed"
129 depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
130 depends on INTEGRITY_ASYMMETRIC_KEYS
131 select KEYS_DEBUG_PROC_KEYS
132 default y
133 help
134 This option requires that all keys added to the .ima
135 keyring be signed by a key on the system trusted keyring.
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index f79fa8be203c..c42056edfc97 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -249,4 +249,16 @@ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
249 return -EINVAL; 249 return -EINVAL;
250} 250}
251#endif /* CONFIG_IMA_LSM_RULES */ 251#endif /* CONFIG_IMA_LSM_RULES */
252
253#ifdef CONFIG_IMA_TRUSTED_KEYRING
254static inline int ima_init_keyring(const unsigned int id)
255{
256 return integrity_init_keyring(id);
257}
258#else
259static inline int ima_init_keyring(const unsigned int id)
260{
261 return 0;
262}
263#endif /* CONFIG_IMA_TRUSTED_KEYRING */
252#endif 264#endif
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f474c608fa11..0d696431209c 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -325,8 +325,14 @@ static int __init init_ima(void)
325 325
326 hash_setup(CONFIG_IMA_DEFAULT_HASH); 326 hash_setup(CONFIG_IMA_DEFAULT_HASH);
327 error = ima_init(); 327 error = ima_init();
328 if (!error) 328 if (error)
329 ima_initialized = 1; 329 goto out;
330
331 error = ima_init_keyring(INTEGRITY_KEYRING_IMA);
332 if (error)
333 goto out;
334 ima_initialized = 1;
335out:
330 return error; 336 return error;
331} 337}
332 338
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 33c0a70f6b15..09c440d9aaee 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -124,6 +124,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
124int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 124int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
125 const char *digest, int digestlen); 125 const char *digest, int digestlen);
126 126
127int integrity_init_keyring(const unsigned int id);
127#else 128#else
128 129
129static inline int integrity_digsig_verify(const unsigned int id, 130static inline int integrity_digsig_verify(const unsigned int id,
@@ -133,6 +134,10 @@ static inline int integrity_digsig_verify(const unsigned int id,
133 return -EOPNOTSUPP; 134 return -EOPNOTSUPP;
134} 135}
135 136
137static inline int integrity_init_keyring(const unsigned int id)
138{
139 return 0;
140}
136#endif /* CONFIG_INTEGRITY_SIGNATURE */ 141#endif /* CONFIG_INTEGRITY_SIGNATURE */
137 142
138#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS 143#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 8137b27d641d..c2f91a0cf889 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -34,7 +34,9 @@ MODULE_LICENSE("GPL");
34struct key_type key_type_big_key = { 34struct key_type key_type_big_key = {
35 .name = "big_key", 35 .name = "big_key",
36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
37 .instantiate = big_key_instantiate, 37 .preparse = big_key_preparse,
38 .free_preparse = big_key_free_preparse,
39 .instantiate = generic_key_instantiate,
38 .match = user_match, 40 .match = user_match,
39 .revoke = big_key_revoke, 41 .revoke = big_key_revoke,
40 .destroy = big_key_destroy, 42 .destroy = big_key_destroy,
@@ -43,11 +45,11 @@ struct key_type key_type_big_key = {
43}; 45};
44 46
45/* 47/*
46 * Instantiate a big key 48 * Preparse a big key
47 */ 49 */
48int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 50int big_key_preparse(struct key_preparsed_payload *prep)
49{ 51{
50 struct path *path = (struct path *)&key->payload.data2; 52 struct path *path = (struct path *)&prep->payload;
51 struct file *file; 53 struct file *file;
52 ssize_t written; 54 ssize_t written;
53 size_t datalen = prep->datalen; 55 size_t datalen = prep->datalen;
@@ -58,11 +60,9 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
58 goto error; 60 goto error;
59 61
60 /* Set an arbitrary quota */ 62 /* Set an arbitrary quota */
61 ret = key_payload_reserve(key, 16); 63 prep->quotalen = 16;
62 if (ret < 0)
63 goto error;
64 64
65 key->type_data.x[1] = datalen; 65 prep->type_data[1] = (void *)(unsigned long)datalen;
66 66
67 if (datalen > BIG_KEY_FILE_THRESHOLD) { 67 if (datalen > BIG_KEY_FILE_THRESHOLD) {
68 /* Create a shmem file to store the data in. This will permit the data 68 /* Create a shmem file to store the data in. This will permit the data
@@ -73,7 +73,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
73 file = shmem_kernel_file_setup("", datalen, 0); 73 file = shmem_kernel_file_setup("", datalen, 0);
74 if (IS_ERR(file)) { 74 if (IS_ERR(file)) {
75 ret = PTR_ERR(file); 75 ret = PTR_ERR(file);
76 goto err_quota; 76 goto error;
77 } 77 }
78 78
79 written = kernel_write(file, prep->data, prep->datalen, 0); 79 written = kernel_write(file, prep->data, prep->datalen, 0);
@@ -93,24 +93,33 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
93 } else { 93 } else {
94 /* Just store the data in a buffer */ 94 /* Just store the data in a buffer */
95 void *data = kmalloc(datalen, GFP_KERNEL); 95 void *data = kmalloc(datalen, GFP_KERNEL);
96 if (!data) { 96 if (!data)
97 ret = -ENOMEM; 97 return -ENOMEM;
98 goto err_quota;
99 }
100 98
101 key->payload.data = memcpy(data, prep->data, prep->datalen); 99 prep->payload[0] = memcpy(data, prep->data, prep->datalen);
102 } 100 }
103 return 0; 101 return 0;
104 102
105err_fput: 103err_fput:
106 fput(file); 104 fput(file);
107err_quota:
108 key_payload_reserve(key, 0);
109error: 105error:
110 return ret; 106 return ret;
111} 107}
112 108
113/* 109/*
110 * Clear preparsement.
111 */
112void big_key_free_preparse(struct key_preparsed_payload *prep)
113{
114 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
115 struct path *path = (struct path *)&prep->payload;
116 path_put(path);
117 } else {
118 kfree(prep->payload[0]);
119 }
120}
121
122/*
114 * dispose of the links from a revoked keyring 123 * dispose of the links from a revoked keyring
115 * - called with the key sem write-locked 124 * - called with the key sem write-locked
116 */ 125 */
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 5fe443d120af..d252c5704f8a 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -811,7 +811,7 @@ static int encrypted_instantiate(struct key *key,
811 goto out; 811 goto out;
812 } 812 }
813 813
814 rcu_assign_keypointer(key, epayload); 814 prep->payload[0] = epayload;
815out: 815out:
816 kfree(datablob); 816 kfree(datablob);
817 return ret; 817 return ret;
diff --git a/security/keys/key.c b/security/keys/key.c
index 2048a110e7f1..b90a68c4e2c4 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -437,6 +437,11 @@ static int __key_instantiate_and_link(struct key *key,
437 /* disable the authorisation key */ 437 /* disable the authorisation key */
438 if (authkey) 438 if (authkey)
439 key_revoke(authkey); 439 key_revoke(authkey);
440
441 if (prep->expiry != TIME_T_MAX) {
442 key->expiry = prep->expiry;
443 key_schedule_gc(prep->expiry + key_gc_delay);
444 }
440 } 445 }
441 } 446 }
442 447
@@ -479,6 +484,7 @@ int key_instantiate_and_link(struct key *key,
479 prep.data = data; 484 prep.data = data;
480 prep.datalen = datalen; 485 prep.datalen = datalen;
481 prep.quotalen = key->type->def_datalen; 486 prep.quotalen = key->type->def_datalen;
487 prep.expiry = TIME_T_MAX;
482 if (key->type->preparse) { 488 if (key->type->preparse) {
483 ret = key->type->preparse(&prep); 489 ret = key->type->preparse(&prep);
484 if (ret < 0) 490 if (ret < 0)
@@ -488,7 +494,7 @@ int key_instantiate_and_link(struct key *key,
488 if (keyring) { 494 if (keyring) {
489 ret = __key_link_begin(keyring, &key->index_key, &edit); 495 ret = __key_link_begin(keyring, &key->index_key, &edit);
490 if (ret < 0) 496 if (ret < 0)
491 goto error_free_preparse; 497 goto error;
492 } 498 }
493 499
494 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit); 500 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
@@ -496,10 +502,9 @@ int key_instantiate_and_link(struct key *key,
496 if (keyring) 502 if (keyring)
497 __key_link_end(keyring, &key->index_key, edit); 503 __key_link_end(keyring, &key->index_key, edit);
498 504
499error_free_preparse: 505error:
500 if (key->type->preparse) 506 if (key->type->preparse)
501 key->type->free_preparse(&prep); 507 key->type->free_preparse(&prep);
502error:
503 return ret; 508 return ret;
504} 509}
505 510
@@ -811,11 +816,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 prep.datalen = plen; 816 prep.datalen = plen;
812 prep.quotalen = index_key.type->def_datalen; 817 prep.quotalen = index_key.type->def_datalen;
813 prep.trusted = flags & KEY_ALLOC_TRUSTED; 818 prep.trusted = flags & KEY_ALLOC_TRUSTED;
819 prep.expiry = TIME_T_MAX;
814 if (index_key.type->preparse) { 820 if (index_key.type->preparse) {
815 ret = index_key.type->preparse(&prep); 821 ret = index_key.type->preparse(&prep);
816 if (ret < 0) { 822 if (ret < 0) {
817 key_ref = ERR_PTR(ret); 823 key_ref = ERR_PTR(ret);
818 goto error_put_type; 824 goto error_free_prep;
819 } 825 }
820 if (!index_key.description) 826 if (!index_key.description)
821 index_key.description = prep.description; 827 index_key.description = prep.description;
@@ -941,6 +947,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
941 prep.data = payload; 947 prep.data = payload;
942 prep.datalen = plen; 948 prep.datalen = plen;
943 prep.quotalen = key->type->def_datalen; 949 prep.quotalen = key->type->def_datalen;
950 prep.expiry = TIME_T_MAX;
944 if (key->type->preparse) { 951 if (key->type->preparse) {
945 ret = key->type->preparse(&prep); 952 ret = key->type->preparse(&prep);
946 if (ret < 0) 953 if (ret < 0)
@@ -956,9 +963,9 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
956 963
957 up_write(&key->sem); 964 up_write(&key->sem);
958 965
966error:
959 if (key->type->preparse) 967 if (key->type->preparse)
960 key->type->free_preparse(&prep); 968 key->type->free_preparse(&prep);
961error:
962 return ret; 969 return ret;
963} 970}
964EXPORT_SYMBOL(key_update); 971EXPORT_SYMBOL(key_update);
@@ -1024,6 +1031,38 @@ void key_invalidate(struct key *key)
1024EXPORT_SYMBOL(key_invalidate); 1031EXPORT_SYMBOL(key_invalidate);
1025 1032
1026/** 1033/**
1034 * generic_key_instantiate - Simple instantiation of a key from preparsed data
1035 * @key: The key to be instantiated
1036 * @prep: The preparsed data to load.
1037 *
1038 * Instantiate a key from preparsed data. We assume we can just copy the data
1039 * in directly and clear the old pointers.
1040 *
1041 * This can be pointed to directly by the key type instantiate op pointer.
1042 */
1043int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
1044{
1045 int ret;
1046
1047 pr_devel("==>%s()\n", __func__);
1048
1049 ret = key_payload_reserve(key, prep->quotalen);
1050 if (ret == 0) {
1051 key->type_data.p[0] = prep->type_data[0];
1052 key->type_data.p[1] = prep->type_data[1];
1053 rcu_assign_keypointer(key, prep->payload[0]);
1054 key->payload.data2[1] = prep->payload[1];
1055 prep->type_data[0] = NULL;
1056 prep->type_data[1] = NULL;
1057 prep->payload[0] = NULL;
1058 prep->payload[1] = NULL;
1059 }
1060 pr_devel("<==%s() = %d\n", __func__, ret);
1061 return ret;
1062}
1063EXPORT_SYMBOL(generic_key_instantiate);
1064
1065/**
1027 * register_key_type - Register a type of key. 1066 * register_key_type - Register a type of key.
1028 * @ktype: The new key type. 1067 * @ktype: The new key type.
1029 * 1068 *
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cd5bd0cef25d..e26f860e5f2e 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -37,8 +37,6 @@ static int key_get_type_from_user(char *type,
37 return ret; 37 return ret;
38 if (ret == 0 || ret >= len) 38 if (ret == 0 || ret >= len)
39 return -EINVAL; 39 return -EINVAL;
40 if (type[0] == '.')
41 return -EPERM;
42 type[len - 1] = '\0'; 40 type[len - 1] = '\0';
43 return 0; 41 return 0;
44} 42}
@@ -86,6 +84,10 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
86 if (!*description) { 84 if (!*description) {
87 kfree(description); 85 kfree(description);
88 description = NULL; 86 description = NULL;
87 } else if ((description[0] == '.') &&
88 (strncmp(type, "keyring", 7) == 0)) {
89 ret = -EPERM;
90 goto error2;
89 } 91 }
90 } 92 }
91 93
@@ -404,12 +406,25 @@ long keyctl_invalidate_key(key_serial_t id)
404 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); 406 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
405 if (IS_ERR(key_ref)) { 407 if (IS_ERR(key_ref)) {
406 ret = PTR_ERR(key_ref); 408 ret = PTR_ERR(key_ref);
409
410 /* Root is permitted to invalidate certain special keys */
411 if (capable(CAP_SYS_ADMIN)) {
412 key_ref = lookup_user_key(id, 0, 0);
413 if (IS_ERR(key_ref))
414 goto error;
415 if (test_bit(KEY_FLAG_ROOT_CAN_INVAL,
416 &key_ref_to_ptr(key_ref)->flags))
417 goto invalidate;
418 goto error_put;
419 }
420
407 goto error; 421 goto error;
408 } 422 }
409 423
424invalidate:
410 key_invalidate(key_ref_to_ptr(key_ref)); 425 key_invalidate(key_ref_to_ptr(key_ref));
411 ret = 0; 426 ret = 0;
412 427error_put:
413 key_ref_put(key_ref); 428 key_ref_put(key_ref);
414error: 429error:
415 kleave(" = %ld", ret); 430 kleave(" = %ld", ret);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 9cf2575f0d97..8314a7d2104d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -73,6 +73,8 @@ static inline unsigned keyring_hash(const char *desc)
73 * can be treated as ordinary keys in addition to having their own special 73 * can be treated as ordinary keys in addition to having their own special
74 * operations. 74 * operations.
75 */ 75 */
76static int keyring_preparse(struct key_preparsed_payload *prep);
77static void keyring_free_preparse(struct key_preparsed_payload *prep);
76static int keyring_instantiate(struct key *keyring, 78static int keyring_instantiate(struct key *keyring,
77 struct key_preparsed_payload *prep); 79 struct key_preparsed_payload *prep);
78static void keyring_revoke(struct key *keyring); 80static void keyring_revoke(struct key *keyring);
@@ -84,6 +86,8 @@ static long keyring_read(const struct key *keyring,
84struct key_type key_type_keyring = { 86struct key_type key_type_keyring = {
85 .name = "keyring", 87 .name = "keyring",
86 .def_datalen = 0, 88 .def_datalen = 0,
89 .preparse = keyring_preparse,
90 .free_preparse = keyring_free_preparse,
87 .instantiate = keyring_instantiate, 91 .instantiate = keyring_instantiate,
88 .match = user_match, 92 .match = user_match,
89 .revoke = keyring_revoke, 93 .revoke = keyring_revoke,
@@ -123,6 +127,21 @@ static void keyring_publish_name(struct key *keyring)
123} 127}
124 128
125/* 129/*
130 * Preparse a keyring payload
131 */
132static int keyring_preparse(struct key_preparsed_payload *prep)
133{
134 return prep->datalen != 0 ? -EINVAL : 0;
135}
136
137/*
138 * Free a preparse of a user defined key payload
139 */
140static void keyring_free_preparse(struct key_preparsed_payload *prep)
141{
142}
143
144/*
126 * Initialise a keyring. 145 * Initialise a keyring.
127 * 146 *
128 * Returns 0 on success, -EINVAL if given any data. 147 * Returns 0 on success, -EINVAL if given any data.
@@ -130,17 +149,10 @@ static void keyring_publish_name(struct key *keyring)
130static int keyring_instantiate(struct key *keyring, 149static int keyring_instantiate(struct key *keyring,
131 struct key_preparsed_payload *prep) 150 struct key_preparsed_payload *prep)
132{ 151{
133 int ret; 152 assoc_array_init(&keyring->keys);
134 153 /* make the keyring available by name if it has one */
135 ret = -EINVAL; 154 keyring_publish_name(keyring);
136 if (prep->datalen == 0) { 155 return 0;
137 assoc_array_init(&keyring->keys);
138 /* make the keyring available by name if it has one */
139 keyring_publish_name(keyring);
140 ret = 0;
141 }
142
143 return ret;
144} 156}
145 157
146/* 158/*
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 7495a93b4b90..842e6f410d50 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -20,6 +20,8 @@
20#include "internal.h" 20#include "internal.h"
21#include <keys/user-type.h> 21#include <keys/user-type.h>
22 22
23static int request_key_auth_preparse(struct key_preparsed_payload *);
24static void request_key_auth_free_preparse(struct key_preparsed_payload *);
23static int request_key_auth_instantiate(struct key *, 25static int request_key_auth_instantiate(struct key *,
24 struct key_preparsed_payload *); 26 struct key_preparsed_payload *);
25static void request_key_auth_describe(const struct key *, struct seq_file *); 27static void request_key_auth_describe(const struct key *, struct seq_file *);
@@ -33,6 +35,8 @@ static long request_key_auth_read(const struct key *, char __user *, size_t);
33struct key_type key_type_request_key_auth = { 35struct key_type key_type_request_key_auth = {
34 .name = ".request_key_auth", 36 .name = ".request_key_auth",
35 .def_datalen = sizeof(struct request_key_auth), 37 .def_datalen = sizeof(struct request_key_auth),
38 .preparse = request_key_auth_preparse,
39 .free_preparse = request_key_auth_free_preparse,
36 .instantiate = request_key_auth_instantiate, 40 .instantiate = request_key_auth_instantiate,
37 .describe = request_key_auth_describe, 41 .describe = request_key_auth_describe,
38 .revoke = request_key_auth_revoke, 42 .revoke = request_key_auth_revoke,
@@ -40,6 +44,15 @@ struct key_type key_type_request_key_auth = {
40 .read = request_key_auth_read, 44 .read = request_key_auth_read,
41}; 45};
42 46
47int request_key_auth_preparse(struct key_preparsed_payload *prep)
48{
49 return 0;
50}
51
52void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
53{
54}
55
43/* 56/*
44 * Instantiate a request-key authorisation key. 57 * Instantiate a request-key authorisation key.
45 */ 58 */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index faa2caeb593f..eee340011f2b 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -27,7 +27,9 @@ static int logon_vet_description(const char *desc);
27struct key_type key_type_user = { 27struct key_type key_type_user = {
28 .name = "user", 28 .name = "user",
29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
30 .instantiate = user_instantiate, 30 .preparse = user_preparse,
31 .free_preparse = user_free_preparse,
32 .instantiate = generic_key_instantiate,
31 .update = user_update, 33 .update = user_update,
32 .match = user_match, 34 .match = user_match,
33 .revoke = user_revoke, 35 .revoke = user_revoke,
@@ -47,7 +49,9 @@ EXPORT_SYMBOL_GPL(key_type_user);
47struct key_type key_type_logon = { 49struct key_type key_type_logon = {
48 .name = "logon", 50 .name = "logon",
49 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 51 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
50 .instantiate = user_instantiate, 52 .preparse = user_preparse,
53 .free_preparse = user_free_preparse,
54 .instantiate = generic_key_instantiate,
51 .update = user_update, 55 .update = user_update,
52 .match = user_match, 56 .match = user_match,
53 .revoke = user_revoke, 57 .revoke = user_revoke,
@@ -58,38 +62,37 @@ struct key_type key_type_logon = {
58EXPORT_SYMBOL_GPL(key_type_logon); 62EXPORT_SYMBOL_GPL(key_type_logon);
59 63
60/* 64/*
61 * instantiate a user defined key 65 * Preparse a user defined key payload
62 */ 66 */
63int user_instantiate(struct key *key, struct key_preparsed_payload *prep) 67int user_preparse(struct key_preparsed_payload *prep)
64{ 68{
65 struct user_key_payload *upayload; 69 struct user_key_payload *upayload;
66 size_t datalen = prep->datalen; 70 size_t datalen = prep->datalen;
67 int ret;
68 71
69 ret = -EINVAL;
70 if (datalen <= 0 || datalen > 32767 || !prep->data) 72 if (datalen <= 0 || datalen > 32767 || !prep->data)
71 goto error; 73 return -EINVAL;
72
73 ret = key_payload_reserve(key, datalen);
74 if (ret < 0)
75 goto error;
76 74
77 ret = -ENOMEM;
78 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); 75 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
79 if (!upayload) 76 if (!upayload)
80 goto error; 77 return -ENOMEM;
81 78
82 /* attach the data */ 79 /* attach the data */
80 prep->quotalen = datalen;
81 prep->payload[0] = upayload;
83 upayload->datalen = datalen; 82 upayload->datalen = datalen;
84 memcpy(upayload->data, prep->data, datalen); 83 memcpy(upayload->data, prep->data, datalen);
85 rcu_assign_keypointer(key, upayload); 84 return 0;
86 ret = 0;
87
88error:
89 return ret;
90} 85}
86EXPORT_SYMBOL_GPL(user_preparse);
91 87
92EXPORT_SYMBOL_GPL(user_instantiate); 88/*
89 * Free a preparse of a user defined key payload
90 */
91void user_free_preparse(struct key_preparsed_payload *prep)
92{
93 kfree(prep->payload[0]);
94}
95EXPORT_SYMBOL_GPL(user_free_preparse);
93 96
94/* 97/*
95 * update a user defined key 98 * update a user defined key