All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corentin Labbe <clabbe.montjoie@gmail.com>
To: Dongliang Mu <mudongliangabcd@gmail.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	Maxime Ripard <mripard@kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	"Jason A. Donenfeld" <Jason@zx2c4.com>,
	Ard Biesheuvel <ardb@kernel.org>,
	Eric Biggers <ebiggers@google.com>,
	Colin Ian King <colin.king@canonical.com>,
	Xiang Chen <chenxiang66@hisilicon.com>,
	dan.carpenter@oracle.com, linux-crypto@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] crypto: sun8i-ce: fix memory leak and return value of sun8i_ce_hash_run
Date: Mon, 26 Jul 2021 08:48:10 +0200	[thread overview]
Message-ID: <YP5aqtmAXS4xNtv/@Red> (raw)
In-Reply-To: <20210726062801.2078117-1-mudongliangabcd@gmail.com>

Le Mon, Jul 26, 2021 at 02:27:50PM +0800, Dongliang Mu a écrit :
> This patch fixes some memory leak caused by dma_mmap_sg/single
> in the error handling code. In addition, it fixes the return value
> when errors related with dma_mmap_sg/single occur.
> 
> Reported-by: Dongliang Mu <mudongliangabcd@gmail.com>
> Fixes: 732b764099f65 ("crypto: sun8i-ce - fix two error path's memory leak")
> Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
> ---
>  .../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 37 ++++++++++---------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
> index 3c073eb3db03..7c4ed19f5466 100644
> --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
> +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
> @@ -324,11 +324,11 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	struct sun8i_ss_alg_template *algt;
>  	struct sun8i_ss_dev *ss;
>  	struct scatterlist *sg;
> -	int nr_sgs, err, digestsize;
> +	int j, i, todo, nr_sgs, tmp_err, digestsize;
> +	int err = 0;
>  	unsigned int len;
>  	u64 fill, min_fill, byte_count;
>  	void *pad, *result;
> -	int j, i, todo;
>  	__be64 *bebits;
>  	__le64 *lebits;
>  	dma_addr_t addr_res, addr_pad;
> @@ -368,14 +368,14 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
>  		dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs);
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_result;
>  	}
>  
>  	addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
>  	if (dma_mapping_error(ss->dev, addr_res)) {
>  		dev_err(ss->dev, "DMA map dest\n");
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_unmap_sg;
>  	}
>  
>  	len = areq->nbytes;
> @@ -390,7 +390,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	if (len > 0) {
>  		dev_err(ss->dev, "remaining len %d\n", len);
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_addr_res;
>  	}
>  
>  	byte_count = areq->nbytes;
> @@ -421,27 +421,30 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	}
>  
>  	addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE);
> -	rctx->t_src[i].addr = addr_pad;
> -	rctx->t_src[i].len = j;
> -	rctx->t_dst[i].addr = addr_res;
> -	rctx->t_dst[i].len = digestsize / 4;
>  	if (dma_mapping_error(ss->dev, addr_pad)) {
>  		dev_err(ss->dev, "DMA error on padding SG\n");
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_addr_res;
>  	}
> +	rctx->t_src[i].addr = addr_pad;
> +	rctx->t_src[i].len = j;
> +	rctx->t_dst[i].addr = addr_res;
> +	rctx->t_dst[i].len = digestsize / 4;
>  
> -	err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
> +	tmp_err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
> +
> +	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
> +
> +	crypto_finalize_hash_request(engine, breq, tmp_err);
>  
>  	dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE);
> +err_addr_res:
> +	dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> +err_unmap_sg:
>  	dma_unmap_sg(ss->dev, areq->src, sg_nents(areq->src),
>  		     DMA_TO_DEVICE);
> -	dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> -
> -	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
> -theend:
> +err_result:
>  	kfree(pad);
>  	kfree(result);
> -	crypto_finalize_hash_request(engine, breq, err);
> -	return 0;
> +	return err;
>  }

Hello

This is wrong, you need to always call crypto_finalize_hash_request()

Do you have tested your changes ? Copying results before dma_unmap() is also very wrong, this will lead to random cache fail.

Regards

WARNING: multiple messages have this Message-ID (diff)
From: Corentin Labbe <clabbe.montjoie@gmail.com>
To: Dongliang Mu <mudongliangabcd@gmail.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	Maxime Ripard <mripard@kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	"Jason A. Donenfeld" <Jason@zx2c4.com>,
	Ard Biesheuvel <ardb@kernel.org>,
	Eric Biggers <ebiggers@google.com>,
	Colin Ian King <colin.king@canonical.com>,
	Xiang Chen <chenxiang66@hisilicon.com>,
	dan.carpenter@oracle.com, linux-crypto@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] crypto: sun8i-ce: fix memory leak and return value of sun8i_ce_hash_run
