summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/integrity/Kconfig1
-rw-r--r--security/integrity/digsig.c15
-rw-r--r--security/integrity/ima/Kconfig36
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima_mok.c23
-rw-r--r--security/keys/Kconfig15
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/big_key.c198
-rw-r--r--security/keys/compat.c4
-rw-r--r--security/keys/dh.c160
-rw-r--r--security/keys/internal.h12
-rw-r--r--security/keys/key.c42
-rw-r--r--security/keys/keyctl.c5
-rw-r--r--security/keys/keyring.c46
-rw-r--r--security/keys/persistent.c4
-rw-r--r--security/keys/process_keys.c16
-rw-r--r--security/keys/request_key.c4
-rw-r--r--security/keys/request_key_auth.c2
-rw-r--r--security/keys/user_defined.c42
19 files changed, 516 insertions, 112 deletions
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 979be65d22c4..da9565891738 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -35,7 +35,6 @@ config INTEGRITY_ASYMMETRIC_KEYS
35 default n 35 default n
36 select ASYMMETRIC_KEY_TYPE 36 select ASYMMETRIC_KEY_TYPE
37 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE 37 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
38 select PUBLIC_KEY_ALGO_RSA
39 select CRYPTO_RSA 38 select CRYPTO_RSA
40 select X509_CERTIFICATE_PARSER 39 select X509_CERTIFICATE_PARSER
41 help 40 help
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 8ef15118cc78..4304372b323f 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -18,6 +18,8 @@
18#include <linux/cred.h> 18#include <linux/cred.h>
19#include <linux/key-type.h> 19#include <linux/key-type.h>
20#include <linux/digsig.h> 20#include <linux/digsig.h>
21#include <crypto/public_key.h>
22#include <keys/system_keyring.h>
21 23
22#include "integrity.h" 24#include "integrity.h"
23 25
@@ -40,6 +42,12 @@ static bool init_keyring __initdata = true;
40static bool init_keyring __initdata; 42static bool init_keyring __initdata;
41#endif 43#endif
42 44
45#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
46#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
47#else
48#define restrict_link_to_ima restrict_link_by_builtin_trusted
49#endif
50
43int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 51int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
44 const char *digest, int digestlen) 52 const char *digest, int digestlen)
45{ 53{
@@ -83,10 +91,9 @@ int __init integrity_init_keyring(const unsigned int id)
83 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 91 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
84 KEY_USR_VIEW | KEY_USR_READ | 92 KEY_USR_VIEW | KEY_USR_READ |
85 KEY_USR_WRITE | KEY_USR_SEARCH), 93 KEY_USR_WRITE | KEY_USR_SEARCH),
86 KEY_ALLOC_NOT_IN_QUOTA, NULL); 94 KEY_ALLOC_NOT_IN_QUOTA,
87 if (!IS_ERR(keyring[id])) 95 restrict_link_to_ima, NULL);
88 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); 96 if (IS_ERR(keyring[id])) {
89 else {
90 err = PTR_ERR(keyring[id]); 97 err = PTR_ERR(keyring[id]);
91 pr_info("Can't allocate %s keyring (%d)\n", 98 pr_info("Can't allocate %s keyring (%d)\n",
92 keyring_name[id], err); 99 keyring_name[id], err);
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index e54a8a8dae94..5487827fa86c 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -155,23 +155,33 @@ config IMA_TRUSTED_KEYRING
155 155
156 This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING 156 This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING
157 157
158config IMA_MOK_KEYRING 158config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
159 bool "Create IMA machine owner keys (MOK) and blacklist keyrings" 159 bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)"
160 depends on SYSTEM_TRUSTED_KEYRING
161 depends on SECONDARY_TRUSTED_KEYRING
162 depends on INTEGRITY_ASYMMETRIC_KEYS
163 select INTEGRITY_TRUSTED_KEYRING
164 default n
165 help
166 Keys may be added to the IMA or IMA blacklist keyrings, if the
167 key is validly signed by a CA cert in the system built-in or
168 secondary trusted keyrings.
169
170 Intermediate keys between those the kernel has compiled in and the
171 IMA keys to be added may be added to the system secondary keyring,
172 provided they are validly signed by a key already resident in the
173 built-in or secondary trusted keyrings.
174
175config IMA_BLACKLIST_KEYRING
176 bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)"
160 depends on SYSTEM_TRUSTED_KEYRING 177 depends on SYSTEM_TRUSTED_KEYRING
161 depends on IMA_TRUSTED_KEYRING 178 depends on IMA_TRUSTED_KEYRING
162 default n 179 default n
163 help 180 help
164 This option creates IMA MOK and blacklist keyrings. IMA MOK is an 181 This option creates an IMA blacklist keyring, which contains all
165 intermediate keyring that sits between .system and .ima keyrings, 182 revoked IMA keys. It is consulted before any other keyring. If
166 effectively forming a simple CA hierarchy. To successfully import a 183 the search is successful the requested operation is rejected and
167 key into .ima_mok it must be signed by a key which CA is in .system 184 an error is returned to the caller.
168 keyring. On turn any key that needs to go in .ima keyring must be
169 signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty
170 at kernel boot.
171
172 IMA blacklist keyring contains all revoked IMA keys. It is consulted
173 before any other keyring. If the search is successful the requested
174 operation is rejected and error is returned to the caller.
175 185
176config IMA_LOAD_X509 186config IMA_LOAD_X509
177 bool "Load X509 certificate onto the '.ima' trusted keyring" 187 bool "Load X509 certificate onto the '.ima' trusted keyring"
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index a8539f9e060f..9aeaedad1e2b 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,4 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o ima_template.o ima_template_lib.o 9 ima_policy.o ima_template.o ima_template_lib.o
10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o 10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
11obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o 11obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
index 676885e4320e..74a279957464 100644
--- a/security/integrity/ima/ima_mok.c
+++ b/security/integrity/ima/ima_mok.c
@@ -17,38 +17,29 @@
17#include <linux/cred.h> 17#include <linux/cred.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <keys/asymmetric-type.h> 20#include <keys/system_keyring.h>
21 21
22 22
23struct key *ima_mok_keyring;
24struct key *ima_blacklist_keyring; 23struct key *ima_blacklist_keyring;
25 24
26/* 25/*
27 * Allocate the IMA MOK and blacklist keyrings 26 * Allocate the IMA blacklist keyring
28 */ 27 */
29__init int ima_mok_init(void) 28__init int ima_mok_init(void)
30{ 29{
31 pr_notice("Allocating IMA MOK and blacklist keyrings.\n"); 30 pr_notice("Allocating IMA blacklist keyring.\n");
32
33 ima_mok_keyring = keyring_alloc(".ima_mok",
34 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
35 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
36 KEY_USR_VIEW | KEY_USR_READ |
37 KEY_USR_WRITE | KEY_USR_SEARCH,
38 KEY_ALLOC_NOT_IN_QUOTA, NULL);
39 31
40 ima_blacklist_keyring = keyring_alloc(".ima_blacklist", 32 ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
41 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 33 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
42 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 34 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
43 KEY_USR_VIEW | KEY_USR_READ | 35 KEY_USR_VIEW | KEY_USR_READ |
44 KEY_USR_WRITE | KEY_USR_SEARCH, 36 KEY_USR_WRITE | KEY_USR_SEARCH,
45 KEY_ALLOC_NOT_IN_QUOTA, NULL); 37 KEY_ALLOC_NOT_IN_QUOTA,
38 restrict_link_by_builtin_trusted, NULL);
46 39
47 if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) 40 if (IS_ERR(ima_blacklist_keyring))
48 panic("Can't allocate IMA MOK or blacklist keyrings."); 41 panic("Can't allocate IMA blacklist keyring.");
49 set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);
50 42
51 set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);
52 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); 43 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);
53 return 0; 44 return 0;
54} 45}
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index fe4d74e126a7..f826e8739023 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -41,6 +41,10 @@ config BIG_KEYS
41 bool "Large payload keys" 41 bool "Large payload keys"
42 depends on KEYS 42 depends on KEYS
43 depends on TMPFS 43 depends on TMPFS
44 select CRYPTO
45 select CRYPTO_AES
46 select CRYPTO_ECB
47 select CRYPTO_RNG
44 help 48 help
45 This option provides support for holding large keys within the kernel 49 This option provides support for holding large keys within the kernel
46 (for example Kerberos ticket caches). The data may be stored out to 50 (for example Kerberos ticket caches). The data may be stored out to
@@ -81,3 +85,14 @@ config ENCRYPTED_KEYS
81 Userspace only ever sees/stores encrypted blobs. 85 Userspace only ever sees/stores encrypted blobs.
82 86
83 If you are unsure as to whether this is required, answer N. 87 If you are unsure as to whether this is required, answer N.
88
89config KEY_DH_OPERATIONS
90 bool "Diffie-Hellman operations on retained keys"
91 depends on KEYS
92 select MPILIB
93 help
94 This option provides support for calculating Diffie-Hellman
95 public keys and shared secrets using values stored as keys
96 in the kernel.
97
98 If you are unsure as to whether this is required, answer N.
diff --git a/security/keys/Makefile b/security/keys/Makefile
index dfb3a7bededf..1fd4a16e6daf 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_KEYS_COMPAT) += compat.o
19obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
20obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
21obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o 21obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o
22obj-$(CONFIG_KEY_DH_OPERATIONS) += dh.o
22 23
23# 24#
24# Key types 25# Key types
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index c721e398893a..9e443fccad4c 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -14,8 +14,10 @@
14#include <linux/file.h> 14#include <linux/file.h>
15#include <linux/shmem_fs.h> 15#include <linux/shmem_fs.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/scatterlist.h>
17#include <keys/user-type.h> 18#include <keys/user-type.h>
18#include <keys/big_key-type.h> 19#include <keys/big_key-type.h>
20#include <crypto/rng.h>
19 21
20/* 22/*
21 * Layout of key payload words. 23 * Layout of key payload words.
@@ -28,6 +30,14 @@ enum {
28}; 30};
29 31
30/* 32/*
33 * Crypto operation with big_key data
34 */
35enum big_key_op {
36 BIG_KEY_ENC,
37 BIG_KEY_DEC,
38};
39
40/*
31 * If the data is under this limit, there's no point creating a shm file to 41 * If the data is under this limit, there's no point creating a shm file to
32 * hold it as the permanently resident metadata for the shmem fs will be at 42 * hold it as the permanently resident metadata for the shmem fs will be at
33 * least as large as the data. 43 * least as large as the data.
@@ -35,6 +45,11 @@ enum {
35#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry)) 45#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))
36 46
37/* 47/*
48 * Key size for big_key data encryption
49 */
50#define ENC_KEY_SIZE 16
51
52/*
38 * big_key defined keys take an arbitrary string as the description and an 53 * big_key defined keys take an arbitrary string as the description and an
39 * arbitrary blob of data as the payload 54 * arbitrary blob of data as the payload
40 */ 55 */
@@ -50,12 +65,62 @@ struct key_type key_type_big_key = {
50}; 65};
51 66
52/* 67/*
68 * Crypto names for big_key data encryption
69 */
70static const char big_key_rng_name[] = "stdrng";
71static const char big_key_alg_name[] = "ecb(aes)";
72
73/*
74 * Crypto algorithms for big_key data encryption
75 */
76static struct crypto_rng *big_key_rng;
77static struct crypto_blkcipher *big_key_blkcipher;
78
79/*
80 * Generate random key to encrypt big_key data
81 */
82static inline int big_key_gen_enckey(u8 *key)
83{
84 return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE);
85}
86
87/*
88 * Encrypt/decrypt big_key data
89 */
90static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
91{
92 int ret = -EINVAL;
93 struct scatterlist sgio;
94 struct blkcipher_desc desc;
95
96 if (crypto_blkcipher_setkey(big_key_blkcipher, key, ENC_KEY_SIZE)) {
97 ret = -EAGAIN;
98 goto error;
99 }
100
101 desc.flags = 0;
102 desc.tfm = big_key_blkcipher;
103
104 sg_init_one(&sgio, data, datalen);
105
106 if (op == BIG_KEY_ENC)
107 ret = crypto_blkcipher_encrypt(&desc, &sgio, &sgio, datalen);
108 else
109 ret = crypto_blkcipher_decrypt(&desc, &sgio, &sgio, datalen);
110
111error:
112 return ret;
113}
114
115/*
53 * Preparse a big key 116 * Preparse a big key
54 */ 117 */
55int big_key_preparse(struct key_preparsed_payload *prep) 118int big_key_preparse(struct key_preparsed_payload *prep)
56{ 119{
57 struct path *path = (struct path *)&prep->payload.data[big_key_path]; 120 struct path *path = (struct path *)&prep->payload.data[big_key_path];
58 struct file *file; 121 struct file *file;
122 u8 *enckey;
123 u8 *data = NULL;
59 ssize_t written; 124 ssize_t written;
60 size_t datalen = prep->datalen; 125 size_t datalen = prep->datalen;
61 int ret; 126 int ret;
@@ -73,16 +138,43 @@ int big_key_preparse(struct key_preparsed_payload *prep)
73 /* Create a shmem file to store the data in. This will permit the data 138 /* Create a shmem file to store the data in. This will permit the data
74 * to be swapped out if needed. 139 * to be swapped out if needed.
75 * 140 *
76 * TODO: Encrypt the stored data with a temporary key. 141 * File content is stored encrypted with randomly generated key.
77 */ 142 */
78 file = shmem_kernel_file_setup("", datalen, 0); 143 size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher));
144
145 /* prepare aligned data to encrypt */
146 data = kmalloc(enclen, GFP_KERNEL);
147 if (!data)
148 return -ENOMEM;
149
150 memcpy(data, prep->data, datalen);
151 memset(data + datalen, 0x00, enclen - datalen);
152
153 /* generate random key */
154 enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
155 if (!enckey) {
156 ret = -ENOMEM;
157 goto error;
158 }
159
160 ret = big_key_gen_enckey(enckey);
161 if (ret)
162 goto err_enckey;
163
164 /* encrypt aligned data */
165 ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey);
166 if (ret)
167 goto err_enckey;
168
169 /* save aligned data to file */
170 file = shmem_kernel_file_setup("", enclen, 0);
79 if (IS_ERR(file)) { 171 if (IS_ERR(file)) {
80 ret = PTR_ERR(file); 172 ret = PTR_ERR(file);
81 goto error; 173 goto err_enckey;
82 } 174 }
83 175
84 written = kernel_write(file, prep->data, prep->datalen, 0); 176 written = kernel_write(file, data, enclen, 0);
85 if (written != datalen) { 177 if (written != enclen) {
86 ret = written; 178 ret = written;
87 if (written >= 0) 179 if (written >= 0)
88 ret = -ENOMEM; 180 ret = -ENOMEM;
@@ -92,12 +184,15 @@ int big_key_preparse(struct key_preparsed_payload *prep)
92 /* Pin the mount and dentry to the key so that we can open it again 184 /* Pin the mount and dentry to the key so that we can open it again
93 * later 185 * later
94 */ 186 */
187 prep->payload.data[big_key_data] = enckey;
95 *path = file->f_path; 188 *path = file->f_path;
96 path_get(path); 189 path_get(path);
97 fput(file); 190 fput(file);
191 kfree(data);
98 } else { 192 } else {
99 /* Just store the data in a buffer */ 193 /* Just store the data in a buffer */
100 void *data = kmalloc(datalen, GFP_KERNEL); 194 void *data = kmalloc(datalen, GFP_KERNEL);
195
101 if (!data) 196 if (!data)
102 return -ENOMEM; 197 return -ENOMEM;
103 198
@@ -108,7 +203,10 @@ int big_key_preparse(struct key_preparsed_payload *prep)
108 203
109err_fput: 204err_fput:
110 fput(file); 205 fput(file);
206err_enckey:
207 kfree(enckey);
111error: 208error:
209 kfree(data);
112 return ret; 210 return ret;
113} 211}
114 212
@@ -119,10 +217,10 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
119{ 217{
120 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) { 218 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
121 struct path *path = (struct path *)&prep->payload.data[big_key_path]; 219 struct path *path = (struct path *)&prep->payload.data[big_key_path];
220
122 path_put(path); 221 path_put(path);
123 } else {
124 kfree(prep->payload.data[big_key_data]);
125 } 222 }
223 kfree(prep->payload.data[big_key_data]);
126} 224}
127 225
128/* 226/*
@@ -147,15 +245,15 @@ void big_key_destroy(struct key *key)
147{ 245{
148 size_t datalen = (size_t)key->payload.data[big_key_len]; 246 size_t datalen = (size_t)key->payload.data[big_key_len];
149 247
150 if (datalen) { 248 if (datalen > BIG_KEY_FILE_THRESHOLD) {
151 struct path *path = (struct path *)&key->payload.data[big_key_path]; 249 struct path *path = (struct path *)&key->payload.data[big_key_path];
250
152 path_put(path); 251 path_put(path);
153 path->mnt = NULL; 252 path->mnt = NULL;
154 path->dentry = NULL; 253 path->dentry = NULL;
155 } else {
156 kfree(key->payload.data[big_key_data]);
157 key->payload.data[big_key_data] = NULL;
158 } 254 }
255 kfree(key->payload.data[big_key_data]);
256 key->payload.data[big_key_data] = NULL;
159} 257}
160 258
161/* 259/*
@@ -188,17 +286,41 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
188 if (datalen > BIG_KEY_FILE_THRESHOLD) { 286 if (datalen > BIG_KEY_FILE_THRESHOLD) {
189 struct path *path = (struct path *)&key->payload.data[big_key_path]; 287 struct path *path = (struct path *)&key->payload.data[big_key_path];
190 struct file *file; 288 struct file *file;
191 loff_t pos; 289 u8 *data;
290 u8 *enckey = (u8 *)key->payload.data[big_key_data];
291 size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher));
292
293 data = kmalloc(enclen, GFP_KERNEL);
294 if (!data)
295 return -ENOMEM;
192 296
193 file = dentry_open(path, O_RDONLY, current_cred()); 297 file = dentry_open(path, O_RDONLY, current_cred());
194 if (IS_ERR(file)) 298 if (IS_ERR(file)) {
195 return PTR_ERR(file); 299 ret = PTR_ERR(file);
300 goto error;
301 }
196 302
197 pos = 0; 303 /* read file to kernel and decrypt */
198 ret = vfs_read(file, buffer, datalen, &pos); 304 ret = kernel_read(file, 0, data, enclen);
199 fput(file); 305 if (ret >= 0 && ret != enclen) {
200 if (ret >= 0 && ret != datalen)
201 ret = -EIO; 306 ret = -EIO;
307 goto err_fput;
308 }
309
310 ret = big_key_crypt(BIG_KEY_DEC, data, enclen, enckey);
311 if (ret)
312 goto err_fput;
313
314 ret = datalen;
315
316 /* copy decrypted data to user */
317 if (copy_to_user(buffer, data, datalen) != 0)
318 ret = -EFAULT;
319
320err_fput:
321 fput(file);
322error:
323 kfree(data);
202 } else { 324 } else {
203 ret = datalen; 325 ret = datalen;
204 if (copy_to_user(buffer, key->payload.data[big_key_data], 326 if (copy_to_user(buffer, key->payload.data[big_key_data],
@@ -209,8 +331,48 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
209 return ret; 331 return ret;
210} 332}
211 333
334/*
335 * Register key type
336 */
212static int __init big_key_init(void) 337static int __init big_key_init(void)
213{ 338{
214 return register_key_type(&key_type_big_key); 339 return register_key_type(&key_type_big_key);
215} 340}
341
342/*
343 * Initialize big_key crypto and RNG algorithms
344 */
345static int __init big_key_crypto_init(void)
346{
347 int ret = -EINVAL;
348
349 /* init RNG */
350 big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
351 if (IS_ERR(big_key_rng)) {
352 big_key_rng = NULL;
353 return -EFAULT;
354 }
355
356 /* seed RNG */
357 ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));
358 if (ret)
359 goto error;
360
361 /* init block cipher */
362 big_key_blkcipher = crypto_alloc_blkcipher(big_key_alg_name, 0, 0);
363 if (IS_ERR(big_key_blkcipher)) {
364 big_key_blkcipher = NULL;
365 ret = -EFAULT;
366 goto error;
367 }
368
369 return 0;
370
371error:
372 crypto_free_rng(big_key_rng);
373 big_key_rng = NULL;
374 return ret;
375}
376
216device_initcall(big_key_init); 377device_initcall(big_key_init);
378late_initcall(big_key_crypto_init);
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 25430a3aa7f7..c8783b3b628c 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -132,6 +132,10 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
132 case KEYCTL_GET_PERSISTENT: 132 case KEYCTL_GET_PERSISTENT:
133 return keyctl_get_persistent(arg2, arg3); 133 return keyctl_get_persistent(arg2, arg3);
134 134
135 case KEYCTL_DH_COMPUTE:
136 return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),
137 arg4);
138
135 default: 139 default:
136 return -EOPNOTSUPP; 140 return -EOPNOTSUPP;
137 } 141 }
diff --git a/security/keys/dh.c b/security/keys/dh.c
new file mode 100644
index 000000000000..880505a4b9f1
--- /dev/null
+++ b/security/keys/dh.c
@@ -0,0 +1,160 @@
1/* Crypto operations using stored keys
2 *
3 * Copyright (c) 2016, Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <linux/mpi.h>
12#include <linux/slab.h>
13#include <linux/uaccess.h>
14#include <keys/user-type.h>
15#include "internal.h"
16
17/*
18 * Public key or shared secret generation function [RFC2631 sec 2.1.1]
19 *
20 * ya = g^xa mod p;
21 * or
22 * ZZ = yb^xa mod p;
23 *
24 * where xa is the local private key, ya is the local public key, g is
25 * the generator, p is the prime, yb is the remote public key, and ZZ
26 * is the shared secret.
27 *
28 * Both are the same calculation, so g or yb are the "base" and ya or
29 * ZZ are the "result".
30 */
31static int do_dh(MPI result, MPI base, MPI xa, MPI p)
32{
33 return mpi_powm(result, base, xa, p);
34}
35
36static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi)
37{
38 struct key *key;
39 key_ref_t key_ref;
40 long status;
41 ssize_t ret;
42
43 key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
44 if (IS_ERR(key_ref)) {
45 ret = -ENOKEY;
46 goto error;
47 }
48
49 key = key_ref_to_ptr(key_ref);
50
51 ret = -EOPNOTSUPP;
52 if (key->type == &key_type_user) {
53 down_read(&key->sem);
54 status = key_validate(key);
55 if (status == 0) {
56 const struct user_key_payload *payload;
57
58 payload = user_key_payload(key);
59
60 if (maxlen == 0) {
61 *mpi = NULL;
62 ret = payload->datalen;
63 } else if (payload->datalen <= maxlen) {
64 *mpi = mpi_read_raw_data(payload->data,
65 payload->datalen);
66 if (*mpi)
67 ret = payload->datalen;
68 } else {
69 ret = -EINVAL;
70 }
71 }
72 up_read(&key->sem);
73 }
74
75 key_put(key);
76error:
77 return ret;
78}
79
80long keyctl_dh_compute(struct keyctl_dh_params __user *params,
81 char __user *buffer, size_t buflen)
82{
83 long ret;
84 MPI base, private, prime, result;
85 unsigned nbytes;
86 struct keyctl_dh_params pcopy;
87 uint8_t *kbuf;
88 ssize_t keylen;
89 size_t resultlen;
90
91 if (!params || (!buffer && buflen)) {
92 ret = -EINVAL;
93 goto out;
94 }
95 if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
96 ret = -EFAULT;
97 goto out;
98 }
99
100 keylen = mpi_from_key(pcopy.prime, buflen, &prime);
101 if (keylen < 0 || !prime) {
102 /* buflen == 0 may be used to query the required buffer size,
103 * which is the prime key length.
104 */
105 ret = keylen;
106 goto out;
107 }
108
109 /* The result is never longer than the prime */
110 resultlen = keylen;
111
112 keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base);
113 if (keylen < 0 || !base) {
114 ret = keylen;
115 goto error1;
116 }
117
118 keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private);
119 if (keylen < 0 || !private) {
120 ret = keylen;
121 goto error2;
122 }
123
124 result = mpi_alloc(0);
125 if (!result) {
126 ret = -ENOMEM;
127 goto error3;
128 }
129
130 kbuf = kmalloc(resultlen, GFP_KERNEL);
131 if (!kbuf) {
132 ret = -ENOMEM;
133 goto error4;
134 }
135
136 ret = do_dh(result, base, private, prime);
137 if (ret)
138 goto error5;
139
140 ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL);
141 if (ret != 0)
142 goto error5;
143
144 ret = nbytes;
145 if (copy_to_user(buffer, kbuf, nbytes) != 0)
146 ret = -EFAULT;
147
148error5:
149 kfree(kbuf);
150error4:
151 mpi_free(result);
152error3:
153 mpi_free(private);
154error2:
155 mpi_free(base);
156error1:
157 mpi_free(prime);
158out:
159 return ret;
160}
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 5105c2c2da75..8ec7a528365d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -15,6 +15,7 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/key-type.h> 16#include <linux/key-type.h>
17#include <linux/task_work.h> 17#include <linux/task_work.h>
18#include <linux/keyctl.h>
18 19
19struct iovec; 20struct iovec;
20 21
@@ -257,6 +258,17 @@ static inline long keyctl_get_persistent(uid_t uid, key_serial_t destring)
257} 258}
258#endif 259#endif
259 260
261#ifdef CONFIG_KEY_DH_OPERATIONS
262extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
263 size_t);
264#else
265static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params,
266 char __user *buffer, size_t buflen)
267{
268 return -EOPNOTSUPP;
269}
270#endif
271
260/* 272/*
261 * Debugging key validation 273 * Debugging key validation
262 */ 274 */
diff --git a/security/keys/key.c b/security/keys/key.c
index b28755131687..bd5a272f28a6 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -201,6 +201,7 @@ serial_exists:
201 * @cred: The credentials specifying UID namespace. 201 * @cred: The credentials specifying UID namespace.
202 * @perm: The permissions mask of the new key. 202 * @perm: The permissions mask of the new key.
203 * @flags: Flags specifying quota properties. 203 * @flags: Flags specifying quota properties.
204 * @restrict_link: Optional link restriction method for new keyrings.
204 * 205 *
205 * Allocate a key of the specified type with the attributes given. The key is 206 * Allocate a key of the specified type with the attributes given. The key is
206 * returned in an uninstantiated state and the caller needs to instantiate the 207 * returned in an uninstantiated state and the caller needs to instantiate the
@@ -223,7 +224,10 @@ serial_exists:
223 */ 224 */
224struct key *key_alloc(struct key_type *type, const char *desc, 225struct key *key_alloc(struct key_type *type, const char *desc,
225 kuid_t uid, kgid_t gid, const struct cred *cred, 226 kuid_t uid, kgid_t gid, const struct cred *cred,
226 key_perm_t perm, unsigned long flags) 227 key_perm_t perm, unsigned long flags,
228 int (*restrict_link)(struct key *,
229 const struct key_type *,
230 const union key_payload *))
227{ 231{
228 struct key_user *user = NULL; 232 struct key_user *user = NULL;
229 struct key *key; 233 struct key *key;
@@ -291,11 +295,10 @@ struct key *key_alloc(struct key_type *type, const char *desc,
291 key->uid = uid; 295 key->uid = uid;
292 key->gid = gid; 296 key->gid = gid;
293 key->perm = perm; 297 key->perm = perm;
298 key->restrict_link = restrict_link;
294 299
295 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 300 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
296 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 301 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
297 if (flags & KEY_ALLOC_TRUSTED)
298 key->flags |= 1 << KEY_FLAG_TRUSTED;
299 if (flags & KEY_ALLOC_BUILT_IN) 302 if (flags & KEY_ALLOC_BUILT_IN)
300 key->flags |= 1 << KEY_FLAG_BUILTIN; 303 key->flags |= 1 << KEY_FLAG_BUILTIN;
301 304
@@ -496,6 +499,12 @@ int key_instantiate_and_link(struct key *key,
496 } 499 }
497 500
498 if (keyring) { 501 if (keyring) {
502 if (keyring->restrict_link) {
503 ret = keyring->restrict_link(keyring, key->type,
504 &prep.payload);
505 if (ret < 0)
506 goto error;
507 }
499 ret = __key_link_begin(keyring, &key->index_key, &edit); 508 ret = __key_link_begin(keyring, &key->index_key, &edit);
500 if (ret < 0) 509 if (ret < 0)
501 goto error; 510 goto error;
@@ -551,8 +560,12 @@ int key_reject_and_link(struct key *key,
551 awaken = 0; 560 awaken = 0;
552 ret = -EBUSY; 561 ret = -EBUSY;
553 562
554 if (keyring) 563 if (keyring) {
564 if (keyring->restrict_link)
565 return -EPERM;
566
555 link_ret = __key_link_begin(keyring, &key->index_key, &edit); 567 link_ret = __key_link_begin(keyring, &key->index_key, &edit);
568 }
556 569
557 mutex_lock(&key_construction_mutex); 570 mutex_lock(&key_construction_mutex);
558 571
@@ -793,6 +806,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
793 struct key *keyring, *key = NULL; 806 struct key *keyring, *key = NULL;
794 key_ref_t key_ref; 807 key_ref_t key_ref;
795 int ret; 808 int ret;
809 int (*restrict_link)(struct key *,
810 const struct key_type *,
811 const union key_payload *) = NULL;
796 812
797 /* look up the key type to see if it's one of the registered kernel 813 /* look up the key type to see if it's one of the registered kernel
798 * types */ 814 * types */
@@ -811,6 +827,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 827
812 key_check(keyring); 828 key_check(keyring);
813 829
830 key_ref = ERR_PTR(-EPERM);
831 if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
832 restrict_link = keyring->restrict_link;
833
814 key_ref = ERR_PTR(-ENOTDIR); 834 key_ref = ERR_PTR(-ENOTDIR);
815 if (keyring->type != &key_type_keyring) 835 if (keyring->type != &key_type_keyring)
816 goto error_put_type; 836 goto error_put_type;
@@ -819,7 +839,6 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
819 prep.data = payload; 839 prep.data = payload;
820 prep.datalen = plen; 840 prep.datalen = plen;
821 prep.quotalen = index_key.type->def_datalen; 841 prep.quotalen = index_key.type->def_datalen;
822 prep.trusted = flags & KEY_ALLOC_TRUSTED;
823 prep.expiry = TIME_T_MAX; 842 prep.expiry = TIME_T_MAX;
824 if (index_key.type->preparse) { 843 if (index_key.type->preparse) {
825 ret = index_key.type->preparse(&prep); 844 ret = index_key.type->preparse(&prep);
@@ -835,10 +854,13 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
835 } 854 }
836 index_key.desc_len = strlen(index_key.description); 855 index_key.desc_len = strlen(index_key.description);
837 856
838 key_ref = ERR_PTR(-EPERM); 857 if (restrict_link) {
839 if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags)) 858 ret = restrict_link(keyring, index_key.type, &prep.payload);
840 goto error_free_prep; 859 if (ret < 0) {
841 flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0; 860 key_ref = ERR_PTR(ret);
861 goto error_free_prep;
862 }
863 }
842 864
843 ret = __key_link_begin(keyring, &index_key, &edit); 865 ret = __key_link_begin(keyring, &index_key, &edit);
844 if (ret < 0) { 866 if (ret < 0) {
@@ -879,7 +901,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
879 901
880 /* allocate a new key */ 902 /* allocate a new key */
881 key = key_alloc(index_key.type, index_key.description, 903 key = key_alloc(index_key.type, index_key.description,
882 cred->fsuid, cred->fsgid, cred, perm, flags); 904 cred->fsuid, cred->fsgid, cred, perm, flags, NULL);
883 if (IS_ERR(key)) { 905 if (IS_ERR(key)) {
884 key_ref = ERR_CAST(key); 906 key_ref = ERR_CAST(key);
885 goto error_link_end; 907 goto error_link_end;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index ed73c6c1c326..3b135a0af344 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1686,6 +1686,11 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
1686 case KEYCTL_GET_PERSISTENT: 1686 case KEYCTL_GET_PERSISTENT:
1687 return keyctl_get_persistent((uid_t)arg2, (key_serial_t)arg3); 1687 return keyctl_get_persistent((uid_t)arg2, (key_serial_t)arg3);
1688 1688
1689 case KEYCTL_DH_COMPUTE:
1690 return keyctl_dh_compute((struct keyctl_dh_params __user *) arg2,
1691 (char __user *) arg3,
1692 (size_t) arg4);
1693
1689 default: 1694 default:
1690 return -EOPNOTSUPP; 1695 return -EOPNOTSUPP;
1691 } 1696 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index f931ccfeefb0..c91e4e0cea08 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -491,13 +491,17 @@ static long keyring_read(const struct key *keyring,
491 */ 491 */
492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
493 const struct cred *cred, key_perm_t perm, 493 const struct cred *cred, key_perm_t perm,
494 unsigned long flags, struct key *dest) 494 unsigned long flags,
495 int (*restrict_link)(struct key *,
496 const struct key_type *,
497 const union key_payload *),
498 struct key *dest)
495{ 499{
496 struct key *keyring; 500 struct key *keyring;
497 int ret; 501 int ret;
498 502
499 keyring = key_alloc(&key_type_keyring, description, 503 keyring = key_alloc(&key_type_keyring, description,
500 uid, gid, cred, perm, flags); 504 uid, gid, cred, perm, flags, restrict_link);
501 if (!IS_ERR(keyring)) { 505 if (!IS_ERR(keyring)) {
502 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 506 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
503 if (ret < 0) { 507 if (ret < 0) {
@@ -510,6 +514,26 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
510} 514}
511EXPORT_SYMBOL(keyring_alloc); 515EXPORT_SYMBOL(keyring_alloc);
512 516
517/**
518 * restrict_link_reject - Give -EPERM to restrict link
519 * @keyring: The keyring being added to.
520 * @type: The type of key being added.
521 * @payload: The payload of the key intended to be added.
522 *
523 * Reject the addition of any links to a keyring. It can be overridden by
524 * passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when
525 * adding a key to a keyring.
526 *
527 * This is meant to be passed as the restrict_link parameter to
528 * keyring_alloc().
529 */
530int restrict_link_reject(struct key *keyring,
531 const struct key_type *type,
532 const union key_payload *payload)
533{
534 return -EPERM;
535}
536
513/* 537/*
514 * By default, we keys found by getting an exact match on their descriptions. 538 * By default, we keys found by getting an exact match on their descriptions.
515 */ 539 */
@@ -1191,6 +1215,16 @@ void __key_link_end(struct key *keyring,
1191 up_write(&keyring->sem); 1215 up_write(&keyring->sem);
1192} 1216}
1193 1217
1218/*
1219 * Check addition of keys to restricted keyrings.
1220 */
1221static int __key_link_check_restriction(struct key *keyring, struct key *key)
1222{
1223 if (!keyring->restrict_link)
1224 return 0;
1225 return keyring->restrict_link(keyring, key->type, &key->payload);
1226}
1227
1194/** 1228/**
1195 * key_link - Link a key to a keyring 1229 * key_link - Link a key to a keyring
1196 * @keyring: The keyring to make the link in. 1230 * @keyring: The keyring to make the link in.
@@ -1221,14 +1255,12 @@ int key_link(struct key *keyring, struct key *key)
1221 key_check(keyring); 1255 key_check(keyring);
1222 key_check(key); 1256 key_check(key);
1223 1257
1224 if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&
1225 !test_bit(KEY_FLAG_TRUSTED, &key->flags))
1226 return -EPERM;
1227
1228 ret = __key_link_begin(keyring, &key->index_key, &edit); 1258 ret = __key_link_begin(keyring, &key->index_key, &edit);
1229 if (ret == 0) { 1259 if (ret == 0) {
1230 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage)); 1260 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));
1231 ret = __key_link_check_live_key(keyring, key); 1261 ret = __key_link_check_restriction(keyring, key);
1262 if (ret == 0)
1263 ret = __key_link_check_live_key(keyring, key);
1232 if (ret == 0) 1264 if (ret == 0)
1233 __key_link(key, &edit); 1265 __key_link(key, &edit);
1234 __key_link_end(keyring, &key->index_key, edit); 1266 __key_link_end(keyring, &key->index_key, edit);
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index c9fae5ea89fe..2ef45b319dd9 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -26,7 +26,7 @@ static int key_create_persistent_register(struct user_namespace *ns)
26 current_cred(), 26 current_cred(),
27 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 27 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
28 KEY_USR_VIEW | KEY_USR_READ), 28 KEY_USR_VIEW | KEY_USR_READ),
29 KEY_ALLOC_NOT_IN_QUOTA, NULL); 29 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
30 if (IS_ERR(reg)) 30 if (IS_ERR(reg))
31 return PTR_ERR(reg); 31 return PTR_ERR(reg);
32 32
@@ -60,7 +60,7 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
60 uid, INVALID_GID, current_cred(), 60 uid, INVALID_GID, current_cred(),
61 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 61 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
62 KEY_USR_VIEW | KEY_USR_READ), 62 KEY_USR_VIEW | KEY_USR_READ),
63 KEY_ALLOC_NOT_IN_QUOTA, 63 KEY_ALLOC_NOT_IN_QUOTA, NULL,
64 ns->persistent_keyring_register); 64 ns->persistent_keyring_register);
65 if (IS_ERR(persistent)) 65 if (IS_ERR(persistent))
66 return ERR_CAST(persistent); 66 return ERR_CAST(persistent);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index e6d50172872f..40a885239782 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -76,7 +76,8 @@ int install_user_keyrings(void)
76 if (IS_ERR(uid_keyring)) { 76 if (IS_ERR(uid_keyring)) {
77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
78 cred, user_keyring_perm, 78 cred, user_keyring_perm,
79 KEY_ALLOC_IN_QUOTA, NULL); 79 KEY_ALLOC_IN_QUOTA,
80 NULL, NULL);
80 if (IS_ERR(uid_keyring)) { 81 if (IS_ERR(uid_keyring)) {
81 ret = PTR_ERR(uid_keyring); 82 ret = PTR_ERR(uid_keyring);
82 goto error; 83 goto error;
@@ -92,7 +93,8 @@ int install_user_keyrings(void)
92 session_keyring = 93 session_keyring =
93 keyring_alloc(buf, user->uid, INVALID_GID, 94 keyring_alloc(buf, user->uid, INVALID_GID,
94 cred, user_keyring_perm, 95 cred, user_keyring_perm,
95 KEY_ALLOC_IN_QUOTA, NULL); 96 KEY_ALLOC_IN_QUOTA,
97 NULL, NULL);
96 if (IS_ERR(session_keyring)) { 98 if (IS_ERR(session_keyring)) {
97 ret = PTR_ERR(session_keyring); 99 ret = PTR_ERR(session_keyring);
98 goto error_release; 100 goto error_release;
@@ -134,7 +136,8 @@ int install_thread_keyring_to_cred(struct cred *new)
134 136
135 keyring = keyring_alloc("_tid", new->uid, new->gid, new, 137 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
136 KEY_POS_ALL | KEY_USR_VIEW, 138 KEY_POS_ALL | KEY_USR_VIEW,
137 KEY_ALLOC_QUOTA_OVERRUN, NULL); 139 KEY_ALLOC_QUOTA_OVERRUN,
140 NULL, NULL);
138 if (IS_ERR(keyring)) 141 if (IS_ERR(keyring))
139 return PTR_ERR(keyring); 142 return PTR_ERR(keyring);
140 143
@@ -180,7 +183,8 @@ int install_process_keyring_to_cred(struct cred *new)
180 183
181 keyring = keyring_alloc("_pid", new->uid, new->gid, new, 184 keyring = keyring_alloc("_pid", new->uid, new->gid, new,
182 KEY_POS_ALL | KEY_USR_VIEW, 185 KEY_POS_ALL | KEY_USR_VIEW,
183 KEY_ALLOC_QUOTA_OVERRUN, NULL); 186 KEY_ALLOC_QUOTA_OVERRUN,
187 NULL, NULL);
184 if (IS_ERR(keyring)) 188 if (IS_ERR(keyring))
185 return PTR_ERR(keyring); 189 return PTR_ERR(keyring);
186 190
@@ -231,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
231 235
232 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred, 236 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
233 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 237 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
234 flags, NULL); 238 flags, NULL, NULL);
235 if (IS_ERR(keyring)) 239 if (IS_ERR(keyring))
236 return PTR_ERR(keyring); 240 return PTR_ERR(keyring);
237 } else { 241 } else {
@@ -785,7 +789,7 @@ long join_session_keyring(const char *name)
785 keyring = keyring_alloc( 789 keyring = keyring_alloc(
786 name, old->uid, old->gid, old, 790 name, old->uid, old->gid, old,
787 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK, 791 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
788 KEY_ALLOC_IN_QUOTA, NULL); 792 KEY_ALLOC_IN_QUOTA, NULL, NULL);
789 if (IS_ERR(keyring)) { 793 if (IS_ERR(keyring)) {
790 ret = PTR_ERR(keyring); 794 ret = PTR_ERR(keyring);
791 goto error2; 795 goto error2;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index c7a117c9a8f3..a29e3554751e 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -116,7 +116,7 @@ static int call_sbin_request_key(struct key_construction *cons,
116 cred = get_current_cred(); 116 cred = get_current_cred();
117 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred, 117 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
118 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 118 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
119 KEY_ALLOC_QUOTA_OVERRUN, NULL); 119 KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
120 put_cred(cred); 120 put_cred(cred);
121 if (IS_ERR(keyring)) { 121 if (IS_ERR(keyring)) {
122 ret = PTR_ERR(keyring); 122 ret = PTR_ERR(keyring);
@@ -355,7 +355,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
355 355
356 key = key_alloc(ctx->index_key.type, ctx->index_key.description, 356 key = key_alloc(ctx->index_key.type, ctx->index_key.description,
357 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, 357 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
358 perm, flags); 358 perm, flags, NULL);
359 if (IS_ERR(key)) 359 if (IS_ERR(key))
360 goto alloc_failed; 360 goto alloc_failed;
361 361
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 4f0f112fe276..9db8b4a82787 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -202,7 +202,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
202 authkey = key_alloc(&key_type_request_key_auth, desc, 202 authkey = key_alloc(&key_type_request_key_auth, desc,
203 cred->fsuid, cred->fsgid, cred, 203 cred->fsuid, cred->fsgid, cred,
204 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 204 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); 205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
206 if (IS_ERR(authkey)) { 206 if (IS_ERR(authkey)) {
207 ret = PTR_ERR(authkey); 207 ret = PTR_ERR(authkey);
208 goto error_alloc; 208 goto error_alloc;
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 8705d79b2c6f..66b1840b4110 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -96,45 +96,25 @@ EXPORT_SYMBOL_GPL(user_free_preparse);
96 */ 96 */
97int user_update(struct key *key, struct key_preparsed_payload *prep) 97int user_update(struct key *key, struct key_preparsed_payload *prep)
98{ 98{
99 struct user_key_payload *upayload, *zap; 99 struct user_key_payload *zap = NULL;
100 size_t datalen = prep->datalen;
101 int ret; 100 int ret;
102 101
103 ret = -EINVAL;
104 if (datalen <= 0 || datalen > 32767 || !prep->data)
105 goto error;
106
107 /* construct a replacement payload */
108 ret = -ENOMEM;
109 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
110 if (!upayload)
111 goto error;
112
113 upayload->datalen = datalen;
114 memcpy(upayload->data, prep->data, datalen);
115
116 /* check the quota and attach the new data */ 102 /* check the quota and attach the new data */
117 zap = upayload; 103 ret = key_payload_reserve(key, prep->datalen);
118 104 if (ret < 0)
119 ret = key_payload_reserve(key, datalen); 105 return ret;
120 106
121 if (ret == 0) { 107 /* attach the new data, displacing the old */
122 /* attach the new data, displacing the old */ 108 key->expiry = prep->expiry;
123 if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 109 if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
124 zap = key->payload.data[0]; 110 zap = rcu_dereference_key(key);
125 else 111 rcu_assign_keypointer(key, prep->payload.data[0]);
126 zap = NULL; 112 prep->payload.data[0] = NULL;
127 rcu_assign_keypointer(key, upayload);
128 key->expiry = 0;
129 }
130 113
131 if (zap) 114 if (zap)
132 kfree_rcu(zap, rcu); 115 kfree_rcu(zap, rcu);
133
134error:
135 return ret; 116 return ret;
136} 117}
137
138EXPORT_SYMBOL_GPL(user_update); 118EXPORT_SYMBOL_GPL(user_update);
139 119
140/* 120/*