aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/key.c56
-rw-r--r--security/keys/keyring.c64
-rw-r--r--security/keys/user_defined.c33
3 files changed, 3 insertions, 150 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index 01bcfecb7eae..bb036623d0a8 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -240,9 +240,9 @@ static inline void key_alloc_serial(struct key *key)
240/* 240/*
241 * allocate a key of the specified type 241 * allocate a key of the specified type
242 * - update the user's quota to reflect the existence of the key 242 * - update the user's quota to reflect the existence of the key
243 * - called from a key-type operation with key_types_sem read-locked by either 243 * - called from a key-type operation with key_types_sem read-locked by
244 * key_create_or_update() or by key_duplicate(); this prevents unregistration 244 * key_create_or_update()
245 * of the key type 245 * - this prevents unregistration of the key type
246 * - upon return the key is as yet uninstantiated; the caller needs to either 246 * - upon return the key is as yet uninstantiated; the caller needs to either
247 * instantiate the key or discard it before returning 247 * instantiate the key or discard it before returning
248 */ 248 */
@@ -889,56 +889,6 @@ EXPORT_SYMBOL(key_update);
889 889
890/*****************************************************************************/ 890/*****************************************************************************/
891/* 891/*
892 * duplicate a key, potentially with a revised description
893 * - must be supported by the keytype (keyrings for instance can be duplicated)
894 */
895struct key *key_duplicate(struct key *source, const char *desc)
896{
897 struct key *key;
898 int ret;
899
900 key_check(source);
901
902 if (!desc)
903 desc = source->description;
904
905 down_read(&key_types_sem);
906
907 ret = -EINVAL;
908 if (!source->type->duplicate)
909 goto error;
910
911 /* allocate and instantiate a key */
912 key = key_alloc(source->type, desc, current->fsuid, current->fsgid,
913 source->perm, 0);
914 if (IS_ERR(key))
915 goto error_k;
916
917 down_read(&source->sem);
918 ret = key->type->duplicate(key, source);
919 up_read(&source->sem);
920 if (ret < 0)
921 goto error2;
922
923 atomic_inc(&key->user->nikeys);
924 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
925
926 error_k:
927 up_read(&key_types_sem);
928 out:
929 return key;
930
931 error2:
932 key_put(key);
933 error:
934 up_read(&key_types_sem);
935 key = ERR_PTR(ret);
936 goto out;
937
938} /* end key_duplicate() */
939
940/*****************************************************************************/
941/*
942 * revoke a key 892 * revoke a key
943 */ 893 */
944void key_revoke(struct key *key) 894void key_revoke(struct key *key)
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 4e9fa8be44b8..0acecbd4fa37 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -48,7 +48,6 @@ static inline unsigned keyring_hash(const char *desc)
48 */ 48 */
49static int keyring_instantiate(struct key *keyring, 49static int keyring_instantiate(struct key *keyring,
50 const void *data, size_t datalen); 50 const void *data, size_t datalen);
51static int keyring_duplicate(struct key *keyring, const struct key *source);
52static int keyring_match(const struct key *keyring, const void *criterion); 51static int keyring_match(const struct key *keyring, const void *criterion);
53static void keyring_destroy(struct key *keyring); 52static void keyring_destroy(struct key *keyring);
54static void keyring_describe(const struct key *keyring, struct seq_file *m); 53static void keyring_describe(const struct key *keyring, struct seq_file *m);
@@ -59,7 +58,6 @@ struct key_type key_type_keyring = {
59 .name = "keyring", 58 .name = "keyring",
60 .def_datalen = sizeof(struct keyring_list), 59 .def_datalen = sizeof(struct keyring_list),
61 .instantiate = keyring_instantiate, 60 .instantiate = keyring_instantiate,
62 .duplicate = keyring_duplicate,
63 .match = keyring_match, 61 .match = keyring_match,
64 .destroy = keyring_destroy, 62 .destroy = keyring_destroy,
65 .describe = keyring_describe, 63 .describe = keyring_describe,
@@ -120,68 +118,6 @@ static int keyring_instantiate(struct key *keyring,
120 118
121/*****************************************************************************/ 119/*****************************************************************************/
122/* 120/*
123 * duplicate the list of subscribed keys from a source keyring into this one
124 */
125static int keyring_duplicate(struct key *keyring, const struct key *source)
126{
127 struct keyring_list *sklist, *klist;
128 unsigned max;
129 size_t size;
130 int loop, ret;
131
132 const unsigned limit =
133 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key *);
134
135 ret = 0;
136
137 /* find out how many keys are currently linked */
138 rcu_read_lock();
139 sklist = rcu_dereference(source->payload.subscriptions);
140 max = 0;
141 if (sklist)
142 max = sklist->nkeys;
143 rcu_read_unlock();
144
145 /* allocate a new payload and stuff load with key links */
146 if (max > 0) {
147 BUG_ON(max > limit);
148
149 max = (max + 3) & ~3;
150 if (max > limit)
151 max = limit;
152
153 ret = -ENOMEM;
154 size = sizeof(*klist) + sizeof(struct key *) * max;
155 klist = kmalloc(size, GFP_KERNEL);
156 if (!klist)
157 goto error;
158
159 /* set links */
160 rcu_read_lock();
161 sklist = rcu_dereference(source->payload.subscriptions);
162
163 klist->maxkeys = max;
164 klist->nkeys = sklist->nkeys;
165 memcpy(klist->keys,
166 sklist->keys,
167 sklist->nkeys * sizeof(struct key *));
168
169 for (loop = klist->nkeys - 1; loop >= 0; loop--)
170 atomic_inc(&klist->keys[loop]->usage);
171
172 rcu_read_unlock();
173
174 rcu_assign_pointer(keyring->payload.subscriptions, klist);
175 ret = 0;
176 }
177
178 error:
179 return ret;
180
181} /* end keyring_duplicate() */
182
183/*****************************************************************************/
184/*
185 * match keyrings on their name 121 * match keyrings on their name
186 */ 122 */
187static int keyring_match(const struct key *keyring, const void *description) 123static int keyring_match(const struct key *keyring, const void *description)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index cbda3b2780a1..8e71895b97a7 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -26,7 +26,6 @@
26struct key_type key_type_user = { 26struct key_type key_type_user = {
27 .name = "user", 27 .name = "user",
28 .instantiate = user_instantiate, 28 .instantiate = user_instantiate,
29 .duplicate = user_duplicate,
30 .update = user_update, 29 .update = user_update,
31 .match = user_match, 30 .match = user_match,
32 .destroy = user_destroy, 31 .destroy = user_destroy,
@@ -68,42 +67,10 @@ error:
68 return ret; 67 return ret;
69 68
70} /* end user_instantiate() */ 69} /* end user_instantiate() */
71
72EXPORT_SYMBOL_GPL(user_instantiate); 70EXPORT_SYMBOL_GPL(user_instantiate);
73 71
74/*****************************************************************************/ 72/*****************************************************************************/
75/* 73/*
76 * duplicate a user defined key
77 * - both keys' semaphores are locked against further modification
78 * - the new key cannot yet be accessed
79 */
80int user_duplicate(struct key *key, const struct key *source)
81{
82 struct user_key_payload *upayload, *spayload;
83 int ret;
84
85 /* just copy the payload */
86 ret = -ENOMEM;
87 upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL);
88 if (upayload) {
89 spayload = rcu_dereference(source->payload.data);
90 BUG_ON(source->datalen != spayload->datalen);
91
92 upayload->datalen = key->datalen = spayload->datalen;
93 memcpy(upayload->data, spayload->data, key->datalen);
94
95 key->payload.data = upayload;
96 ret = 0;
97 }
98
99 return ret;
100
101} /* end user_duplicate() */
102
103EXPORT_SYMBOL_GPL(user_duplicate);
104
105/*****************************************************************************/
106/*
107 * dispose of the old data from an updated user defined key 74 * dispose of the old data from an updated user defined key
108 */ 75 */
109static void user_update_rcu_disposal(struct rcu_head *rcu) 76static void user_update_rcu_disposal(struct rcu_head *rcu)