diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2016-02-03 08:39:26 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-02-06 02:23:55 -0500 |
commit | 6454c2b83f719057069777132b13949e4c6b6350 (patch) | |
tree | 49d2a92d72b5461fd9388b058d912368d0e85c9c | |
parent | ec69bbfb9902c32a5c1492f2b1b8ad032a66d724 (diff) |
crypto: algif_skcipher - Do not dereference ctx without socket lock
Any access to non-constant bits of the private context must be
done under the socket lock, in particular, this includes ctx->req.
This patch moves such accesses under the lock, and fetches the
tfm from the parent socket which is guaranteed to be constant,
rather than from ctx->req.
Cc: stable@vger.kernel.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/algif_skcipher.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index ec07a864b9c5..ef84353e0f24 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c | |||
@@ -295,8 +295,11 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, | |||
295 | { | 295 | { |
296 | struct sock *sk = sock->sk; | 296 | struct sock *sk = sock->sk; |
297 | struct alg_sock *ask = alg_sk(sk); | 297 | struct alg_sock *ask = alg_sk(sk); |
298 | struct sock *psk = ask->parent; | ||
299 | struct alg_sock *pask = alg_sk(psk); | ||
298 | struct skcipher_ctx *ctx = ask->private; | 300 | struct skcipher_ctx *ctx = ask->private; |
299 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req); | 301 | struct skcipher_tfm *skc = pask->private; |
302 | struct crypto_skcipher *tfm = skc->skcipher; | ||
300 | unsigned ivsize = crypto_skcipher_ivsize(tfm); | 303 | unsigned ivsize = crypto_skcipher_ivsize(tfm); |
301 | struct skcipher_sg_list *sgl; | 304 | struct skcipher_sg_list *sgl; |
302 | struct af_alg_control con = {}; | 305 | struct af_alg_control con = {}; |
@@ -508,7 +511,7 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
508 | struct skcipher_async_req *sreq; | 511 | struct skcipher_async_req *sreq; |
509 | struct skcipher_request *req; | 512 | struct skcipher_request *req; |
510 | struct skcipher_async_rsgl *last_rsgl = NULL; | 513 | struct skcipher_async_rsgl *last_rsgl = NULL; |
511 | unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx); | 514 | unsigned int txbufs = 0, len = 0, tx_nents; |
512 | unsigned int reqsize = crypto_skcipher_reqsize(tfm); | 515 | unsigned int reqsize = crypto_skcipher_reqsize(tfm); |
513 | unsigned int ivsize = crypto_skcipher_ivsize(tfm); | 516 | unsigned int ivsize = crypto_skcipher_ivsize(tfm); |
514 | int err = -ENOMEM; | 517 | int err = -ENOMEM; |
@@ -526,6 +529,7 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg, | |||
526 | sreq->inflight = &ctx->inflight; | 529 | sreq->inflight = &ctx->inflight; |
527 | 530 | ||
528 | lock_sock(sk); | 531 | lock_sock(sk); |
532 | tx_nents = skcipher_all_sg_nents(ctx); | ||
529 | sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); | 533 | sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); |
530 | if (unlikely(!sreq->tsg)) | 534 | if (unlikely(!sreq->tsg)) |
531 | goto unlock; | 535 | goto unlock; |
@@ -633,9 +637,12 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg, | |||
633 | { | 637 | { |
634 | struct sock *sk = sock->sk; | 638 | struct sock *sk = sock->sk; |
635 | struct alg_sock *ask = alg_sk(sk); | 639 | struct alg_sock *ask = alg_sk(sk); |
640 | struct sock *psk = ask->parent; | ||
641 | struct alg_sock *pask = alg_sk(psk); | ||
636 | struct skcipher_ctx *ctx = ask->private; | 642 | struct skcipher_ctx *ctx = ask->private; |
637 | unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm( | 643 | struct skcipher_tfm *skc = pask->private; |
638 | &ctx->req)); | 644 | struct crypto_skcipher *tfm = skc->skcipher; |
645 | unsigned bs = crypto_skcipher_blocksize(tfm); | ||
639 | struct skcipher_sg_list *sgl; | 646 | struct skcipher_sg_list *sgl; |
640 | struct scatterlist *sg; | 647 | struct scatterlist *sg; |
641 | int err = -EAGAIN; | 648 | int err = -EAGAIN; |