diff options
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r-- | security/keys/keyring.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 92024ed12e0a..5620f084dede 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -25,6 +25,8 @@ | |||
25 | (keyring)->payload.subscriptions, \ | 25 | (keyring)->payload.subscriptions, \ |
26 | rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) | 26 | rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) |
27 | 27 | ||
28 | #define KEY_LINK_FIXQUOTA 1UL | ||
29 | |||
28 | /* | 30 | /* |
29 | * When plumbing the depths of the key tree, this sets a hard limit | 31 | * When plumbing the depths of the key tree, this sets a hard limit |
30 | * set on how deep we're willing to go. | 32 | * set on how deep we're willing to go. |
@@ -699,11 +701,11 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) | |||
699 | * Preallocate memory so that a key can be linked into to a keyring. | 701 | * Preallocate memory so that a key can be linked into to a keyring. |
700 | */ | 702 | */ |
701 | int __key_link_begin(struct key *keyring, const struct key_type *type, | 703 | int __key_link_begin(struct key *keyring, const struct key_type *type, |
702 | const char *description, | 704 | const char *description, unsigned long *_prealloc) |
703 | struct keyring_list **_prealloc) | ||
704 | __acquires(&keyring->sem) | 705 | __acquires(&keyring->sem) |
705 | { | 706 | { |
706 | struct keyring_list *klist, *nklist; | 707 | struct keyring_list *klist, *nklist; |
708 | unsigned long prealloc; | ||
707 | unsigned max; | 709 | unsigned max; |
708 | size_t size; | 710 | size_t size; |
709 | int loop, ret; | 711 | int loop, ret; |
@@ -746,6 +748,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, | |||
746 | 748 | ||
747 | /* note replacement slot */ | 749 | /* note replacement slot */ |
748 | klist->delkey = nklist->delkey = loop; | 750 | klist->delkey = nklist->delkey = loop; |
751 | prealloc = (unsigned long)nklist; | ||
749 | goto done; | 752 | goto done; |
750 | } | 753 | } |
751 | } | 754 | } |
@@ -760,6 +763,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, | |||
760 | if (klist && klist->nkeys < klist->maxkeys) { | 763 | if (klist && klist->nkeys < klist->maxkeys) { |
761 | /* there's sufficient slack space to append directly */ | 764 | /* there's sufficient slack space to append directly */ |
762 | nklist = NULL; | 765 | nklist = NULL; |
766 | prealloc = KEY_LINK_FIXQUOTA; | ||
763 | } else { | 767 | } else { |
764 | /* grow the key list */ | 768 | /* grow the key list */ |
765 | max = 4; | 769 | max = 4; |
@@ -794,8 +798,9 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, | |||
794 | nklist->keys[nklist->delkey] = NULL; | 798 | nklist->keys[nklist->delkey] = NULL; |
795 | } | 799 | } |
796 | 800 | ||
801 | prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA; | ||
797 | done: | 802 | done: |
798 | *_prealloc = nklist; | 803 | *_prealloc = prealloc; |
799 | kleave(" = 0"); | 804 | kleave(" = 0"); |
800 | return 0; | 805 | return 0; |
801 | 806 | ||
@@ -836,12 +841,12 @@ int __key_link_check_live_key(struct key *keyring, struct key *key) | |||
836 | * combination. | 841 | * combination. |
837 | */ | 842 | */ |
838 | void __key_link(struct key *keyring, struct key *key, | 843 | void __key_link(struct key *keyring, struct key *key, |
839 | struct keyring_list **_prealloc) | 844 | unsigned long *_prealloc) |
840 | { | 845 | { |
841 | struct keyring_list *klist, *nklist; | 846 | struct keyring_list *klist, *nklist; |
842 | 847 | ||
843 | nklist = *_prealloc; | 848 | nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA); |
844 | *_prealloc = NULL; | 849 | *_prealloc = 0; |
845 | 850 | ||
846 | kenter("%d,%d,%p", keyring->serial, key->serial, nklist); | 851 | kenter("%d,%d,%p", keyring->serial, key->serial, nklist); |
847 | 852 | ||
@@ -881,20 +886,22 @@ void __key_link(struct key *keyring, struct key *key, | |||
881 | * Must be called with __key_link_begin() having being called. | 886 | * Must be called with __key_link_begin() having being called. |
882 | */ | 887 | */ |
883 | void __key_link_end(struct key *keyring, struct key_type *type, | 888 | void __key_link_end(struct key *keyring, struct key_type *type, |
884 | struct keyring_list *prealloc) | 889 | unsigned long prealloc) |
885 | __releases(&keyring->sem) | 890 | __releases(&keyring->sem) |
886 | { | 891 | { |
887 | BUG_ON(type == NULL); | 892 | BUG_ON(type == NULL); |
888 | BUG_ON(type->name == NULL); | 893 | BUG_ON(type->name == NULL); |
889 | kenter("%d,%s,%p", keyring->serial, type->name, prealloc); | 894 | kenter("%d,%s,%lx", keyring->serial, type->name, prealloc); |
890 | 895 | ||
891 | if (type == &key_type_keyring) | 896 | if (type == &key_type_keyring) |
892 | up_write(&keyring_serialise_link_sem); | 897 | up_write(&keyring_serialise_link_sem); |
893 | 898 | ||
894 | if (prealloc) { | 899 | if (prealloc) { |
895 | kfree(prealloc); | 900 | if (prealloc & KEY_LINK_FIXQUOTA) |
896 | key_payload_reserve(keyring, | 901 | key_payload_reserve(keyring, |
897 | keyring->datalen - KEYQUOTA_LINK_BYTES); | 902 | keyring->datalen - |
903 | KEYQUOTA_LINK_BYTES); | ||
904 | kfree((struct keyring_list *)(prealloc & ~KEY_LINK_FIXQUOTA)); | ||
898 | } | 905 | } |
899 | up_write(&keyring->sem); | 906 | up_write(&keyring->sem); |
900 | } | 907 | } |
@@ -921,7 +928,7 @@ void __key_link_end(struct key *keyring, struct key_type *type, | |||
921 | */ | 928 | */ |
922 | int key_link(struct key *keyring, struct key *key) | 929 | int key_link(struct key *keyring, struct key *key) |
923 | { | 930 | { |
924 | struct keyring_list *prealloc; | 931 | unsigned long prealloc; |
925 | int ret; | 932 | int ret; |
926 | 933 | ||
927 | key_check(keyring); | 934 | key_check(keyring); |