diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/keys/key.c | 56 | ||||
-rw-r--r-- | security/keys/keyring.c | 64 | ||||
-rw-r--r-- | security/keys/user_defined.c | 33 |
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 | */ | ||
895 | struct 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 | */ |
944 | void key_revoke(struct key *key) | 894 | void 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 | */ |
49 | static int keyring_instantiate(struct key *keyring, | 49 | static int keyring_instantiate(struct key *keyring, |
50 | const void *data, size_t datalen); | 50 | const void *data, size_t datalen); |
51 | static int keyring_duplicate(struct key *keyring, const struct key *source); | ||
52 | static int keyring_match(const struct key *keyring, const void *criterion); | 51 | static int keyring_match(const struct key *keyring, const void *criterion); |
53 | static void keyring_destroy(struct key *keyring); | 52 | static void keyring_destroy(struct key *keyring); |
54 | static void keyring_describe(const struct key *keyring, struct seq_file *m); | 53 | static 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 | */ | ||
125 | static 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 | */ |
187 | static int keyring_match(const struct key *keyring, const void *description) | 123 | static 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 @@ | |||
26 | struct key_type key_type_user = { | 26 | struct 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 | |||
72 | EXPORT_SYMBOL_GPL(user_instantiate); | 70 | EXPORT_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 | */ | ||
80 | int 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 | |||
103 | EXPORT_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 | */ |
109 | static void user_update_rcu_disposal(struct rcu_head *rcu) | 76 | static void user_update_rcu_disposal(struct rcu_head *rcu) |