diff options
author | David Howells <dhowells@redhat.com> | 2014-07-18 13:56:36 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-07-22 16:46:47 -0400 |
commit | 002edaf76f09af658241029817f5ef66f6bef5e4 (patch) | |
tree | 2b04fa0c47ba3b9dfca97bb769cfae3aa0bbeffe /security | |
parent | 8a7a3eb4ddbe7c7e639170a64adede7cbd5a9247 (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.c | 41 |
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"); | |||
34 | struct key_type key_type_big_key = { | 34 | struct 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 | */ |
48 | int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) | 50 | int 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 | ||
105 | err_fput: | 103 | err_fput: |
106 | fput(file); | 104 | fput(file); |
107 | err_quota: | ||
108 | key_payload_reserve(key, 0); | ||
109 | error: | 105 | error: |
110 | return ret; | 106 | return ret; |
111 | } | 107 | } |
112 | 108 | ||
113 | /* | 109 | /* |
110 | * Clear preparsement. | ||
111 | */ | ||
112 | void 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 | */ |