mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	crypto: qce: skcipher: Fix incorrect sg count for dma transfers
Use the sg count returned by dma_map_sg to call into dmaengine_prep_slave_sg rather than using the original sg count. dma_map_sg can merge consecutive sglist entries, thus making the original sg count wrong. This is a fix for memory coruption issues observed while testing encryption/decryption of large messages using libkcapi framework. Patch has been tested further by running full suite of tcrypt.ko tests including fuzz tests. Signed-off-by: Thara Gopinath <thara.gopinath@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
		
							parent
							
								
									9b7b94683a
								
							
						
					
					
						commit
						1339a7c3ba
					
				
					 1 changed files with 8 additions and 7 deletions
				
			
		| 
						 | 
					@ -72,7 +72,7 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
 | 
				
			||||||
	struct scatterlist *sg;
 | 
						struct scatterlist *sg;
 | 
				
			||||||
	bool diff_dst;
 | 
						bool diff_dst;
 | 
				
			||||||
	gfp_t gfp;
 | 
						gfp_t gfp;
 | 
				
			||||||
	int ret;
 | 
						int dst_nents, src_nents, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rctx->iv = req->iv;
 | 
						rctx->iv = req->iv;
 | 
				
			||||||
	rctx->ivsize = crypto_skcipher_ivsize(skcipher);
 | 
						rctx->ivsize = crypto_skcipher_ivsize(skcipher);
 | 
				
			||||||
| 
						 | 
					@ -123,21 +123,22 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
 | 
				
			||||||
	sg_mark_end(sg);
 | 
						sg_mark_end(sg);
 | 
				
			||||||
	rctx->dst_sg = rctx->dst_tbl.sgl;
 | 
						rctx->dst_sg = rctx->dst_tbl.sgl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
 | 
						dst_nents = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (dst_nents < 0)
 | 
				
			||||||
		goto error_free;
 | 
							goto error_free;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (diff_dst) {
 | 
						if (diff_dst) {
 | 
				
			||||||
		ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src);
 | 
							src_nents = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src);
 | 
				
			||||||
		if (ret < 0)
 | 
							if (src_nents < 0)
 | 
				
			||||||
			goto error_unmap_dst;
 | 
								goto error_unmap_dst;
 | 
				
			||||||
		rctx->src_sg = req->src;
 | 
							rctx->src_sg = req->src;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		rctx->src_sg = rctx->dst_sg;
 | 
							rctx->src_sg = rctx->dst_sg;
 | 
				
			||||||
 | 
							src_nents = dst_nents - 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents,
 | 
						ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, src_nents,
 | 
				
			||||||
			       rctx->dst_sg, rctx->dst_nents,
 | 
								       rctx->dst_sg, dst_nents,
 | 
				
			||||||
			       qce_skcipher_done, async_req);
 | 
								       qce_skcipher_done, async_req);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto error_unmap_src;
 | 
							goto error_unmap_src;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue