diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-14 16:39:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-14 16:39:34 -0400 |
| commit | d25282d1c9b9bc4cda7f9d3c0205108e99aa7a9d (patch) | |
| tree | f414482d768b015a609924293b779b4ad0b8f764 /security | |
| parent | b6eea87fc6850d3531a64a27d2323a4498cd4e43 (diff) | |
| parent | dbadc17683e6c673a69b236c0f041b931cc55c42 (diff) | |
Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module signing support from Rusty Russell:
"module signing is the highlight, but it's an all-over David Howells frenzy..."
Hmm "Magrathea: Glacier signing key". Somebody has been reading too much HHGTTG.
* 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: (37 commits)
X.509: Fix indefinite length element skip error handling
X.509: Convert some printk calls to pr_devel
asymmetric keys: fix printk format warning
MODSIGN: Fix 32-bit overflow in X.509 certificate validity date checking
MODSIGN: Make mrproper should remove generated files.
MODSIGN: Use utf8 strings in signer's name in autogenerated X.509 certs
MODSIGN: Use the same digest for the autogen key sig as for the module sig
MODSIGN: Sign modules during the build process
MODSIGN: Provide a script for generating a key ID from an X.509 cert
MODSIGN: Implement module signature checking
MODSIGN: Provide module signing public keys to the kernel
MODSIGN: Automatically generate module signing keys if missing
MODSIGN: Provide Kconfig options
MODSIGN: Provide gitignore and make clean rules for extra files
MODSIGN: Add FIPS policy
module: signature checking hook
X.509: Add a crypto key parser for binary (DER) X.509 certificates
MPILIB: Provide a function to read raw data into an MPI
X.509: Add an ASN.1 decoder
X.509: Add simple ASN.1 grammar compiler
...
Diffstat (limited to 'security')
| -rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 16 | ||||
| -rw-r--r-- | security/keys/key.c | 114 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 18 | ||||
| -rw-r--r-- | security/keys/keyring.c | 6 | ||||
| -rw-r--r-- | security/keys/request_key_auth.c | 8 | ||||
| -rw-r--r-- | security/keys/trusted.c | 16 | ||||
| -rw-r--r-- | security/keys/user_defined.c | 14 |
7 files changed, 129 insertions, 63 deletions
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 2d1bb8af7696..9e1e005c7596 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
| @@ -773,8 +773,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload, | |||
| 773 | * | 773 | * |
| 774 | * On success, return 0. Otherwise return errno. | 774 | * On success, return 0. Otherwise return errno. |
| 775 | */ | 775 | */ |
| 776 | static int encrypted_instantiate(struct key *key, const void *data, | 776 | static int encrypted_instantiate(struct key *key, |
| 777 | size_t datalen) | 777 | struct key_preparsed_payload *prep) |
| 778 | { | 778 | { |
| 779 | struct encrypted_key_payload *epayload = NULL; | 779 | struct encrypted_key_payload *epayload = NULL; |
| 780 | char *datablob = NULL; | 780 | char *datablob = NULL; |
| @@ -782,16 +782,17 @@ static int encrypted_instantiate(struct key *key, const void *data, | |||
| 782 | char *master_desc = NULL; | 782 | char *master_desc = NULL; |
| 783 | char *decrypted_datalen = NULL; | 783 | char *decrypted_datalen = NULL; |
| 784 | char *hex_encoded_iv = NULL; | 784 | char *hex_encoded_iv = NULL; |
| 785 | size_t datalen = prep->datalen; | ||
| 785 | int ret; | 786 | int ret; |
| 786 | 787 | ||
| 787 | if (datalen <= 0 || datalen > 32767 || !data) | 788 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 788 | return -EINVAL; | 789 | return -EINVAL; |
| 789 | 790 | ||
| 790 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 791 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
| 791 | if (!datablob) | 792 | if (!datablob) |
| 792 | return -ENOMEM; | 793 | return -ENOMEM; |
| 793 | datablob[datalen] = 0; | 794 | datablob[datalen] = 0; |
| 794 | memcpy(datablob, data, datalen); | 795 | memcpy(datablob, prep->data, datalen); |
| 795 | ret = datablob_parse(datablob, &format, &master_desc, | 796 | ret = datablob_parse(datablob, &format, &master_desc, |
| 796 | &decrypted_datalen, &hex_encoded_iv); | 797 | &decrypted_datalen, &hex_encoded_iv); |
| 797 | if (ret < 0) | 798 | if (ret < 0) |
| @@ -834,16 +835,17 @@ static void encrypted_rcu_free(struct rcu_head *rcu) | |||
| 834 | * | 835 | * |
| 835 | * On success, return 0. Otherwise return errno. | 836 | * On success, return 0. Otherwise return errno. |
| 836 | */ | 837 | */ |
| 837 | static int encrypted_update(struct key *key, const void *data, size_t datalen) | 838 | static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) |
| 838 | { | 839 | { |
| 839 | struct encrypted_key_payload *epayload = key->payload.data; | 840 | struct encrypted_key_payload *epayload = key->payload.data; |
| 840 | struct encrypted_key_payload *new_epayload; | 841 | struct encrypted_key_payload *new_epayload; |
| 841 | char *buf; | 842 | char *buf; |
| 842 | char *new_master_desc = NULL; | 843 | char *new_master_desc = NULL; |
| 843 | const char *format = NULL; | 844 | const char *format = NULL; |
| 845 | size_t datalen = prep->datalen; | ||
| 844 | int ret = 0; | 846 | int ret = 0; |
| 845 | 847 | ||
| 846 | if (datalen <= 0 || datalen > 32767 || !data) | 848 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 847 | return -EINVAL; | 849 | return -EINVAL; |
| 848 | 850 | ||
| 849 | buf = kmalloc(datalen + 1, GFP_KERNEL); | 851 | buf = kmalloc(datalen + 1, GFP_KERNEL); |
| @@ -851,7 +853,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) | |||
| 851 | return -ENOMEM; | 853 | return -ENOMEM; |
| 852 | 854 | ||
| 853 | buf[datalen] = 0; | 855 | buf[datalen] = 0; |
| 854 | memcpy(buf, data, datalen); | 856 | memcpy(buf, prep->data, datalen); |
| 855 | ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); | 857 | ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); |
| 856 | if (ret < 0) | 858 | if (ret < 0) |
| 857 | goto out; | 859 | goto out; |
diff --git a/security/keys/key.c b/security/keys/key.c index a30e92734905..a15c9da8f971 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
| @@ -405,8 +405,7 @@ EXPORT_SYMBOL(key_payload_reserve); | |||
| 405 | * key_construction_mutex. | 405 | * key_construction_mutex. |
| 406 | */ | 406 | */ |
| 407 | static int __key_instantiate_and_link(struct key *key, | 407 | static int __key_instantiate_and_link(struct key *key, |
| 408 | const void *data, | 408 | struct key_preparsed_payload *prep, |
| 409 | size_t datalen, | ||
| 410 | struct key *keyring, | 409 | struct key *keyring, |
| 411 | struct key *authkey, | 410 | struct key *authkey, |
| 412 | unsigned long *_prealloc) | 411 | unsigned long *_prealloc) |
| @@ -424,7 +423,7 @@ static int __key_instantiate_and_link(struct key *key, | |||
| 424 | /* can't instantiate twice */ | 423 | /* can't instantiate twice */ |
| 425 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { | 424 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { |
| 426 | /* instantiate the key */ | 425 | /* instantiate the key */ |
| 427 | ret = key->type->instantiate(key, data, datalen); | 426 | ret = key->type->instantiate(key, prep); |
| 428 | 427 | ||
| 429 | if (ret == 0) { | 428 | if (ret == 0) { |
| 430 | /* mark the key as being instantiated */ | 429 | /* mark the key as being instantiated */ |
| @@ -475,22 +474,37 @@ int key_instantiate_and_link(struct key *key, | |||
| 475 | struct key *keyring, | 474 | struct key *keyring, |
| 476 | struct key *authkey) | 475 | struct key *authkey) |
| 477 | { | 476 | { |
| 477 | struct key_preparsed_payload prep; | ||
| 478 | unsigned long prealloc; | 478 | unsigned long prealloc; |
| 479 | int ret; | 479 | int ret; |
| 480 | 480 | ||
| 481 | memset(&prep, 0, sizeof(prep)); | ||
| 482 | prep.data = data; | ||
| 483 | prep.datalen = datalen; | ||
| 484 | prep.quotalen = key->type->def_datalen; | ||
| 485 | if (key->type->preparse) { | ||
| 486 | ret = key->type->preparse(&prep); | ||
| 487 | if (ret < 0) | ||
| 488 | goto error; | ||
| 489 | } | ||
| 490 | |||
| 481 | if (keyring) { | 491 | if (keyring) { |
| 482 | ret = __key_link_begin(keyring, key->type, key->description, | 492 | ret = __key_link_begin(keyring, key->type, key->description, |
| 483 | &prealloc); | 493 | &prealloc); |
| 484 | if (ret < 0) | 494 | if (ret < 0) |
| 485 | return ret; | 495 | goto error_free_preparse; |
| 486 | } | 496 | } |
| 487 | 497 | ||
| 488 | ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey, | 498 | ret = __key_instantiate_and_link(key, &prep, keyring, authkey, |
| 489 | &prealloc); | 499 | &prealloc); |
| 490 | 500 | ||
| 491 | if (keyring) | 501 | if (keyring) |
| 492 | __key_link_end(keyring, key->type, prealloc); | 502 | __key_link_end(keyring, key->type, prealloc); |
| 493 | 503 | ||
| 504 | error_free_preparse: | ||
| 505 | if (key->type->preparse) | ||
| 506 | key->type->free_preparse(&prep); | ||
| 507 | error: | ||
| 494 | return ret; | 508 | return ret; |
| 495 | } | 509 | } |
| 496 | 510 | ||
| @@ -699,7 +713,7 @@ void key_type_put(struct key_type *ktype) | |||
| 699 | * if we get an error. | 713 | * if we get an error. |
| 700 | */ | 714 | */ |
| 701 | static inline key_ref_t __key_update(key_ref_t key_ref, | 715 | static inline key_ref_t __key_update(key_ref_t key_ref, |
| 702 | const void *payload, size_t plen) | 716 | struct key_preparsed_payload *prep) |
| 703 | { | 717 | { |
| 704 | struct key *key = key_ref_to_ptr(key_ref); | 718 | struct key *key = key_ref_to_ptr(key_ref); |
| 705 | int ret; | 719 | int ret; |
| @@ -715,7 +729,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref, | |||
| 715 | 729 | ||
| 716 | down_write(&key->sem); | 730 | down_write(&key->sem); |
| 717 | 731 | ||
| 718 | ret = key->type->update(key, payload, plen); | 732 | ret = key->type->update(key, prep); |
| 719 | if (ret == 0) | 733 | if (ret == 0) |
| 720 | /* updating a negative key instantiates it */ | 734 | /* updating a negative key instantiates it */ |
| 721 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); | 735 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); |
| @@ -767,6 +781,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
| 767 | unsigned long flags) | 781 | unsigned long flags) |
| 768 | { | 782 | { |
| 769 | unsigned long prealloc; | 783 | unsigned long prealloc; |
| 784 | struct key_preparsed_payload prep; | ||
| 770 | const struct cred *cred = current_cred(); | 785 | const struct cred *cred = current_cred(); |
| 771 | struct key_type *ktype; | 786 | struct key_type *ktype; |
| 772 | struct key *keyring, *key = NULL; | 787 | struct key *keyring, *key = NULL; |
| @@ -782,8 +797,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
| 782 | } | 797 | } |
| 783 | 798 | ||
| 784 | key_ref = ERR_PTR(-EINVAL); | 799 | key_ref = ERR_PTR(-EINVAL); |
| 785 | if (!ktype->match || !ktype->instantiate) | 800 | if (!ktype->match || !ktype->instantiate || |
| 786 | goto error_2; | 801 | (!description && !ktype->preparse)) |
| 802 | goto error_put_type; | ||
| 787 | 803 | ||
| 788 | keyring = key_ref_to_ptr(keyring_ref); | 804 | keyring = key_ref_to_ptr(keyring_ref); |
| 789 | 805 | ||
| @@ -791,18 +807,37 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
| 791 | 807 | ||
| 792 | key_ref = ERR_PTR(-ENOTDIR); | 808 | key_ref = ERR_PTR(-ENOTDIR); |
| 793 | if (keyring->type != &key_type_keyring) | 809 | if (keyring->type != &key_type_keyring) |
| 794 | goto error_2; | 810 | goto error_put_type; |
| 811 | |||
| 812 | memset(&prep, 0, sizeof(prep)); | ||
| 813 | prep.data = payload; | ||
| 814 | prep.datalen = plen; | ||
| 815 | prep.quotalen = ktype->def_datalen; | ||
| 816 | if (ktype->preparse) { | ||
| 817 | ret = ktype->preparse(&prep); | ||
| 818 | if (ret < 0) { | ||
| 819 | key_ref = ERR_PTR(ret); | ||
| 820 | goto error_put_type; | ||
| 821 | } | ||
| 822 | if (!description) | ||
| 823 | description = prep.description; | ||
| 824 | key_ref = ERR_PTR(-EINVAL); | ||
| 825 | if (!description) | ||
| 826 | goto error_free_prep; | ||
| 827 | } | ||
| 795 | 828 | ||
| 796 | ret = __key_link_begin(keyring, ktype, description, &prealloc); | 829 | ret = __key_link_begin(keyring, ktype, description, &prealloc); |
| 797 | if (ret < 0) | 830 | if (ret < 0) { |
| 798 | goto error_2; | 831 | key_ref = ERR_PTR(ret); |
| 832 | goto error_free_prep; | ||
| 833 | } | ||
| 799 | 834 | ||
| 800 | /* if we're going to allocate a new key, we're going to have | 835 | /* if we're going to allocate a new key, we're going to have |
| 801 | * to modify the keyring */ | 836 | * to modify the keyring */ |
| 802 | ret = key_permission(keyring_ref, KEY_WRITE); | 837 | ret = key_permission(keyring_ref, KEY_WRITE); |
| 803 | if (ret < 0) { | 838 | if (ret < 0) { |
| 804 | key_ref = ERR_PTR(ret); | 839 | key_ref = ERR_PTR(ret); |
| 805 | goto error_3; | 840 | goto error_link_end; |
| 806 | } | 841 | } |
| 807 | 842 | ||
| 808 | /* if it's possible to update this type of key, search for an existing | 843 | /* if it's possible to update this type of key, search for an existing |
| @@ -833,25 +868,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
| 833 | perm, flags); | 868 | perm, flags); |
| 834 | if (IS_ERR(key)) { | 869 | if (IS_ERR(key)) { |
| 835 | key_ref = ERR_CAST(key); | 870 | key_ref = ERR_CAST(key); |
| 836 | goto error_3; | 871 | goto error_link_end; |
| 837 | } | 872 | } |
| 838 | 873 | ||
| 839 | /* instantiate it and link it into the target keyring */ | 874 | /* instantiate it and link it into the target keyring */ |
| 840 | ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL, | 875 | ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc); |
| 841 | &prealloc); | ||
| 842 | if (ret < 0) { | 876 | if (ret < 0) { |
| 843 | key_put(key); | 877 | key_put(key); |
| 844 | key_ref = ERR_PTR(ret); | 878 | key_ref = ERR_PTR(ret); |
| 845 | goto error_3; | 879 | goto error_link_end; |
| 846 | } | 880 | } |
| 847 | 881 | ||
| 848 | key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); | 882 | key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); |
| 849 | 883 | ||
| 850 | error_3: | 884 | error_link_end: |
| 851 | __key_link_end(keyring, ktype, prealloc); | 885 | __key_link_end(keyring, ktype, prealloc); |
| 852 | error_2: | 886 | error_free_prep: |
| 887 | if (ktype->preparse) | ||
| 888 | ktype->free_preparse(&prep); | ||
| 889 | error_put_type: | ||
| 853 | key_type_put(ktype); | 890 | key_type_put(ktype); |
| 854 | error: | 891 | error: |
| 855 | return key_ref; | 892 | return key_ref; |
| 856 | 893 | ||
| 857 | found_matching_key: | 894 | found_matching_key: |
| @@ -859,10 +896,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
| 859 | * - we can drop the locks first as we have the key pinned | 896 | * - we can drop the locks first as we have the key pinned |
| 860 | */ | 897 | */ |
| 861 | __key_link_end(keyring, ktype, prealloc); | 898 | __key_link_end(keyring, ktype, prealloc); |
| 862 | key_type_put(ktype); | ||
| 863 | 899 | ||
| 864 | key_ref = __key_update(key_ref, payload, plen); | 900 | key_ref = __key_update(key_ref, &prep); |
| 865 | goto error; | 901 | goto error_free_prep; |
| 866 | } | 902 | } |
| 867 | EXPORT_SYMBOL(key_create_or_update); | 903 | EXPORT_SYMBOL(key_create_or_update); |
| 868 | 904 | ||
| @@ -881,6 +917,7 @@ EXPORT_SYMBOL(key_create_or_update); | |||
| 881 | */ | 917 | */ |
| 882 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) | 918 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) |
| 883 | { | 919 | { |
| 920 | struct key_preparsed_payload prep; | ||
| 884 | struct key *key = key_ref_to_ptr(key_ref); | 921 | struct key *key = key_ref_to_ptr(key_ref); |
| 885 | int ret; | 922 | int ret; |
| 886 | 923 | ||
| @@ -893,18 +930,31 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) | |||
| 893 | 930 | ||
| 894 | /* attempt to update it if supported */ | 931 | /* attempt to update it if supported */ |
| 895 | ret = -EOPNOTSUPP; | 932 | ret = -EOPNOTSUPP; |
| 896 | if (key->type->update) { | 933 | if (!key->type->update) |
| 897 | down_write(&key->sem); | 934 | goto error; |
| 898 | |||
| 899 | ret = key->type->update(key, payload, plen); | ||
| 900 | if (ret == 0) | ||
| 901 | /* updating a negative key instantiates it */ | ||
| 902 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); | ||
| 903 | 935 | ||
| 904 | up_write(&key->sem); | 936 | memset(&prep, 0, sizeof(prep)); |
| 937 | prep.data = payload; | ||
| 938 | prep.datalen = plen; | ||
| 939 | prep.quotalen = key->type->def_datalen; | ||
| 940 | if (key->type->preparse) { | ||
| 941 | ret = key->type->preparse(&prep); | ||
| 942 | if (ret < 0) | ||
| 943 | goto error; | ||
| 905 | } | 944 | } |
| 906 | 945 | ||
| 907 | error: | 946 | down_write(&key->sem); |
| 947 | |||
| 948 | ret = key->type->update(key, &prep); | ||
| 949 | if (ret == 0) | ||
| 950 | /* updating a negative key instantiates it */ | ||
| 951 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); | ||
| 952 | |||
| 953 | up_write(&key->sem); | ||
| 954 | |||
| 955 | if (key->type->preparse) | ||
| 956 | key->type->free_preparse(&prep); | ||
| 957 | error: | ||
| 908 | return ret; | 958 | return ret; |
| 909 | } | 959 | } |
| 910 | EXPORT_SYMBOL(key_update); | 960 | EXPORT_SYMBOL(key_update); |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 305ecb76519c..5d34b4e827d6 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -46,6 +46,9 @@ static int key_get_type_from_user(char *type, | |||
| 46 | * Extract the description of a new key from userspace and either add it as a | 46 | * Extract the description of a new key from userspace and either add it as a |
| 47 | * new key to the specified keyring or update a matching key in that keyring. | 47 | * new key to the specified keyring or update a matching key in that keyring. |
| 48 | * | 48 | * |
| 49 | * If the description is NULL or an empty string, the key type is asked to | ||
| 50 | * generate one from the payload. | ||
| 51 | * | ||
| 49 | * The keyring must be writable so that we can attach the key to it. | 52 | * The keyring must be writable so that we can attach the key to it. |
| 50 | * | 53 | * |
| 51 | * If successful, the new key's serial number is returned, otherwise an error | 54 | * If successful, the new key's serial number is returned, otherwise an error |
| @@ -72,10 +75,17 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, | |||
| 72 | if (ret < 0) | 75 | if (ret < 0) |
| 73 | goto error; | 76 | goto error; |
| 74 | 77 | ||
| 75 | description = strndup_user(_description, PAGE_SIZE); | 78 | description = NULL; |
| 76 | if (IS_ERR(description)) { | 79 | if (_description) { |
| 77 | ret = PTR_ERR(description); | 80 | description = strndup_user(_description, PAGE_SIZE); |
| 78 | goto error; | 81 | if (IS_ERR(description)) { |
| 82 | ret = PTR_ERR(description); | ||
| 83 | goto error; | ||
| 84 | } | ||
| 85 | if (!*description) { | ||
| 86 | kfree(description); | ||
| 87 | description = NULL; | ||
| 88 | } | ||
| 79 | } | 89 | } |
| 80 | 90 | ||
| 81 | /* pull the payload in if one was supplied */ | 91 | /* pull the payload in if one was supplied */ |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index a5f5c4b6edc5..6e42df15a24c 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
| @@ -66,7 +66,7 @@ static inline unsigned keyring_hash(const char *desc) | |||
| 66 | * operations. | 66 | * operations. |
| 67 | */ | 67 | */ |
| 68 | static int keyring_instantiate(struct key *keyring, | 68 | static int keyring_instantiate(struct key *keyring, |
| 69 | const void *data, size_t datalen); | 69 | struct key_preparsed_payload *prep); |
| 70 | static int keyring_match(const struct key *keyring, const void *criterion); | 70 | static int keyring_match(const struct key *keyring, const void *criterion); |
| 71 | static void keyring_revoke(struct key *keyring); | 71 | static void keyring_revoke(struct key *keyring); |
| 72 | static void keyring_destroy(struct key *keyring); | 72 | static void keyring_destroy(struct key *keyring); |
| @@ -121,12 +121,12 @@ static void keyring_publish_name(struct key *keyring) | |||
| 121 | * Returns 0 on success, -EINVAL if given any data. | 121 | * Returns 0 on success, -EINVAL if given any data. |
| 122 | */ | 122 | */ |
| 123 | static int keyring_instantiate(struct key *keyring, | 123 | static int keyring_instantiate(struct key *keyring, |
| 124 | const void *data, size_t datalen) | 124 | struct key_preparsed_payload *prep) |
| 125 | { | 125 | { |
| 126 | int ret; | 126 | int ret; |
| 127 | 127 | ||
| 128 | ret = -EINVAL; | 128 | ret = -EINVAL; |
| 129 | if (datalen == 0) { | 129 | if (prep->datalen == 0) { |
| 130 | /* make the keyring available by name if it has one */ | 130 | /* make the keyring available by name if it has one */ |
| 131 | keyring_publish_name(keyring); | 131 | keyring_publish_name(keyring); |
| 132 | ret = 0; | 132 | ret = 0; |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 60d4e3f5e4bb..85730d5a5a59 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
| @@ -19,7 +19,8 @@ | |||
| 19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
| 20 | #include "internal.h" | 20 | #include "internal.h" |
| 21 | 21 | ||
| 22 | static int request_key_auth_instantiate(struct key *, const void *, size_t); | 22 | static int request_key_auth_instantiate(struct key *, |
| 23 | struct key_preparsed_payload *); | ||
| 23 | static void request_key_auth_describe(const struct key *, struct seq_file *); | 24 | static void request_key_auth_describe(const struct key *, struct seq_file *); |
| 24 | static void request_key_auth_revoke(struct key *); | 25 | static void request_key_auth_revoke(struct key *); |
| 25 | static void request_key_auth_destroy(struct key *); | 26 | static void request_key_auth_destroy(struct key *); |
| @@ -42,10 +43,9 @@ struct key_type key_type_request_key_auth = { | |||
| 42 | * Instantiate a request-key authorisation key. | 43 | * Instantiate a request-key authorisation key. |
| 43 | */ | 44 | */ |
| 44 | static int request_key_auth_instantiate(struct key *key, | 45 | static int request_key_auth_instantiate(struct key *key, |
| 45 | const void *data, | 46 | struct key_preparsed_payload *prep) |
| 46 | size_t datalen) | ||
| 47 | { | 47 | { |
| 48 | key->payload.data = (struct request_key_auth *) data; | 48 | key->payload.data = (struct request_key_auth *)prep->data; |
| 49 | return 0; | 49 | return 0; |
| 50 | } | 50 | } |
| 51 | 51 | ||
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 3f163d0489ad..e13fcf7636f7 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
| @@ -895,23 +895,24 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key) | |||
| 895 | * | 895 | * |
| 896 | * On success, return 0. Otherwise return errno. | 896 | * On success, return 0. Otherwise return errno. |
| 897 | */ | 897 | */ |
| 898 | static int trusted_instantiate(struct key *key, const void *data, | 898 | static int trusted_instantiate(struct key *key, |
| 899 | size_t datalen) | 899 | struct key_preparsed_payload *prep) |
| 900 | { | 900 | { |
| 901 | struct trusted_key_payload *payload = NULL; | 901 | struct trusted_key_payload *payload = NULL; |
| 902 | struct trusted_key_options *options = NULL; | 902 | struct trusted_key_options *options = NULL; |
| 903 | size_t datalen = prep->datalen; | ||
| 903 | char *datablob; | 904 | char *datablob; |
| 904 | int ret = 0; | 905 | int ret = 0; |
| 905 | int key_cmd; | 906 | int key_cmd; |
| 906 | size_t key_len; | 907 | size_t key_len; |
| 907 | 908 | ||
| 908 | if (datalen <= 0 || datalen > 32767 || !data) | 909 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 909 | return -EINVAL; | 910 | return -EINVAL; |
| 910 | 911 | ||
| 911 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 912 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
| 912 | if (!datablob) | 913 | if (!datablob) |
| 913 | return -ENOMEM; | 914 | return -ENOMEM; |
| 914 | memcpy(datablob, data, datalen); | 915 | memcpy(datablob, prep->data, datalen); |
| 915 | datablob[datalen] = '\0'; | 916 | datablob[datalen] = '\0'; |
| 916 | 917 | ||
| 917 | options = trusted_options_alloc(); | 918 | options = trusted_options_alloc(); |
| @@ -981,17 +982,18 @@ static void trusted_rcu_free(struct rcu_head *rcu) | |||
| 981 | /* | 982 | /* |
| 982 | * trusted_update - reseal an existing key with new PCR values | 983 | * trusted_update - reseal an existing key with new PCR values |
| 983 | */ | 984 | */ |
| 984 | static int trusted_update(struct key *key, const void *data, size_t datalen) | 985 | static int trusted_update(struct key *key, struct key_preparsed_payload *prep) |
| 985 | { | 986 | { |
| 986 | struct trusted_key_payload *p = key->payload.data; | 987 | struct trusted_key_payload *p = key->payload.data; |
| 987 | struct trusted_key_payload *new_p; | 988 | struct trusted_key_payload *new_p; |
| 988 | struct trusted_key_options *new_o; | 989 | struct trusted_key_options *new_o; |
| 990 | size_t datalen = prep->datalen; | ||
| 989 | char *datablob; | 991 | char *datablob; |
| 990 | int ret = 0; | 992 | int ret = 0; |
| 991 | 993 | ||
| 992 | if (!p->migratable) | 994 | if (!p->migratable) |
| 993 | return -EPERM; | 995 | return -EPERM; |
| 994 | if (datalen <= 0 || datalen > 32767 || !data) | 996 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 995 | return -EINVAL; | 997 | return -EINVAL; |
| 996 | 998 | ||
| 997 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 999 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
| @@ -1008,7 +1010,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen) | |||
| 1008 | goto out; | 1010 | goto out; |
| 1009 | } | 1011 | } |
| 1010 | 1012 | ||
| 1011 | memcpy(datablob, data, datalen); | 1013 | memcpy(datablob, prep->data, datalen); |
| 1012 | datablob[datalen] = '\0'; | 1014 | datablob[datalen] = '\0'; |
| 1013 | ret = datablob_parse(datablob, new_p, new_o); | 1015 | ret = datablob_parse(datablob, new_p, new_o); |
| 1014 | if (ret != Opt_update) { | 1016 | if (ret != Opt_update) { |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index c7660a25a3e4..55dc88939185 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c | |||
| @@ -58,13 +58,14 @@ EXPORT_SYMBOL_GPL(key_type_logon); | |||
| 58 | /* | 58 | /* |
| 59 | * instantiate a user defined key | 59 | * instantiate a user defined key |
| 60 | */ | 60 | */ |
| 61 | int user_instantiate(struct key *key, const void *data, size_t datalen) | 61 | int user_instantiate(struct key *key, struct key_preparsed_payload *prep) |
| 62 | { | 62 | { |
| 63 | struct user_key_payload *upayload; | 63 | struct user_key_payload *upayload; |
| 64 | size_t datalen = prep->datalen; | ||
| 64 | int ret; | 65 | int ret; |
| 65 | 66 | ||
| 66 | ret = -EINVAL; | 67 | ret = -EINVAL; |
| 67 | if (datalen <= 0 || datalen > 32767 || !data) | 68 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 68 | goto error; | 69 | goto error; |
| 69 | 70 | ||
| 70 | ret = key_payload_reserve(key, datalen); | 71 | ret = key_payload_reserve(key, datalen); |
| @@ -78,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen) | |||
| 78 | 79 | ||
| 79 | /* attach the data */ | 80 | /* attach the data */ |
| 80 | upayload->datalen = datalen; | 81 | upayload->datalen = datalen; |
| 81 | memcpy(upayload->data, data, datalen); | 82 | memcpy(upayload->data, prep->data, datalen); |
| 82 | rcu_assign_keypointer(key, upayload); | 83 | rcu_assign_keypointer(key, upayload); |
| 83 | ret = 0; | 84 | ret = 0; |
| 84 | 85 | ||
| @@ -92,13 +93,14 @@ EXPORT_SYMBOL_GPL(user_instantiate); | |||
| 92 | * update a user defined key | 93 | * update a user defined key |
| 93 | * - the key's semaphore is write-locked | 94 | * - the key's semaphore is write-locked |
| 94 | */ | 95 | */ |
| 95 | int user_update(struct key *key, const void *data, size_t datalen) | 96 | int user_update(struct key *key, struct key_preparsed_payload *prep) |
| 96 | { | 97 | { |
| 97 | struct user_key_payload *upayload, *zap; | 98 | struct user_key_payload *upayload, *zap; |
| 99 | size_t datalen = prep->datalen; | ||
| 98 | int ret; | 100 | int ret; |
| 99 | 101 | ||
| 100 | ret = -EINVAL; | 102 | ret = -EINVAL; |
| 101 | if (datalen <= 0 || datalen > 32767 || !data) | 103 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 102 | goto error; | 104 | goto error; |
| 103 | 105 | ||
| 104 | /* construct a replacement payload */ | 106 | /* construct a replacement payload */ |
| @@ -108,7 +110,7 @@ int user_update(struct key *key, const void *data, size_t datalen) | |||
| 108 | goto error; | 110 | goto error; |
| 109 | 111 | ||
| 110 | upayload->datalen = datalen; | 112 | upayload->datalen = datalen; |
| 111 | memcpy(upayload->data, data, datalen); | 113 | memcpy(upayload->data, prep->data, datalen); |
| 112 | 114 | ||
| 113 | /* check the quota and attach the new data */ | 115 | /* check the quota and attach the new data */ |
| 114 | zap = upayload; | 116 | zap = upayload; |
