summaryrefslogtreecommitdiff
path: root/crypto/algif_skcipher.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-12-22 12:22:48 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-12-22 12:22:48 -0800
commitd5abe860ac298ebe723b37a6f63a5b2d404fca60 (patch)
tree0abd8646ad5a39bf4993faf67e0200c6be6a5e13 /crypto/algif_skcipher.c
parent479a1006060c7452064ee0c83b25c7e648c479aa (diff)
parentbecd0fb2474ef9c1dc09bee93fb13d68681f7f47 (diff)
downloadlinux-crypto-d5abe860ac298ebe723b37a6f63a5b2d404fca60.tar.gz
linux-crypto-d5abe860ac298ebe723b37a6f63a5b2d404fca60.zip
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: "This fixes the following issues: - fix chacha20 crash on zero-length input due to unset IV - fix potential race conditions in mcryptd with spinlock - only wait once at top of algif recvmsg to avoid inconsistencies - fix potential use-after-free in algif_aead/algif_skcipher" * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: crypto: af_alg - fix race accessing cipher request crypto: mcryptd - protect the per-CPU queue with a lock crypto: af_alg - wait for data at beginning of recvmsg crypto: skcipher - set walk.iv for zero-length inputs
Diffstat (limited to 'crypto/algif_skcipher.c')
-rw-r--r--crypto/algif_skcipher.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 30cff827..baef9bfc 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -72,6 +72,12 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
int err = 0;
size_t len = 0;
+ if (!ctx->used) {
+ err = af_alg_wait_for_data(sk, flags);
+ if (err)
+ return err;
+ }
+
/* Allocate cipher request for current operation. */
areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
crypto_skcipher_reqsize(tfm));
@@ -119,6 +125,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
/* AIO operation */
sock_hold(sk);
areq->iocb = msg->msg_iocb;
+
+ /* Remember output size that will be generated. */
+ areq->outlen = len;
+
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
CRYPTO_TFM_REQ_MAY_SLEEP,
af_alg_async_cb, areq);
@@ -127,12 +137,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
/* AIO operation in progress */
- if (err == -EINPROGRESS || err == -EBUSY) {
- /* Remember output size that will be generated. */
- areq->outlen = len;
-
+ if (err == -EINPROGRESS || err == -EBUSY)
return -EIOCBQUEUED;
- }
sock_put(sk);
} else {