aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2016-10-27 17:29:45 +0300
committerMister Oyster <oysterized@gmail.com>2017-04-11 10:59:02 +0200
commit2a017edbb65794f3e82c0ca20f9d3b2e7ea25fd1 (patch)
tree2763d2929a8bec9b4023fa71191336d21e8ccf25
parentd46d77e1de227a700e321d63441402ec3e0fcb6a (diff)
crypto: af_alg - Forbid bind(2) when nokey child sockets are present
commit a6a48c565f6f112c6983e2a02b1602189ed6e26e upstream. This patch forbids the calling of bind(2) when there are child sockets created by accept(2) in existence, even if they are created on the nokey path. This is needed as those child sockets have references to the tfm object which bind(2) will destroy. Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com> Signed-off-by: Willy Tarreau <w@1wt.eu>
-rw-r--r--crypto/af_alg.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 2f8fd8441..68ec1ac41 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -130,19 +130,16 @@ EXPORT_SYMBOL_GPL(af_alg_release);
void af_alg_release_parent(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
- bool last;
+ unsigned int nokey = ask->nokey_refcnt;
+ bool last = nokey && !ask->refcnt;
sk = ask->parent;
-
- if (ask->nokey_refcnt && !ask->refcnt) {
- sock_put(sk);
- return;
- }
-
ask = alg_sk(sk);
lock_sock(sk);
- last = !--ask->refcnt;
+ ask->nokey_refcnt -= nokey;
+ if (!last)
+ last = !--ask->refcnt;
release_sock(sk);
if (last)
@@ -185,7 +182,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err = -EBUSY;
lock_sock(sk);
- if (ask->refcnt)
+ if (ask->refcnt | ask->nokey_refcnt)
goto unlock;
swap(ask->type, type);
@@ -296,6 +293,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
if (nokey || !ask->refcnt++)
sock_hold(sk);
+ ask->nokey_refcnt += nokey;
alg_sk(sk2)->parent = sk;
alg_sk(sk2)->type = type;
alg_sk(sk2)->nokey_refcnt = nokey;