diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2016-01-03 23:35:18 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-01-18 05:16:10 -0500 |
commit | 37766586c965d63758ad542325a96d5384f4a8c9 (patch) | |
tree | 54a72d60fe6ec7621d066d712561eb381a7f01aa /crypto | |
parent | a383292c86663bbc31ac62cc0c04fc77504636a6 (diff) |
crypto: af_alg - Add nokey compatibility path
This patch adds a compatibility path to support old applications
that do acept(2) before setkey.
Cc: stable@vger.kernel.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/af_alg.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index eaf98e287d89..6566d2eb0142 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c | |||
@@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type) | |||
76 | goto unlock; | 76 | goto unlock; |
77 | 77 | ||
78 | type->ops->owner = THIS_MODULE; | 78 | type->ops->owner = THIS_MODULE; |
79 | if (type->ops_nokey) | ||
80 | type->ops_nokey->owner = THIS_MODULE; | ||
79 | node->type = type; | 81 | node->type = type; |
80 | list_add(&node->list, &alg_types); | 82 | list_add(&node->list, &alg_types); |
81 | err = 0; | 83 | err = 0; |
@@ -267,6 +269,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) | |||
267 | const struct af_alg_type *type; | 269 | const struct af_alg_type *type; |
268 | struct sock *sk2; | 270 | struct sock *sk2; |
269 | int err; | 271 | int err; |
272 | bool nokey; | ||
270 | 273 | ||
271 | lock_sock(sk); | 274 | lock_sock(sk); |
272 | type = ask->type; | 275 | type = ask->type; |
@@ -285,12 +288,17 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) | |||
285 | security_sk_clone(sk, sk2); | 288 | security_sk_clone(sk, sk2); |
286 | 289 | ||
287 | err = type->accept(ask->private, sk2); | 290 | err = type->accept(ask->private, sk2); |
291 | |||
292 | nokey = err == -ENOKEY; | ||
293 | if (nokey && type->accept_nokey) | ||
294 | err = type->accept_nokey(ask->private, sk2); | ||
295 | |||
288 | if (err) | 296 | if (err) |
289 | goto unlock; | 297 | goto unlock; |
290 | 298 | ||
291 | sk2->sk_family = PF_ALG; | 299 | sk2->sk_family = PF_ALG; |
292 | 300 | ||
293 | if (!ask->refcnt++) | 301 | if (nokey || !ask->refcnt++) |
294 | sock_hold(sk); | 302 | sock_hold(sk); |
295 | alg_sk(sk2)->parent = sk; | 303 | alg_sk(sk2)->parent = sk; |
296 | alg_sk(sk2)->type = type; | 304 | alg_sk(sk2)->type = type; |
@@ -298,6 +306,9 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) | |||
298 | newsock->ops = type->ops; | 306 | newsock->ops = type->ops; |
299 | newsock->state = SS_CONNECTED; | 307 | newsock->state = SS_CONNECTED; |
300 | 308 | ||
309 | if (nokey) | ||
310 | newsock->ops = type->ops_nokey; | ||
311 | |||
301 | err = 0; | 312 | err = 0; |
302 | 313 | ||
303 | unlock: | 314 | unlock: |