diff options
| -rw-r--r-- | fs/nfs/nfs4idmap.c | 31 | ||||
| -rw-r--r-- | include/keys/request_key_auth-type.h | 36 | ||||
| -rw-r--r-- | include/linux/key-type.h | 22 | ||||
| -rw-r--r-- | lib/assoc_array.c | 8 | ||||
| -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/process_keys.c | 1 | ||||
| -rw-r--r-- | security/keys/request_key.c | 72 | ||||
| -rw-r--r-- | security/keys/request_key_auth.c | 16 |
10 files changed, 108 insertions, 97 deletions
diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 3f23b6840547..bf34ddaa2ad7 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/keyctl.h> | 44 | #include <linux/keyctl.h> |
| 45 | #include <linux/key-type.h> | 45 | #include <linux/key-type.h> |
| 46 | #include <keys/user-type.h> | 46 | #include <keys/user-type.h> |
| 47 | #include <keys/request_key_auth-type.h> | ||
| 47 | #include <linux/module.h> | 48 | #include <linux/module.h> |
| 48 | 49 | ||
| 49 | #include "internal.h" | 50 | #include "internal.h" |
| @@ -59,7 +60,7 @@ static struct key_type key_type_id_resolver_legacy; | |||
| 59 | struct idmap_legacy_upcalldata { | 60 | struct idmap_legacy_upcalldata { |
| 60 | struct rpc_pipe_msg pipe_msg; | 61 | struct rpc_pipe_msg pipe_msg; |
| 61 | struct idmap_msg idmap_msg; | 62 | struct idmap_msg idmap_msg; |
| 62 | struct key_construction *key_cons; | 63 | struct key *authkey; |
| 63 | struct idmap *idmap; | 64 | struct idmap *idmap; |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| @@ -384,7 +385,7 @@ static const match_table_t nfs_idmap_tokens = { | |||
| 384 | { Opt_find_err, NULL } | 385 | { Opt_find_err, NULL } |
| 385 | }; | 386 | }; |
| 386 | 387 | ||
| 387 | static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); | 388 | static int nfs_idmap_legacy_upcall(struct key *, void *); |
| 388 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, | 389 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, |
| 389 | size_t); | 390 | size_t); |
| 390 | static void idmap_release_pipe(struct inode *); | 391 | static void idmap_release_pipe(struct inode *); |
| @@ -549,11 +550,12 @@ nfs_idmap_prepare_pipe_upcall(struct idmap *idmap, | |||
| 549 | static void | 550 | static void |
| 550 | nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret) | 551 | nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret) |
| 551 | { | 552 | { |
| 552 | struct key_construction *cons = idmap->idmap_upcall_data->key_cons; | 553 | struct key *authkey = idmap->idmap_upcall_data->authkey; |
| 553 | 554 | ||
| 554 | kfree(idmap->idmap_upcall_data); | 555 | kfree(idmap->idmap_upcall_data); |
| 555 | idmap->idmap_upcall_data = NULL; | 556 | idmap->idmap_upcall_data = NULL; |
| 556 | complete_request_key(cons, ret); | 557 | complete_request_key(authkey, ret); |
| 558 | key_put(authkey); | ||
| 557 | } | 559 | } |
| 558 | 560 | ||
| 559 | static void | 561 | static void |
| @@ -563,15 +565,14 @@ nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret) | |||
| 563 | nfs_idmap_complete_pipe_upcall_locked(idmap, ret); | 565 | nfs_idmap_complete_pipe_upcall_locked(idmap, ret); |
| 564 | } | 566 | } |
| 565 | 567 | ||
| 566 | static int nfs_idmap_legacy_upcall(struct key_construction *cons, | 568 | static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux) |
| 567 | const char *op, | ||
| 568 | void *aux) | ||
| 569 | { | 569 | { |
| 570 | struct idmap_legacy_upcalldata *data; | 570 | struct idmap_legacy_upcalldata *data; |
| 571 | struct request_key_auth *rka = get_request_key_auth(authkey); | ||
| 571 | struct rpc_pipe_msg *msg; | 572 | struct rpc_pipe_msg *msg; |
| 572 | struct idmap_msg *im; | 573 | struct idmap_msg *im; |
| 573 | struct idmap *idmap = (struct idmap *)aux; | 574 | struct idmap *idmap = (struct idmap *)aux; |
| 574 | struct key *key = cons->key; | 575 | struct key *key = rka->target_key; |
| 575 | int ret = -ENOKEY; | 576 | int ret = -ENOKEY; |
| 576 | 577 | ||
| 577 | if (!aux) | 578 | if (!aux) |
| @@ -586,7 +587,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
| 586 | msg = &data->pipe_msg; | 587 | msg = &data->pipe_msg; |
| 587 | im = &data->idmap_msg; | 588 | im = &data->idmap_msg; |
| 588 | data->idmap = idmap; | 589 | data->idmap = idmap; |
| 589 | data->key_cons = cons; | 590 | data->authkey = key_get(authkey); |
| 590 | 591 | ||
| 591 | ret = nfs_idmap_prepare_message(key->description, idmap, im, msg); | 592 | ret = nfs_idmap_prepare_message(key->description, idmap, im, msg); |
| 592 | if (ret < 0) | 593 | if (ret < 0) |
| @@ -604,7 +605,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
| 604 | out2: | 605 | out2: |
| 605 | kfree(data); | 606 | kfree(data); |
| 606 | out1: | 607 | out1: |
| 607 | complete_request_key(cons, ret); | 608 | complete_request_key(authkey, ret); |
| 608 | return ret; | 609 | return ret; |
| 609 | } | 610 | } |
| 610 | 611 | ||
| @@ -651,9 +652,10 @@ out: | |||
| 651 | static ssize_t | 652 | static ssize_t |
| 652 | idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | 653 | idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) |
| 653 | { | 654 | { |
| 655 | struct request_key_auth *rka; | ||
| 654 | struct rpc_inode *rpci = RPC_I(file_inode(filp)); | 656 | struct rpc_inode *rpci = RPC_I(file_inode(filp)); |
| 655 | struct idmap *idmap = (struct idmap *)rpci->private; | 657 | struct idmap *idmap = (struct idmap *)rpci->private; |
| 656 | struct key_construction *cons; | 658 | struct key *authkey; |
| 657 | struct idmap_msg im; | 659 | struct idmap_msg im; |
| 658 | size_t namelen_in; | 660 | size_t namelen_in; |
| 659 | int ret = -ENOKEY; | 661 | int ret = -ENOKEY; |
| @@ -665,7 +667,8 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 665 | if (idmap->idmap_upcall_data == NULL) | 667 | if (idmap->idmap_upcall_data == NULL) |
| 666 | goto out_noupcall; | 668 | goto out_noupcall; |
| 667 | 669 | ||
| 668 | cons = idmap->idmap_upcall_data->key_cons; | 670 | authkey = idmap->idmap_upcall_data->authkey; |
| 671 | rka = get_request_key_auth(authkey); | ||
| 669 | 672 | ||
| 670 | if (mlen != sizeof(im)) { | 673 | if (mlen != sizeof(im)) { |
| 671 | ret = -ENOSPC; | 674 | ret = -ENOSPC; |
| @@ -690,9 +693,9 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 690 | 693 | ||
| 691 | ret = nfs_idmap_read_and_verify_message(&im, | 694 | ret = nfs_idmap_read_and_verify_message(&im, |
| 692 | &idmap->idmap_upcall_data->idmap_msg, | 695 | &idmap->idmap_upcall_data->idmap_msg, |
| 693 | cons->key, cons->authkey); | 696 | rka->target_key, authkey); |
| 694 | if (ret >= 0) { | 697 | if (ret >= 0) { |
| 695 | key_set_timeout(cons->key, nfs_idmap_cache_timeout); | 698 | key_set_timeout(rka->target_key, nfs_idmap_cache_timeout); |
| 696 | ret = mlen; | 699 | ret = mlen; |
| 697 | } | 700 | } |
| 698 | 701 | ||
diff --git a/include/keys/request_key_auth-type.h b/include/keys/request_key_auth-type.h new file mode 100644 index 000000000000..a726dd3f1dc6 --- /dev/null +++ b/include/keys/request_key_auth-type.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* request_key authorisation token key type | ||
| 2 | * | ||
| 3 | * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public Licence | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the Licence, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _KEYS_REQUEST_KEY_AUTH_TYPE_H | ||
| 13 | #define _KEYS_REQUEST_KEY_AUTH_TYPE_H | ||
| 14 | |||
| 15 | #include <linux/key.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Authorisation record for request_key(). | ||
| 19 | */ | ||
| 20 | struct request_key_auth { | ||
| 21 | struct key *target_key; | ||
| 22 | struct key *dest_keyring; | ||
| 23 | const struct cred *cred; | ||
| 24 | void *callout_info; | ||
| 25 | size_t callout_len; | ||
| 26 | pid_t pid; | ||
| 27 | char op[8]; | ||
| 28 | } __randomize_layout; | ||
| 29 | |||
| 30 | static inline struct request_key_auth *get_request_key_auth(const struct key *key) | ||
| 31 | { | ||
| 32 | return key->payload.data[0]; | ||
| 33 | } | ||
| 34 | |||
| 35 | |||
| 36 | #endif /* _KEYS_REQUEST_KEY_AUTH_TYPE_H */ | ||
diff --git a/include/linux/key-type.h b/include/linux/key-type.h index bc9af551fc83..e49d1de0614e 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h | |||
| @@ -21,15 +21,6 @@ struct kernel_pkey_query; | |||
| 21 | struct kernel_pkey_params; | 21 | struct kernel_pkey_params; |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | * key under-construction record | ||
| 25 | * - passed to the request_key actor if supplied | ||
| 26 | */ | ||
| 27 | struct key_construction { | ||
| 28 | struct key *key; /* key being constructed */ | ||
| 29 | struct key *authkey;/* authorisation for key being constructed */ | ||
| 30 | }; | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Pre-parsed payload, used by key add, update and instantiate. | 24 | * Pre-parsed payload, used by key add, update and instantiate. |
| 34 | * | 25 | * |
| 35 | * This struct will be cleared and data and datalen will be set with the data | 26 | * This struct will be cleared and data and datalen will be set with the data |
| @@ -50,8 +41,7 @@ struct key_preparsed_payload { | |||
| 50 | time64_t expiry; /* Expiry time of key */ | 41 | time64_t expiry; /* Expiry time of key */ |
| 51 | } __randomize_layout; | 42 | } __randomize_layout; |
| 52 | 43 | ||
| 53 | typedef int (*request_key_actor_t)(struct key_construction *key, | 44 | typedef int (*request_key_actor_t)(struct key *auth_key, void *aux); |
| 54 | const char *op, void *aux); | ||
| 55 | 45 | ||
| 56 | /* | 46 | /* |
| 57 | * Preparsed matching criterion. | 47 | * Preparsed matching criterion. |
| @@ -181,20 +171,20 @@ extern int key_instantiate_and_link(struct key *key, | |||
| 181 | const void *data, | 171 | const void *data, |
| 182 | size_t datalen, | 172 | size_t datalen, |
| 183 | struct key *keyring, | 173 | struct key *keyring, |
| 184 | struct key *instkey); | 174 | struct key *authkey); |
| 185 | extern int key_reject_and_link(struct key *key, | 175 | extern int key_reject_and_link(struct key *key, |
| 186 | unsigned timeout, | 176 | unsigned timeout, |
| 187 | unsigned error, | 177 | unsigned error, |
| 188 | struct key *keyring, | 178 | struct key *keyring, |
| 189 | struct key *instkey); | 179 | struct key *authkey); |
| 190 | extern void complete_request_key(struct key_construction *cons, int error); | 180 | extern void complete_request_key(struct key *authkey, int error); |
| 191 | 181 | ||
| 192 | static inline int key_negate_and_link(struct key *key, | 182 | static inline int key_negate_and_link(struct key *key, |
| 193 | unsigned timeout, | 183 | unsigned timeout, |
| 194 | struct key *keyring, | 184 | struct key *keyring, |
| 195 | struct key *instkey) | 185 | struct key *authkey) |
| 196 | { | 186 | { |
| 197 | return key_reject_and_link(key, timeout, ENOKEY, keyring, instkey); | 187 | return key_reject_and_link(key, timeout, ENOKEY, keyring, authkey); |
| 198 | } | 188 | } |
| 199 | 189 | ||
| 200 | extern int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep); | 190 | extern int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep); |
diff --git a/lib/assoc_array.c b/lib/assoc_array.c index c6659cb37033..59875eb278ea 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c | |||
| @@ -768,9 +768,11 @@ all_leaves_cluster_together: | |||
| 768 | new_s0->index_key[i] = | 768 | new_s0->index_key[i] = |
| 769 | ops->get_key_chunk(index_key, i * ASSOC_ARRAY_KEY_CHUNK_SIZE); | 769 | ops->get_key_chunk(index_key, i * ASSOC_ARRAY_KEY_CHUNK_SIZE); |
| 770 | 770 | ||
| 771 | blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK); | 771 | if (level & ASSOC_ARRAY_KEY_CHUNK_MASK) { |
| 772 | pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank); | 772 | blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK); |
| 773 | new_s0->index_key[keylen - 1] &= ~blank; | 773 | pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank); |
| 774 | new_s0->index_key[keylen - 1] &= ~blank; | ||
| 775 | } | ||
| 774 | 776 | ||
| 775 | /* This now reduces to a node splitting exercise for which we'll need | 777 | /* This now reduces to a node splitting exercise for which we'll need |
| 776 | * to regenerate the disparity table. | 778 | * to regenerate the disparity table. |
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/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..3f56a312dd35 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 = |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 87ea2f54dedc..afc304e8b61e 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 */ |
