diff options
| -rw-r--r-- | include/keys/big_key-type.h | 3 | ||||
| -rw-r--r-- | security/keys/big_key.c | 41 |
2 files changed, 27 insertions, 17 deletions
diff --git a/include/keys/big_key-type.h b/include/keys/big_key-type.h index d69bc8af3292..e0970a578188 100644 --- a/include/keys/big_key-type.h +++ b/include/keys/big_key-type.h | |||
| @@ -16,7 +16,8 @@ | |||
| 16 | 16 | ||
| 17 | extern struct key_type key_type_big_key; | 17 | extern struct key_type key_type_big_key; |
| 18 | 18 | ||
| 19 | extern int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep); | 19 | extern int big_key_preparse(struct key_preparsed_payload *prep); |
| 20 | extern void big_key_free_preparse(struct key_preparsed_payload *prep); | ||
| 20 | extern void big_key_revoke(struct key *key); | 21 | extern void big_key_revoke(struct key *key); |
| 21 | extern void big_key_destroy(struct key *key); | 22 | extern void big_key_destroy(struct key *key); |
| 22 | extern void big_key_describe(const struct key *big_key, struct seq_file *m); | 23 | extern void big_key_describe(const struct key *big_key, struct seq_file *m); |
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 | */ |
