af_alg.c (01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba) af_alg.c (c840ac6af3f8713a71b4d2363419145760bd6044)
1/*
2 * af_alg: User-space algorithm interface
3 *
4 * This file provides the user-space API for algorithms.
5 *
6 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it

--- 111 unchanged lines hidden (view full) ---

120int af_alg_release(struct socket *sock)
121{
122 if (sock->sk)
123 sock_put(sock->sk);
124 return 0;
125}
126EXPORT_SYMBOL_GPL(af_alg_release);
127
1/*
2 * af_alg: User-space algorithm interface
3 *
4 * This file provides the user-space API for algorithms.
5 *
6 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it

--- 111 unchanged lines hidden (view full) ---

120int af_alg_release(struct socket *sock)
121{
122 if (sock->sk)
123 sock_put(sock->sk);
124 return 0;
125}
126EXPORT_SYMBOL_GPL(af_alg_release);
127
128void af_alg_release_parent(struct sock *sk)
129{
130 struct alg_sock *ask = alg_sk(sk);
131 bool last;
132
133 sk = ask->parent;
134 ask = alg_sk(sk);
135
136 lock_sock(sk);
137 last = !--ask->refcnt;
138 release_sock(sk);
139
140 if (last)
141 sock_put(sk);
142}
143EXPORT_SYMBOL_GPL(af_alg_release_parent);
144
128static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
129{
130 const u32 forbidden = CRYPTO_ALG_INTERNAL;
131 struct sock *sk = sock->sk;
132 struct alg_sock *ask = alg_sk(sk);
133 struct sockaddr_alg *sa = (void *)uaddr;
134 const struct af_alg_type *type;
135 void *private;
145static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
146{
147 const u32 forbidden = CRYPTO_ALG_INTERNAL;
148 struct sock *sk = sock->sk;
149 struct alg_sock *ask = alg_sk(sk);
150 struct sockaddr_alg *sa = (void *)uaddr;
151 const struct af_alg_type *type;
152 void *private;
153 int err;
136
137 if (sock->state == SS_CONNECTED)
138 return -EINVAL;
139
140 if (addr_len != sizeof(*sa))
141 return -EINVAL;
142
143 sa->salg_type[sizeof(sa->salg_type) - 1] = 0;

--- 11 unchanged lines hidden (view full) ---

155 private = type->bind(sa->salg_name,
156 sa->salg_feat & ~forbidden,
157 sa->salg_mask & ~forbidden);
158 if (IS_ERR(private)) {
159 module_put(type->owner);
160 return PTR_ERR(private);
161 }
162
154
155 if (sock->state == SS_CONNECTED)
156 return -EINVAL;
157
158 if (addr_len != sizeof(*sa))
159 return -EINVAL;
160
161 sa->salg_type[sizeof(sa->salg_type) - 1] = 0;

--- 11 unchanged lines hidden (view full) ---

173 private = type->bind(sa->salg_name,
174 sa->salg_feat & ~forbidden,
175 sa->salg_mask & ~forbidden);
176 if (IS_ERR(private)) {
177 module_put(type->owner);
178 return PTR_ERR(private);
179 }
180
181 err = -EBUSY;
163 lock_sock(sk);
182 lock_sock(sk);
183 if (ask->refcnt)
184 goto unlock;
164
165 swap(ask->type, type);
166 swap(ask->private, private);
167
185
186 swap(ask->type, type);
187 swap(ask->private, private);
188
189 err = 0;
190
191unlock:
168 release_sock(sk);
169
170 alg_do_release(type, private);
171
192 release_sock(sk);
193
194 alg_do_release(type, private);
195
172 return 0;
196 return err;
173}
174
175static int alg_setkey(struct sock *sk, char __user *ukey,
176 unsigned int keylen)
177{
178 struct alg_sock *ask = alg_sk(sk);
179 const struct af_alg_type *type = ask->type;
180 u8 *key;

--- 16 unchanged lines hidden (view full) ---

197}
198
199static int alg_setsockopt(struct socket *sock, int level, int optname,
200 char __user *optval, unsigned int optlen)
201{
202 struct sock *sk = sock->sk;
203 struct alg_sock *ask = alg_sk(sk);
204 const struct af_alg_type *type;
197}
198
199static int alg_setkey(struct sock *sk, char __user *ukey,
200 unsigned int keylen)
201{
202 struct alg_sock *ask = alg_sk(sk);
203 const struct af_alg_type *type = ask->type;
204 u8 *key;

--- 16 unchanged lines hidden (view full) ---

221}
222
223static int alg_setsockopt(struct socket *sock, int level, int optname,
224 char __user *optval, unsigned int optlen)
225{
226 struct sock *sk = sock->sk;
227 struct alg_sock *ask = alg_sk(sk);
228 const struct af_alg_type *type;
205 int err = -ENOPROTOOPT;
229 int err = -EBUSY;
206
207 lock_sock(sk);
230
231 lock_sock(sk);
232 if (ask->refcnt)
233 goto unlock;
234
208 type = ask->type;
209
235 type = ask->type;
236
237 err = -ENOPROTOOPT;
210 if (level != SOL_ALG || !type)
211 goto unlock;
212
213 switch (optname) {
214 case ALG_SET_KEY:
215 if (sock->state == SS_CONNECTED)
216 goto unlock;
217 if (!type->setkey)

--- 41 unchanged lines hidden (view full) ---

259 err = type->accept(ask->private, sk2);
260 if (err) {
261 sk_free(sk2);
262 goto unlock;
263 }
264
265 sk2->sk_family = PF_ALG;
266
238 if (level != SOL_ALG || !type)
239 goto unlock;
240
241 switch (optname) {
242 case ALG_SET_KEY:
243 if (sock->state == SS_CONNECTED)
244 goto unlock;
245 if (!type->setkey)

--- 41 unchanged lines hidden (view full) ---

287 err = type->accept(ask->private, sk2);
288 if (err) {
289 sk_free(sk2);
290 goto unlock;
291 }
292
293 sk2->sk_family = PF_ALG;
294
267 sock_hold(sk);
295 if (!ask->refcnt++)
296 sock_hold(sk);
268 alg_sk(sk2)->parent = sk;
269 alg_sk(sk2)->type = type;
270
271 newsock->ops = type->ops;
272 newsock->state = SS_CONNECTED;
273
274 err = 0;
275

--- 219 unchanged lines hidden ---
297 alg_sk(sk2)->parent = sk;
298 alg_sk(sk2)->type = type;
299
300 newsock->ops = type->ops;
301 newsock->state = SS_CONNECTED;
302
303 err = 0;
304

--- 219 unchanged lines hidden ---