aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-07-18 13:56:36 -0400
committerDavid Howells <dhowells@redhat.com>2014-07-22 16:46:47 -0400
commit002edaf76f09af658241029817f5ef66f6bef5e4 (patch)
tree2b04fa0c47ba3b9dfca97bb769cfae3aa0bbeffe /security
parent8a7a3eb4ddbe7c7e639170a64adede7cbd5a9247 (diff)
KEYS: big_key: Use key preparsing
Make use of key preparsing in the big key type so that quota size determination can take place prior to keyring locking when a key is being added. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'security')
-rw-r--r--security/keys/big_key.c41
1 files changed, 25 insertions, 16 deletions
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 */