diff options
Diffstat (limited to 'security/keys')
| -rw-r--r-- | security/keys/internal.h | 13 | ||||
| -rw-r--r-- | security/keys/key.c | 5 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 1 | ||||
| -rw-r--r-- | security/keys/keyring.c | 4 | ||||
| -rw-r--r-- | security/keys/proc.c | 3 | ||||
| -rw-r--r-- | security/keys/process_keys.c | 1 | ||||
| -rw-r--r-- | security/keys/request_key.c | 73 | ||||
| -rw-r--r-- | security/keys/request_key_auth.c | 18 |
8 files changed, 48 insertions, 70 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index 479909b858c7..8f533c81aa8d 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
| @@ -186,20 +186,9 @@ static inline int key_permission(const key_ref_t key_ref, unsigned perm) | |||
| 186 | return key_task_permission(key_ref, current_cred(), perm); | 186 | return key_task_permission(key_ref, current_cred(), perm); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | /* | ||
| 190 | * Authorisation record for request_key(). | ||
| 191 | */ | ||
| 192 | struct request_key_auth { | ||
| 193 | struct key *target_key; | ||
| 194 | struct key *dest_keyring; | ||
| 195 | const struct cred *cred; | ||
| 196 | void *callout_info; | ||
| 197 | size_t callout_len; | ||
| 198 | pid_t pid; | ||
| 199 | } __randomize_layout; | ||
| 200 | |||
| 201 | extern struct key_type key_type_request_key_auth; | 189 | extern struct key_type key_type_request_key_auth; |
| 202 | extern struct key *request_key_auth_new(struct key *target, | 190 | extern struct key *request_key_auth_new(struct key *target, |
| 191 | const char *op, | ||
| 203 | const void *callout_info, | 192 | const void *callout_info, |
| 204 | size_t callout_len, | 193 | size_t callout_len, |
| 205 | struct key *dest_keyring); | 194 | struct key *dest_keyring); |
diff --git a/security/keys/key.c b/security/keys/key.c index 44a80d6741a1..696f1c092c50 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
| @@ -265,8 +265,8 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
| 265 | 265 | ||
| 266 | spin_lock(&user->lock); | 266 | spin_lock(&user->lock); |
| 267 | if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { | 267 | if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { |
| 268 | if (user->qnkeys + 1 >= maxkeys || | 268 | if (user->qnkeys + 1 > maxkeys || |
| 269 | user->qnbytes + quotalen >= maxbytes || | 269 | user->qnbytes + quotalen > maxbytes || |
| 270 | user->qnbytes + quotalen < user->qnbytes) | 270 | user->qnbytes + quotalen < user->qnbytes) |
| 271 | goto no_quota; | 271 | goto no_quota; |
| 272 | } | 272 | } |
| @@ -297,6 +297,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
| 297 | key->gid = gid; | 297 | key->gid = gid; |
| 298 | key->perm = perm; | 298 | key->perm = perm; |
| 299 | key->restrict_link = restrict_link; | 299 | key->restrict_link = restrict_link; |
| 300 | key->last_used_at = ktime_get_real_seconds(); | ||
| 300 | 301 | ||
| 301 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) | 302 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) |
| 302 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; | 303 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index e8093d025966..7bbe03593e58 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/security.h> | 25 | #include <linux/security.h> |
| 26 | #include <linux/uio.h> | 26 | #include <linux/uio.h> |
| 27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
| 28 | #include <keys/request_key_auth-type.h> | ||
| 28 | #include "internal.h" | 29 | #include "internal.h" |
| 29 | 30 | ||
| 30 | #define KEY_MAX_DESC_SIZE 4096 | 31 | #define KEY_MAX_DESC_SIZE 4096 |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index eadebb92986a..f81372f53dd7 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
| @@ -661,9 +661,6 @@ static bool search_nested_keyrings(struct key *keyring, | |||
| 661 | BUG_ON((ctx->flags & STATE_CHECKS) == 0 || | 661 | BUG_ON((ctx->flags & STATE_CHECKS) == 0 || |
| 662 | (ctx->flags & STATE_CHECKS) == STATE_CHECKS); | 662 | (ctx->flags & STATE_CHECKS) == STATE_CHECKS); |
| 663 | 663 | ||
| 664 | if (ctx->index_key.description) | ||
| 665 | ctx->index_key.desc_len = strlen(ctx->index_key.description); | ||
| 666 | |||
| 667 | /* Check to see if this top-level keyring is what we are looking for | 664 | /* Check to see if this top-level keyring is what we are looking for |
| 668 | * and whether it is valid or not. | 665 | * and whether it is valid or not. |
| 669 | */ | 666 | */ |
| @@ -914,6 +911,7 @@ key_ref_t keyring_search(key_ref_t keyring, | |||
| 914 | struct keyring_search_context ctx = { | 911 | struct keyring_search_context ctx = { |
| 915 | .index_key.type = type, | 912 | .index_key.type = type, |
| 916 | .index_key.description = description, | 913 | .index_key.description = description, |
| 914 | .index_key.desc_len = strlen(description), | ||
| 917 | .cred = current_cred(), | 915 | .cred = current_cred(), |
| 918 | .match_data.cmp = key_default_cmp, | 916 | .match_data.cmp = key_default_cmp, |
| 919 | .match_data.raw_data = description, | 917 | .match_data.raw_data = description, |
diff --git a/security/keys/proc.c b/security/keys/proc.c index d2b802072693..78ac305d715e 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
| @@ -165,8 +165,7 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
| 165 | int rc; | 165 | int rc; |
| 166 | 166 | ||
| 167 | struct keyring_search_context ctx = { | 167 | struct keyring_search_context ctx = { |
| 168 | .index_key.type = key->type, | 168 | .index_key = key->index_key, |
| 169 | .index_key.description = key->description, | ||
| 170 | .cred = m->file->f_cred, | 169 | .cred = m->file->f_cred, |
| 171 | .match_data.cmp = lookup_user_key_possessed, | 170 | .match_data.cmp = lookup_user_key_possessed, |
| 172 | .match_data.raw_data = key, | 171 | .match_data.raw_data = key, |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 02c77e928f68..0e0b9ccad2f8 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/security.h> | 19 | #include <linux/security.h> |
| 20 | #include <linux/user_namespace.h> | 20 | #include <linux/user_namespace.h> |
| 21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| 22 | #include <keys/request_key_auth-type.h> | ||
| 22 | #include "internal.h" | 23 | #include "internal.h" |
| 23 | 24 | ||
| 24 | /* Session keyring create vs join semaphore */ | 25 | /* Session keyring create vs join semaphore */ |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 301f0e300dbd..7a0c6b666ff0 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
| @@ -18,31 +18,30 @@ | |||
| 18 | #include <linux/keyctl.h> | 18 | #include <linux/keyctl.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include "internal.h" | 20 | #include "internal.h" |
| 21 | #include <keys/request_key_auth-type.h> | ||
| 21 | 22 | ||
| 22 | #define key_negative_timeout 60 /* default timeout on a negative key's existence */ | 23 | #define key_negative_timeout 60 /* default timeout on a negative key's existence */ |
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| 25 | * complete_request_key - Complete the construction of a key. | 26 | * complete_request_key - Complete the construction of a key. |
| 26 | * @cons: The key construction record. | 27 | * @auth_key: The authorisation key. |
| 27 | * @error: The success or failute of the construction. | 28 | * @error: The success or failute of the construction. |
| 28 | * | 29 | * |
| 29 | * Complete the attempt to construct a key. The key will be negated | 30 | * Complete the attempt to construct a key. The key will be negated |
| 30 | * if an error is indicated. The authorisation key will be revoked | 31 | * if an error is indicated. The authorisation key will be revoked |
| 31 | * unconditionally. | 32 | * unconditionally. |
| 32 | */ | 33 | */ |
| 33 | void complete_request_key(struct key_construction *cons, int error) | 34 | void complete_request_key(struct key *authkey, int error) |
| 34 | { | 35 | { |
| 35 | kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error); | 36 | struct request_key_auth *rka = get_request_key_auth(authkey); |
| 37 | struct key *key = rka->target_key; | ||
| 38 | |||
| 39 | kenter("%d{%d},%d", authkey->serial, key->serial, error); | ||
| 36 | 40 | ||
| 37 | if (error < 0) | 41 | if (error < 0) |
| 38 | key_negate_and_link(cons->key, key_negative_timeout, NULL, | 42 | key_negate_and_link(key, key_negative_timeout, NULL, authkey); |
| 39 | cons->authkey); | ||
| 40 | else | 43 | else |
| 41 | key_revoke(cons->authkey); | 44 | key_revoke(authkey); |
| 42 | |||
| 43 | key_put(cons->key); | ||
| 44 | key_put(cons->authkey); | ||
| 45 | kfree(cons); | ||
| 46 | } | 45 | } |
| 47 | EXPORT_SYMBOL(complete_request_key); | 46 | EXPORT_SYMBOL(complete_request_key); |
| 48 | 47 | ||
| @@ -91,21 +90,19 @@ static int call_usermodehelper_keys(const char *path, char **argv, char **envp, | |||
| 91 | * Request userspace finish the construction of a key | 90 | * Request userspace finish the construction of a key |
| 92 | * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" | 91 | * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" |
| 93 | */ | 92 | */ |
| 94 | static int call_sbin_request_key(struct key_construction *cons, | 93 | static int call_sbin_request_key(struct key *authkey, void *aux) |
| 95 | const char *op, | ||
| 96 | void *aux) | ||
| 97 | { | 94 | { |
| 98 | static char const request_key[] = "/sbin/request-key"; | 95 | static char const request_key[] = "/sbin/request-key"; |
| 96 | struct request_key_auth *rka = get_request_key_auth(authkey); | ||
| 99 | const struct cred *cred = current_cred(); | 97 | const struct cred *cred = current_cred(); |
| 100 | key_serial_t prkey, sskey; | 98 | key_serial_t prkey, sskey; |
| 101 | struct key *key = cons->key, *authkey = cons->authkey, *keyring, | 99 | struct key *key = rka->target_key, *keyring, *session; |
| 102 | *session; | ||
| 103 | char *argv[9], *envp[3], uid_str[12], gid_str[12]; | 100 | char *argv[9], *envp[3], uid_str[12], gid_str[12]; |
| 104 | char key_str[12], keyring_str[3][12]; | 101 | char key_str[12], keyring_str[3][12]; |
| 105 | char desc[20]; | 102 | char desc[20]; |
| 106 | int ret, i; | 103 | int ret, i; |
| 107 | 104 | ||
| 108 | kenter("{%d},{%d},%s", key->serial, authkey->serial, op); | 105 | kenter("{%d},{%d},%s", key->serial, authkey->serial, rka->op); |
| 109 | 106 | ||
| 110 | ret = install_user_keyrings(); | 107 | ret = install_user_keyrings(); |
| 111 | if (ret < 0) | 108 | if (ret < 0) |
| @@ -163,7 +160,7 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
| 163 | /* set up the argument list */ | 160 | /* set up the argument list */ |
| 164 | i = 0; | 161 | i = 0; |
| 165 | argv[i++] = (char *)request_key; | 162 | argv[i++] = (char *)request_key; |
| 166 | argv[i++] = (char *) op; | 163 | argv[i++] = (char *)rka->op; |
| 167 | argv[i++] = key_str; | 164 | argv[i++] = key_str; |
| 168 | argv[i++] = uid_str; | 165 | argv[i++] = uid_str; |
| 169 | argv[i++] = gid_str; | 166 | argv[i++] = gid_str; |
| @@ -191,7 +188,7 @@ error_link: | |||
| 191 | key_put(keyring); | 188 | key_put(keyring); |
| 192 | 189 | ||
| 193 | error_alloc: | 190 | error_alloc: |
| 194 | complete_request_key(cons, ret); | 191 | complete_request_key(authkey, ret); |
| 195 | kleave(" = %d", ret); | 192 | kleave(" = %d", ret); |
| 196 | return ret; | 193 | return ret; |
| 197 | } | 194 | } |
| @@ -205,42 +202,31 @@ static int construct_key(struct key *key, const void *callout_info, | |||
| 205 | size_t callout_len, void *aux, | 202 | size_t callout_len, void *aux, |
| 206 | struct key *dest_keyring) | 203 | struct key *dest_keyring) |
| 207 | { | 204 | { |
| 208 | struct key_construction *cons; | ||
| 209 | request_key_actor_t actor; | 205 | request_key_actor_t actor; |
| 210 | struct key *authkey; | 206 | struct key *authkey; |
| 211 | int ret; | 207 | int ret; |
| 212 | 208 | ||
| 213 | kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); | 209 | kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); |
| 214 | 210 | ||
| 215 | cons = kmalloc(sizeof(*cons), GFP_KERNEL); | ||
| 216 | if (!cons) | ||
| 217 | return -ENOMEM; | ||
| 218 | |||
| 219 | /* allocate an authorisation key */ | 211 | /* allocate an authorisation key */ |
| 220 | authkey = request_key_auth_new(key, callout_info, callout_len, | 212 | authkey = request_key_auth_new(key, "create", callout_info, callout_len, |
| 221 | dest_keyring); | 213 | dest_keyring); |
| 222 | if (IS_ERR(authkey)) { | 214 | if (IS_ERR(authkey)) |
| 223 | kfree(cons); | 215 | return PTR_ERR(authkey); |
| 224 | ret = PTR_ERR(authkey); | ||
| 225 | authkey = NULL; | ||
| 226 | } else { | ||
| 227 | cons->authkey = key_get(authkey); | ||
| 228 | cons->key = key_get(key); | ||
| 229 | 216 | ||
| 230 | /* make the call */ | 217 | /* Make the call */ |
| 231 | actor = call_sbin_request_key; | 218 | actor = call_sbin_request_key; |
| 232 | if (key->type->request_key) | 219 | if (key->type->request_key) |
| 233 | actor = key->type->request_key; | 220 | actor = key->type->request_key; |
| 234 | 221 | ||
| 235 | ret = actor(cons, "create", aux); | 222 | ret = actor(authkey, aux); |
| 236 | 223 | ||
| 237 | /* check that the actor called complete_request_key() prior to | 224 | /* check that the actor called complete_request_key() prior to |
| 238 | * returning an error */ | 225 | * returning an error */ |
| 239 | WARN_ON(ret < 0 && | 226 | WARN_ON(ret < 0 && |
| 240 | !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); | 227 | !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); |
| 241 | key_put(authkey); | ||
| 242 | } | ||
| 243 | 228 | ||
| 229 | key_put(authkey); | ||
| 244 | kleave(" = %d", ret); | 230 | kleave(" = %d", ret); |
| 245 | return ret; | 231 | return ret; |
| 246 | } | 232 | } |
| @@ -275,7 +261,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring) | |||
| 275 | if (cred->request_key_auth) { | 261 | if (cred->request_key_auth) { |
| 276 | authkey = cred->request_key_auth; | 262 | authkey = cred->request_key_auth; |
| 277 | down_read(&authkey->sem); | 263 | down_read(&authkey->sem); |
| 278 | rka = authkey->payload.data[0]; | 264 | rka = get_request_key_auth(authkey); |
| 279 | if (!test_bit(KEY_FLAG_REVOKED, | 265 | if (!test_bit(KEY_FLAG_REVOKED, |
| 280 | &authkey->flags)) | 266 | &authkey->flags)) |
| 281 | dest_keyring = | 267 | dest_keyring = |
| @@ -545,6 +531,7 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 545 | struct keyring_search_context ctx = { | 531 | struct keyring_search_context ctx = { |
| 546 | .index_key.type = type, | 532 | .index_key.type = type, |
| 547 | .index_key.description = description, | 533 | .index_key.description = description, |
| 534 | .index_key.desc_len = strlen(description), | ||
| 548 | .cred = current_cred(), | 535 | .cred = current_cred(), |
| 549 | .match_data.cmp = key_default_cmp, | 536 | .match_data.cmp = key_default_cmp, |
| 550 | .match_data.raw_data = description, | 537 | .match_data.raw_data = description, |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 87ea2f54dedc..bda6201c6c45 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
| 19 | #include "internal.h" | 19 | #include "internal.h" |
| 20 | #include <keys/user-type.h> | 20 | #include <keys/request_key_auth-type.h> |
| 21 | 21 | ||
| 22 | static int request_key_auth_preparse(struct key_preparsed_payload *); | 22 | static int request_key_auth_preparse(struct key_preparsed_payload *); |
| 23 | static void request_key_auth_free_preparse(struct key_preparsed_payload *); | 23 | static void request_key_auth_free_preparse(struct key_preparsed_payload *); |
| @@ -68,7 +68,7 @@ static int request_key_auth_instantiate(struct key *key, | |||
| 68 | static void request_key_auth_describe(const struct key *key, | 68 | static void request_key_auth_describe(const struct key *key, |
| 69 | struct seq_file *m) | 69 | struct seq_file *m) |
| 70 | { | 70 | { |
| 71 | struct request_key_auth *rka = key->payload.data[0]; | 71 | struct request_key_auth *rka = get_request_key_auth(key); |
| 72 | 72 | ||
| 73 | seq_puts(m, "key:"); | 73 | seq_puts(m, "key:"); |
| 74 | seq_puts(m, key->description); | 74 | seq_puts(m, key->description); |
| @@ -83,7 +83,7 @@ static void request_key_auth_describe(const struct key *key, | |||
| 83 | static long request_key_auth_read(const struct key *key, | 83 | static long request_key_auth_read(const struct key *key, |
| 84 | char __user *buffer, size_t buflen) | 84 | char __user *buffer, size_t buflen) |
| 85 | { | 85 | { |
| 86 | struct request_key_auth *rka = key->payload.data[0]; | 86 | struct request_key_auth *rka = get_request_key_auth(key); |
| 87 | size_t datalen; | 87 | size_t datalen; |
| 88 | long ret; | 88 | long ret; |
| 89 | 89 | ||
| @@ -109,7 +109,7 @@ static long request_key_auth_read(const struct key *key, | |||
| 109 | */ | 109 | */ |
| 110 | static void request_key_auth_revoke(struct key *key) | 110 | static void request_key_auth_revoke(struct key *key) |
| 111 | { | 111 | { |
| 112 | struct request_key_auth *rka = key->payload.data[0]; | 112 | struct request_key_auth *rka = get_request_key_auth(key); |
| 113 | 113 | ||
| 114 | kenter("{%d}", key->serial); | 114 | kenter("{%d}", key->serial); |
| 115 | 115 | ||
| @@ -136,7 +136,7 @@ static void free_request_key_auth(struct request_key_auth *rka) | |||
| 136 | */ | 136 | */ |
| 137 | static void request_key_auth_destroy(struct key *key) | 137 | static void request_key_auth_destroy(struct key *key) |
| 138 | { | 138 | { |
| 139 | struct request_key_auth *rka = key->payload.data[0]; | 139 | struct request_key_auth *rka = get_request_key_auth(key); |
| 140 | 140 | ||
| 141 | kenter("{%d}", key->serial); | 141 | kenter("{%d}", key->serial); |
| 142 | 142 | ||
| @@ -147,8 +147,9 @@ static void request_key_auth_destroy(struct key *key) | |||
| 147 | * Create an authorisation token for /sbin/request-key or whoever to gain | 147 | * Create an authorisation token for /sbin/request-key or whoever to gain |
| 148 | * access to the caller's security data. | 148 | * access to the caller's security data. |
| 149 | */ | 149 | */ |
| 150 | struct key *request_key_auth_new(struct key *target, const void *callout_info, | 150 | struct key *request_key_auth_new(struct key *target, const char *op, |
| 151 | size_t callout_len, struct key *dest_keyring) | 151 | const void *callout_info, size_t callout_len, |
| 152 | struct key *dest_keyring) | ||
| 152 | { | 153 | { |
| 153 | struct request_key_auth *rka, *irka; | 154 | struct request_key_auth *rka, *irka; |
| 154 | const struct cred *cred = current->cred; | 155 | const struct cred *cred = current->cred; |
| @@ -166,6 +167,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, | |||
| 166 | if (!rka->callout_info) | 167 | if (!rka->callout_info) |
| 167 | goto error_free_rka; | 168 | goto error_free_rka; |
| 168 | rka->callout_len = callout_len; | 169 | rka->callout_len = callout_len; |
| 170 | strlcpy(rka->op, op, sizeof(rka->op)); | ||
| 169 | 171 | ||
| 170 | /* see if the calling process is already servicing the key request of | 172 | /* see if the calling process is already servicing the key request of |
| 171 | * another process */ | 173 | * another process */ |
| @@ -245,7 +247,7 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id) | |||
| 245 | struct key *authkey; | 247 | struct key *authkey; |
| 246 | key_ref_t authkey_ref; | 248 | key_ref_t authkey_ref; |
| 247 | 249 | ||
| 248 | sprintf(description, "%x", target_id); | 250 | ctx.index_key.desc_len = sprintf(description, "%x", target_id); |
| 249 | 251 | ||
| 250 | authkey_ref = search_process_keyrings(&ctx); | 252 | authkey_ref = search_process_keyrings(&ctx); |
| 251 | 253 | ||
