mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	crypto: algif_hash - Fix NULL hash crash with shash
Recently algif_hash has been changed to allow null hashes.  This
triggers a bug when used with an shash algorithm whereby it will
cause a crash during the digest operation.
This patch fixes it by avoiding the digest operation and instead
doing an init followed by a final which avoids the buggy code in
shash.
This patch also ensures that the result buffer is freed after an
error so that it is not returned as a genuine hash result on the
next recv call.
The shash/ahash wrapper code will be fixed later to handle this
case correctly.
Fixes: 493b2ed3f7 ("crypto: algif_hash - Handle NULL hashes correctly")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Tested-by: Laura Abbott <labbott@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									a5a40d4624
								
							
						
					
					
						commit
						a8348bca29
					
				
					 1 changed files with 10 additions and 7 deletions
				
			
		| 
						 | 
					@ -214,23 +214,26 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
 | 
						ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ctx->more) {
 | 
						if (!result) {
 | 
				
			||||||
 | 
							err = af_alg_wait_for_completion(
 | 
				
			||||||
 | 
									crypto_ahash_init(&ctx->req),
 | 
				
			||||||
 | 
									&ctx->completion);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								goto unlock;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!result || ctx->more) {
 | 
				
			||||||
		ctx->more = 0;
 | 
							ctx->more = 0;
 | 
				
			||||||
		err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
 | 
							err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
 | 
				
			||||||
						 &ctx->completion);
 | 
											 &ctx->completion);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			goto unlock;
 | 
								goto unlock;
 | 
				
			||||||
	} else if (!result) {
 | 
					 | 
				
			||||||
		err = af_alg_wait_for_completion(
 | 
					 | 
				
			||||||
				crypto_ahash_digest(&ctx->req),
 | 
					 | 
				
			||||||
				&ctx->completion);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = memcpy_to_msg(msg, ctx->result, len);
 | 
						err = memcpy_to_msg(msg, ctx->result, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hash_free_result(sk, ctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unlock:
 | 
					unlock:
 | 
				
			||||||
 | 
						hash_free_result(sk, ctx);
 | 
				
			||||||
	release_sock(sk);
 | 
						release_sock(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err ?: len;
 | 
						return err ?: len;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue