aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2016-02-03 08:39:26 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2016-02-06 02:23:55 -0500
commit6454c2b83f719057069777132b13949e4c6b6350 (patch)
tree49d2a92d72b5461fd9388b058d912368d0e85c9c
parentec69bbfb9902c32a5c1492f2b1b8ad032a66d724 (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.c15
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;