summaryrefslogtreecommitdiffstats
path: root/crypto/algif_aead.c
diff options
context:
space:
mode:
authorLinus Torvalds2017-12-22 21:22:48 +0100
committerLinus Torvalds2017-12-22 21:22:48 +0100
commit0fc0f18bed026a7aa6d5499d06cc9a6eb47dc3cc (patch)
tree65b591e05b563441c22d28ef76485de8ad1deefc /crypto/algif_aead.c
parentMerge tag 'pinctrl-v4.15-3' of git://git.kernel.org/pub/scm/linux/kernel/git/... (diff)
parentcrypto: af_alg - fix race accessing cipher request (diff)
downloadkernel-qcow2-linux-0fc0f18bed026a7aa6d5499d06cc9a6eb47dc3cc.tar.gz
kernel-qcow2-linux-0fc0f18bed026a7aa6d5499d06cc9a6eb47dc3cc.tar.xz
kernel-qcow2-linux-0fc0f18bed026a7aa6d5499d06cc9a6eb47dc3cc.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_aead.c')
-rw-r--r--crypto/algif_aead.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 48b34e9c6834..ddcc45f77edd 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -111,6 +111,12 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
size_t usedpages = 0; /* [in] RX bufs to be used from user */
size_t processed = 0; /* [in] TX bufs to be consumed */
+ if (!ctx->used) {
+ err = af_alg_wait_for_data(sk, flags);
+ if (err)
+ return err;
+ }
+
/*
* Data length provided by caller via sendmsg/sendpage that has not
* yet been processed.
@@ -285,6 +291,10 @@ static int _aead_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 = outlen;
+
aead_request_set_callback(&areq->cra_u.aead_req,
CRYPTO_TFM_REQ_MAY_BACKLOG,
af_alg_async_cb, areq);
@@ -292,12 +302,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
crypto_aead_decrypt(&areq->cra_u.aead_req);
/* AIO operation in progress */
- if (err == -EINPROGRESS || err == -EBUSY) {
- /* Remember output size that will be generated. */
- areq->outlen = outlen;
-
+ if (err == -EINPROGRESS || err == -EBUSY)
return -EIOCBQUEUED;
- }
sock_put(sk);
} else {