Date: Mon, 26 Jul 2021 08:48:10 +0200	[thread overview]
Message-ID: <YP5aqtmAXS4xNtv/@Red> (raw)
In-Reply-To: <20210726062801.2078117-1-mudongliangabcd@gmail.com>

Le Mon, Jul 26, 2021 at 02:27:50PM +0800, Dongliang Mu a écrit :
> This patch fixes some memory leak caused by dma_mmap_sg/single
> in the error handling code. In addition, it fixes the return value
> when errors related with dma_mmap_sg/single occur.
> 
> Reported-by: Dongliang Mu <mudongliangabcd@gmail.com>
> Fixes: 732b764099f65 ("crypto: sun8i-ce - fix two error path's memory leak")
> Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
> ---
>  .../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 37 ++++++++++---------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
> index 3c073eb3db03..7c4ed19f5466 100644
> --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
> +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
> @@ -324,11 +324,11 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	struct sun8i_ss_alg_template *algt;
>  	struct sun8i_ss_dev *ss;
>  	struct scatterlist *sg;
> -	int nr_sgs, err, digestsize;
> +	int j, i, todo, nr_sgs, tmp_err, digestsize;
> +	int err = 0;
>  	unsigned int len;
>  	u64 fill, min_fill, byte_count;
>  	void *pad, *result;
> -	int j, i, todo;
>  	__be64 *bebits;
>  	__le64 *lebits;
>  	dma_addr_t addr_res, addr_pad;
> @@ -368,14 +368,14 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
>  		dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs);
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_result;
>  	}
>  
>  	addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
>  	if (dma_mapping_error(ss->dev, addr_res)) {
>  		dev_err(ss->dev, "DMA map dest\n");
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_unmap_sg;
>  	}
>  
>  	len = areq->nbytes;
> @@ -390,7 +390,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	if (len > 0) {
>  		dev_err(ss->dev, "remaining len %d\n", len);
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_addr_res;
>  	}
>  
>  	byte_count = areq->nbytes;
> @@ -421,27 +421,30 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
>  	}
>  
>  	addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE);
> -	rctx->t_src[i].addr = addr_pad;
> -	rctx->t_src[i].len = j;
> -	rctx->t_dst[i].addr = addr_res;
> -	rctx->t_dst[i].len = digestsize / 4;
>  	if (dma_mapping_error(ss->dev, addr_pad)) {
>  		dev_err(ss->dev, "DMA error on padding SG\n");
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_addr_res;
>  	}
> +	rctx->t_src[i].addr = addr_pad;
> +	rctx->t_src[i].len = j;
> +	rctx->t_dst[i].addr = addr_res;
> +	rctx->t_dst[i].len = digestsize / 4;
>  
> -	err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
> +	tmp_err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
> +
> +	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
> +
> +	crypto_finalize_hash_request(engine, breq, tmp_err);
>  
>  	dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE);
> +err_addr_res:
> +	dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> +err_unmap_sg:
>  	dma_unmap_sg(ss->dev, areq->src, sg_nents(areq->src),
>  		     DMA_TO_DEVICE);
> -	dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> -
> -	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
> -theend:
> +err_result:
>  	kfree(pad);
>  	kfree(result);
> -	crypto_finalize_hash_request(engine, breq, err);
> -	return 0;
> +	return err;
>  }

Hello

This is wrong, you need to always call crypto_finalize_hash_request()

Do you have tested your changes ? Copying results before dma_unmap() is also very wrong, this will lead to random cache fail.

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-07-26  6:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-26  6:27 [PATCH] crypto: sun8i-ce: fix memory leak and return value of sun8i_ce_hash_run Dongliang Mu
2021-07-26  6:27 ` Dongliang Mu
2021-07-26  6:48 ` Corentin Labbe [this message]
2021-07-26  6:48   ` Corentin Labbe
2021-07-26  7:05   ` Dongliang Mu
2021-07-26  7:05     ` Dongliang Mu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YP5aqtmAXS4xNtv/@Red \
    --to=clabbe.montjoie@gmail.com \
    --cc=Jason@zx2c4.com \
    --cc=ardb@kernel.org \
    --cc=chenxiang66@hisilicon.com \
    --cc=colin.king@canonical.com \
    --cc=dan.carpenter@oracle.com \
    --cc=davem@davemloft.net \
    --cc=ebiggers@google.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=jernej.skrabec@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=mripard@kernel.org \
    --cc=mudongliangabcd@gmail.com \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.