forked from mirrors/linux
		
	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: 2d97591ef4 ("crypto: af_alg - consolidation of...")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
			
			
This commit is contained in:
		
							parent
							
								
									1532e31f50
								
							
						
					
					
						commit
						f3c802a1f3
					
				
					 4 changed files with 15 additions and 8 deletions
				
			
		|  | @ -635,6 +635,7 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, | |||
| 
 | ||||
| 	if (!ctx->used) | ||||
| 		ctx->merge = 0; | ||||
| 	ctx->init = ctx->more; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(af_alg_pull_tsgl); | ||||
| 
 | ||||
|  | @ -734,9 +735,10 @@ EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup); | |||
|  * | ||||
|  * @sk socket of connection to user space | ||||
|  * @flags If MSG_DONTWAIT is set, then only report if function would sleep | ||||
|  * @min Set to minimum request size if partial requests are allowed. | ||||
|  * @return 0 when writable memory is available, < 0 upon error | ||||
|  */ | ||||
| int af_alg_wait_for_data(struct sock *sk, unsigned flags) | ||||
| int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min) | ||||
| { | ||||
| 	DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||||
| 	struct alg_sock *ask = alg_sk(sk); | ||||
|  | @ -754,7 +756,9 @@ int af_alg_wait_for_data(struct sock *sk, unsigned flags) | |||
| 		if (signal_pending(current)) | ||||
| 			break; | ||||
| 		timeout = MAX_SCHEDULE_TIMEOUT; | ||||
| 		if (sk_wait_event(sk, &timeout, (ctx->used || !ctx->more), | ||||
| 		if (sk_wait_event(sk, &timeout, | ||||
| 				  ctx->init && (!ctx->more || | ||||
| 						(min && ctx->used >= min)), | ||||
| 				  &wait)) { | ||||
| 			err = 0; | ||||
| 			break; | ||||
|  | @ -843,7 +847,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, | |||
| 	} | ||||
| 
 | ||||
| 	lock_sock(sk); | ||||
| 	if (!ctx->more && ctx->used) { | ||||
| 	if (ctx->init && (init || !ctx->more)) { | ||||
| 		err = -EINVAL; | ||||
| 		goto unlock; | ||||
| 	} | ||||
|  | @ -854,6 +858,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, | |||
| 			memcpy(ctx->iv, con.iv->iv, ivsize); | ||||
| 
 | ||||
| 		ctx->aead_assoclen = con.aead_assoclen; | ||||
| 		ctx->init = true; | ||||
| 	} | ||||
| 
 | ||||
| 	while (size) { | ||||
|  |  | |||
|  | @ -106,8 +106,8 @@ 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 (!ctx->init || ctx->more) { | ||||
| 		err = af_alg_wait_for_data(sk, flags, 0); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 	} | ||||
|  |  | |||
|  | @ -61,8 +61,8 @@ 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 (!ctx->init || (ctx->more && ctx->used < bs)) { | ||||
| 		err = af_alg_wait_for_data(sk, flags, bs); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 	} | ||||
|  |  | |||
|  | @ -135,6 +135,7 @@ struct af_alg_async_req { | |||
|  *			SG? | ||||
|  * @enc:		Cryptographic operation to be performed when | ||||
|  *			recvmsg is invoked. | ||||
|  * @init:		True if metadata has been sent. | ||||
|  * @len:		Length of memory allocated for this data structure. | ||||
|  */ | ||||
| struct af_alg_ctx { | ||||
|  | @ -151,6 +152,7 @@ struct af_alg_ctx { | |||
| 	bool more; | ||||
| 	bool merge; | ||||
| 	bool enc; | ||||
| 	bool init; | ||||
| 
 | ||||
| 	unsigned int len; | ||||
| }; | ||||
|  | @ -226,7 +228,7 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset); | |||
| void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, | ||||
| 		      size_t dst_offset); | ||||
| void af_alg_wmem_wakeup(struct sock *sk); | ||||
| int af_alg_wait_for_data(struct sock *sk, unsigned flags); | ||||
| int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min); | ||||
| int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, | ||||
| 		   unsigned int ivsize); | ||||
| ssize_t af_alg_sendpage(struct socket *sock, struct page *page, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Herbert Xu
						Herbert Xu