Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: algif_aead - Only wake up when ctx->more is zero

AEAD does not support partial requests so we must not wake up
while ctx->more is set. In order to distinguish between the
case of no data sent yet and a zero-length request, a new init
flag has been added to ctx.

SKCIPHER has also been modified to ensure that at least a block
of data is available if there is more data to come.

Fixes: 2d97591ef43d ("crypto: af_alg - consolidation of...")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+15 -8
+8 -3
crypto/af_alg.c
··· 635 635 636 636 if (!ctx->used) 637 637 ctx->merge = 0; 638 + ctx->init = ctx->more; 638 639 } 639 640 EXPORT_SYMBOL_GPL(af_alg_pull_tsgl); 640 641 ··· 735 734 * 736 735 * @sk socket of connection to user space 737 736 * @flags If MSG_DONTWAIT is set, then only report if function would sleep 737 + * @min Set to minimum request size if partial requests are allowed. 738 738 * @return 0 when writable memory is available, < 0 upon error 739 739 */ 740 - int af_alg_wait_for_data(struct sock *sk, unsigned flags) 740 + int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min) 741 741 { 742 742 DEFINE_WAIT_FUNC(wait, woken_wake_function); 743 743 struct alg_sock *ask = alg_sk(sk); ··· 756 754 if (signal_pending(current)) 757 755 break; 758 756 timeout = MAX_SCHEDULE_TIMEOUT; 759 - if (sk_wait_event(sk, &timeout, (ctx->used || !ctx->more), 757 + if (sk_wait_event(sk, &timeout, 758 + ctx->init && (!ctx->more || 759 + (min && ctx->used >= min)), 760 760 &wait)) { 761 761 err = 0; 762 762 break; ··· 847 843 } 848 844 849 845 lock_sock(sk); 850 - if (!ctx->more && ctx->used) { 846 + if (ctx->init && (init || !ctx->more)) { 851 847 err = -EINVAL; 852 848 goto unlock; 853 849 } ··· 858 854 memcpy(ctx->iv, con.iv->iv, ivsize); 859 855 860 856 ctx->aead_assoclen = con.aead_assoclen; 857 + ctx->init = true; 861 858 } 862 859 863 860 while (size) {
+2 -2
crypto/algif_aead.c
··· 106 106 size_t usedpages = 0; /* [in] RX bufs to be used from user */ 107 107 size_t processed = 0; /* [in] TX bufs to be consumed */ 108 108 109 - if (!ctx->used) { 110 - err = af_alg_wait_for_data(sk, flags); 109 + if (!ctx->init || ctx->more) { 110 + err = af_alg_wait_for_data(sk, flags, 0); 111 111 if (err) 112 112 return err; 113 113 }
+2 -2
crypto/algif_skcipher.c
··· 61 61 int err = 0; 62 62 size_t len = 0; 63 63 64 - if (!ctx->used) { 65 - err = af_alg_wait_for_data(sk, flags); 64 + if (!ctx->init || (ctx->more && ctx->used < bs)) { 65 + err = af_alg_wait_for_data(sk, flags, bs); 66 66 if (err) 67 67 return err; 68 68 }
+3 -1
include/crypto/if_alg.h
··· 135 135 * SG? 136 136 * @enc: Cryptographic operation to be performed when 137 137 * recvmsg is invoked. 138 + * @init: True if metadata has been sent. 138 139 * @len: Length of memory allocated for this data structure. 139 140 */ 140 141 struct af_alg_ctx { ··· 152 151 bool more; 153 152 bool merge; 154 153 bool enc; 154 + bool init; 155 155 156 156 unsigned int len; 157 157 }; ··· 228 226 void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, 229 227 size_t dst_offset); 230 228 void af_alg_wmem_wakeup(struct sock *sk); 231 - int af_alg_wait_for_data(struct sock *sk, unsigned flags); 229 + int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min); 232 230 int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, 233 231 unsigned int ivsize); 234 232 ssize_t af_alg_sendpage(struct socket *sock, struct page *page,