From: Willy Tarreau <w@1wt.eu>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, linux@roeck-us.net
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
Andrey Ryabinin <aryabinin@virtuozzo.com>,
Willy Tarreau <w@1wt.eu>
Subject: [PATCH 3.10 004/319] crypto: af_alg - Disallow bind/setkey/... after accept(2)
Date: Sun, 5 Feb 2017 20:09:08 +0100 [thread overview]
Message-ID: <1486322063-7558-5-git-send-email-w@1wt.eu> (raw)
In-Reply-To: <1486322063-7558-1-git-send-email-w@1wt.eu>
From: Herbert Xu <herbert@gondor.apana.org.au>
commit c840ac6af3f8713a71b4d2363419145760bd6044 upstream.
Each af_alg parent socket obtained by socket(2) corresponds to a
tfm object once bind(2) has succeeded. An accept(2) call on that
parent socket creates a context which then uses the tfm object.
Therefore as long as any child sockets created by accept(2) exist
the parent socket must not be modified or freed.
This patch guarantees this by using locks and a reference count
on the parent socket. Any attempt to modify the parent socket will
fail with EBUSY.
Cc: stable@vger.kernel.org
Reported-by: Dmitry Vyukov <dvyukov@google.com>
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>
---
crypto/af_alg.c | 35 ++++++++++++++++++++++++++++++++---
include/crypto/if_alg.h | 8 +++-----
2 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 1aaa555..0ca108f 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -125,6 +125,23 @@ int af_alg_release(struct socket *sock)
}
EXPORT_SYMBOL_GPL(af_alg_release);
+void af_alg_release_parent(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ bool last;
+
+ sk = ask->parent;
+ ask = alg_sk(sk);
+
+ lock_sock(sk);
+ last = !--ask->refcnt;
+ release_sock(sk);
+
+ if (last)
+ sock_put(sk);
+}
+EXPORT_SYMBOL_GPL(af_alg_release_parent);
+
static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sock *sk = sock->sk;
@@ -132,6 +149,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct sockaddr_alg *sa = (void *)uaddr;
const struct af_alg_type *type;
void *private;
+ int err;
if (sock->state == SS_CONNECTED)
return -EINVAL;
@@ -157,16 +175,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return PTR_ERR(private);
}
+ err = -EBUSY;
lock_sock(sk);
+ if (ask->refcnt)
+ goto unlock;
swap(ask->type, type);
swap(ask->private, private);
+ err = 0;
+
+unlock:
release_sock(sk);
alg_do_release(type, private);
- return 0;
+ return err;
}
static int alg_setkey(struct sock *sk, char __user *ukey,
@@ -199,11 +223,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
const struct af_alg_type *type;
- int err = -ENOPROTOOPT;
+ int err = -EBUSY;
lock_sock(sk);
+ if (ask->refcnt)
+ goto unlock;
+
type = ask->type;
+ err = -ENOPROTOOPT;
if (level != SOL_ALG || !type)
goto unlock;
@@ -252,7 +280,8 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
sk2->sk_family = PF_ALG;
- sock_hold(sk);
+ if (!ask->refcnt++)
+ sock_hold(sk);
alg_sk(sk2)->parent = sk;
alg_sk(sk2)->type = type;
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index d61c111..2f38daa 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -30,6 +30,8 @@ struct alg_sock {
struct sock *parent;
+ unsigned int refcnt;
+
const struct af_alg_type *type;
void *private;
};
@@ -64,6 +66,7 @@ int af_alg_register_type(const struct af_alg_type *type);
int af_alg_unregister_type(const struct af_alg_type *type);
int af_alg_release(struct socket *sock);
+void af_alg_release_parent(struct sock *sk);
int af_alg_accept(struct sock *sk, struct socket *newsock);
int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len,
@@ -80,11 +83,6 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
return (struct alg_sock *)sk;
}
-static inline void af_alg_release_parent(struct sock *sk)
-{
- sock_put(alg_sk(sk)->parent);
-}
-
static inline void af_alg_init_completion(struct af_alg_completion *completion)
{
init_completion(&completion->completion);
--
2.8.0.rc2.1.gbe9624a
next prev parent reply other threads:[~2017-02-05 19:15 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-05 19:09 [PATCH 3.10 000/319] 3.10.105-stable review Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 001/319] sched/core: Fix a race between try_to_wake_up() and a woken up task Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 002/319] sched/core: Fix an SMP ordering race in try_to_wake_up() vs. schedule() Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 003/319] crypto: algif_skcipher - Require setkey before accept(2) Willy Tarreau
2017-02-05 19:09 ` Willy Tarreau [this message]
2017-02-05 19:09 ` [PATCH 3.10 005/319] crypto: af_alg - Add nokey compatibility path Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 006/319] crypto: algif_skcipher " Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 007/319] crypto: hash - Add crypto_ahash_has_setkey Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 008/319] crypto: shash - Fix has_key setting Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 009/319] crypto: algif_hash - Require setkey before accept(2) Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 010/319] crypto: skcipher - Add crypto_skcipher_has_setkey Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 011/319] crypto: algif_skcipher - Add key check exception for cipher_null Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 012/319] crypto: af_alg - Allow af_af_alg_release_parent to be called on nokey path Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 013/319] crypto: algif_hash - Remove custom release parent function Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 014/319] crypto: algif_skcipher " Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 015/319] crypto: af_alg - Forbid bind(2) when nokey child sockets are present Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 016/319] crypto: algif_hash - Fix race condition in hash_check_key Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 017/319] crypto: algif_skcipher - Fix race condition in skcipher_check_key Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 018/319] crypto: algif_skcipher - Load TX SG list after waiting Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 019/319] crypto: cryptd - initialize child shash_desc on import Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 020/319] crypto: skcipher - Fix blkcipher walk OOM crash Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 021/319] crypto: gcm - Fix IV buffer size in crypto_gcm_setkey Willy Tarreau
2017-02-05 19:09 ` [PATCH 3.10 022/319] MIPS: KVM: Fix unused variable build warning Willy Tarreau
2017-02-06 3:12 ` [PATCH 3.10 000/319] 3.10.105-stable review Guenter Roeck
2017-02-06 6:30 ` Willy Tarreau
2017-02-06 8:13 ` Willy Tarreau
2017-02-06 14:46 ` Guenter Roeck
2017-02-06 15:10 ` Willy Tarreau
2017-02-06 22:48 ` Willy Tarreau
2017-02-06 23:48 ` Guenter Roeck
2017-02-07 4:56 ` Guenter Roeck
2017-02-07 6:39 ` Willy Tarreau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1486322063-7558-5-git-send-email-w@1wt.eu \
--to=w@1wt.eu \
--cc=aryabinin@virtuozzo.com \
--cc=herbert@gondor.apana.org.au \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®