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; |