linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] crypto: hisilicon - A couple of fixes
@ 2018-11-05 12:35 John Garry
  2018-11-05 12:35 ` [PATCH 1/2] crypto: hisilicon - Fix NULL dereference for same dst and src John Garry
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: John Garry @ 2018-11-05 12:35 UTC (permalink / raw)
  To: herbert, davem
  Cc: Jonathan.Cameron, linux-crypto, linux-kernel, linuxarm, John Garry

This patchset fixes a couple of issues I discovered while attempting to
bringup the driver.

John Garry (2):
  crypto: hisilicon -  Fix NULL dereference for same dst and src
  crypto: hisilicon -  Fix reference after free of memories on error
 path

 drivers/crypto/hisilicon/sec/sec_algs.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] crypto: hisilicon -  Fix NULL dereference for same dst and src
  2018-11-05 12:35 [PATCH 0/2] crypto: hisilicon - A couple of fixes John Garry
@ 2018-11-05 12:35 ` John Garry
  2018-11-05 12:35 ` [PATCH 2/2] crypto: hisilicon - Fix reference after free of memories on error path John Garry
  2018-11-09  9:43 ` [PATCH 0/2] crypto: hisilicon - A couple of fixes Herbert Xu
  2 siblings, 0 replies; 4+ messages in thread
From: John Garry @ 2018-11-05 12:35 UTC (permalink / raw)
  To: herbert, davem
  Cc: Jonathan.Cameron, linux-crypto, linux-kernel, linuxarm, John Garry

When the source and destination addresses for the cipher are the same, we
will get a NULL dereference from accessing the split destination
scatterlist memories, as shown:

[   56.565719] tcrypt:
[   56.565719] testing speed of async ecb(aes) (hisi_sec_aes_ecb) encryption
[   56.574683] tcrypt: test 0 (128 bit key, 16 byte blocks):
[   56.587585] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[   56.596361] Mem abort info:
[   56.599151]   ESR = 0x96000006
[   56.602196]   Exception class = DABT (current EL), IL = 32 bits
[   56.608105]   SET = 0, FnV = 0
[   56.611149]   EA = 0, S1PTW = 0
[   56.614280] Data abort info:
[   56.617151]   ISV = 0, ISS = 0x00000006
[   56.620976]   CM = 0, WnR = 0
[   56.623930] user pgtable: 4k pages, 48-bit VAs, pgdp = (____ptrval____)
[   56.630533] [0000000000000000] pgd=0000041fc7e4d003, pud=0000041fcd9bf003, pmd=0000000000000000
[   56.639224] Internal error: Oops: 96000006 [#1] PREEMPT SMP
[   56.644782] Modules linked in: tcrypt(+)
[   56.648695] CPU: 21 PID: 2326 Comm: insmod Tainted: G        W         4.19.0-rc6-00001-g3fabfb8-dirty #716
[   56.658420] Hardware name: Huawei Taishan 2280 /D05, BIOS Hisilicon D05 IT17 Nemo 2.0 RC0 10/05/2018
[   56.667537] pstate: 20000005 (nzCv daif -PAN -UAO)
[   56.672322] pc : sec_alg_skcipher_crypto+0x318/0x748
[   56.677274] lr : sec_alg_skcipher_crypto+0x178/0x748
[   56.682224] sp : ffff0000118e3840
[   56.685525] x29: ffff0000118e3840 x28: ffff841fbb3f8118
[   56.690825] x27: 0000000000000000 x26: 0000000000000000
[   56.696125] x25: ffff841fbb3f8080 x24: ffff841fbadc0018
[   56.701425] x23: ffff000009119000 x22: ffff841fbb24e280
[   56.706724] x21: ffff841ff212e780 x20: ffff841ff212e700
[   56.712023] x19: 0000000000000001 x18: ffffffffffffffff
[   56.717322] x17: 0000000000000000 x16: 0000000000000000
[   56.722621] x15: ffff0000091196c8 x14: 72635f7265687069
[   56.727920] x13: 636b735f676c615f x12: ffff000009119940
[   56.733219] x11: 0000000000000000 x10: 00000000006080c0
[   56.738519] x9 : 0000000000000000 x8 : ffff841fbb24e480
[   56.743818] x7 : ffff841fbb24e500 x6 : ffff841ff00cdcc0
[   56.749117] x5 : 0000000000000010 x4 : 0000000000000000
[   56.754416] x3 : ffff841fbb24e380 x2 : ffff841fbb24e480
[   56.759715] x1 : 0000000000000000 x0 : ffff000008f682c8
[   56.765016] Process insmod (pid: 2326, stack limit = 0x(____ptrval____))
[   56.771702] Call trace:
[   56.774136]  sec_alg_skcipher_crypto+0x318/0x748
[   56.778740]  sec_alg_skcipher_encrypt+0x10/0x18
[   56.783259]  test_skcipher_speed+0x2a0/0x700 [tcrypt]
[   56.788298]  do_test+0x18f8/0x48c8 [tcrypt]
[   56.792469]  tcrypt_mod_init+0x60/0x1000 [tcrypt]
[   56.797161]  do_one_initcall+0x5c/0x178
[   56.800985]  do_init_module+0x58/0x1b4
[   56.804721]  load_module+0x1da4/0x2150
[   56.808456]  __se_sys_init_module+0x14c/0x1e8
[   56.812799]  __arm64_sys_init_module+0x18/0x20
[   56.817231]  el0_svc_common+0x60/0xe8
[   56.820880]  el0_svc_handler+0x2c/0x80
[   56.824615]  el0_svc+0x8/0xc
[   56.827483] Code: a94c87a3 910b2000 f87b7842 f9004ba2 (b87b7821)
[   56.833564] ---[ end trace 0f63290590e93d94 ]---
Segmentation fault

Fix this by only accessing these memories when we have different src and
dst.

Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver")
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/crypto/hisilicon/sec/sec_algs.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c
index f7d6d69..32c6c02 100644
--- a/drivers/crypto/hisilicon/sec/sec_algs.c
+++ b/drivers/crypto/hisilicon/sec/sec_algs.c
@@ -732,6 +732,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 	int *splits_in_nents;
 	int *splits_out_nents = NULL;
 	struct sec_request_el *el, *temp;
+	bool split = skreq->src != skreq->dst;
 
 	mutex_init(&sec_req->lock);
 	sec_req->req_base = &skreq->base;
@@ -750,7 +751,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 	if (ret)
 		goto err_free_split_sizes;
 
-	if (skreq->src != skreq->dst) {
+	if (split) {
 		sec_req->len_out = sg_nents(skreq->dst);
 		ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps,
 					   &splits_out, &splits_out_nents,
@@ -785,8 +786,9 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 					       split_sizes[i],
 					       skreq->src != skreq->dst,
 					       splits_in[i], splits_in_nents[i],
-					       splits_out[i],
-					       splits_out_nents[i], info);
+					       split ? splits_out[i] : NULL,
+					       split ? splits_out_nents[i] : 0,
+					       info);
 		if (IS_ERR(el)) {
 			ret = PTR_ERR(el);
 			goto err_free_elements;
@@ -854,7 +856,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 				 crypto_skcipher_ivsize(atfm),
 				 DMA_BIDIRECTIONAL);
 err_unmap_out_sg:
-	if (skreq->src != skreq->dst)
+	if (split)
 		sec_unmap_sg_on_err(skreq->dst, steps, splits_out,
 				    splits_out_nents, sec_req->len_out,
 				    info->dev);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] crypto: hisilicon -  Fix reference after free of memories on error path
  2018-11-05 12:35 [PATCH 0/2] crypto: hisilicon - A couple of fixes John Garry
  2018-11-05 12:35 ` [PATCH 1/2] crypto: hisilicon - Fix NULL dereference for same dst and src John Garry
@ 2018-11-05 12:35 ` John Garry
  2018-11-09  9:43 ` [PATCH 0/2] crypto: hisilicon - A couple of fixes Herbert Xu
  2 siblings, 0 replies; 4+ messages in thread
From: John Garry @ 2018-11-05 12:35 UTC (permalink / raw)
  To: herbert, davem
  Cc: Jonathan.Cameron, linux-crypto, linux-kernel, linuxarm, John Garry

coccicheck currently warns of the following issues in the driver:
drivers/crypto/hisilicon/sec/sec_algs.c:864:51-66: ERROR: reference preceded by free on line 812
drivers/crypto/hisilicon/sec/sec_algs.c:864:40-49: ERROR: reference preceded by free on line 813
drivers/crypto/hisilicon/sec/sec_algs.c:861:8-24: ERROR: reference preceded by free on line 814
drivers/crypto/hisilicon/sec/sec_algs.c:860:41-51: ERROR: reference preceded by free on line 815
drivers/crypto/hisilicon/sec/sec_algs.c:867:7-18: ERROR: reference preceded by free on line 816

It would appear than on certain error paths that we may attempt reference-
after-free some memories.

This patch fixes those issues. The solution doesn't look perfect, but
having same memories free'd possibly from separate functions makes it
tricky.

Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver")
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/crypto/hisilicon/sec/sec_algs.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c
index 32c6c02..cdc4f9a 100644
--- a/drivers/crypto/hisilicon/sec/sec_algs.c
+++ b/drivers/crypto/hisilicon/sec/sec_algs.c
@@ -808,13 +808,6 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 	 * more refined but this is unlikely to happen so no need.
 	 */
 
-	/* Cleanup - all elements in pointer arrays have been coppied */
-	kfree(splits_in_nents);
-	kfree(splits_in);
-	kfree(splits_out_nents);
-	kfree(splits_out);
-	kfree(split_sizes);
-
 	/* Grab a big lock for a long time to avoid concurrency issues */
 	mutex_lock(&queue->queuelock);
 
@@ -829,13 +822,13 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 	     (!queue->havesoftqueue ||
 	      kfifo_avail(&queue->softqueue) > steps)) ||
 	    !list_empty(&ctx->backlog)) {
+		ret = -EBUSY;
 		if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
 			list_add_tail(&sec_req->backlog_head, &ctx->backlog);
 			mutex_unlock(&queue->queuelock);
-			return -EBUSY;
+			goto out;
 		}
 
-		ret = -EBUSY;
 		mutex_unlock(&queue->queuelock);
 		goto err_free_elements;
 	}
@@ -844,7 +837,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
 	if (ret)
 		goto err_free_elements;
 
-	return -EINPROGRESS;
+	ret = -EINPROGRESS;
+out:
+	/* Cleanup - all elements in pointer arrays have been copied */
+	kfree(splits_in_nents);
+	kfree(splits_in);
+	kfree(splits_out_nents);
+	kfree(splits_out);
+	kfree(split_sizes);
+	return ret;
 
 err_free_elements:
 	list_for_each_entry_safe(el, temp, &sec_req->elements, head) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] crypto: hisilicon - A couple of fixes
  2018-11-05 12:35 [PATCH 0/2] crypto: hisilicon - A couple of fixes John Garry
  2018-11-05 12:35 ` [PATCH 1/2] crypto: hisilicon - Fix NULL dereference for same dst and src John Garry
  2018-11-05 12:35 ` [PATCH 2/2] crypto: hisilicon - Fix reference after free of memories on error path John Garry
@ 2018-11-09  9:43 ` Herbert Xu
  2 siblings, 0 replies; 4+ messages in thread
From: Herbert Xu @ 2018-11-09  9:43 UTC (permalink / raw)
  To: John Garry; +Cc: davem, Jonathan.Cameron, linux-crypto, linux-kernel, linuxarm

On Mon, Nov 05, 2018 at 08:35:13PM +0800, John Garry wrote:
> This patchset fixes a couple of issues I discovered while attempting to
> bringup the driver.
> 
> John Garry (2):
>   crypto: hisilicon -  Fix NULL dereference for same dst and src
>   crypto: hisilicon -  Fix reference after free of memories on error
>  path
> 
>  drivers/crypto/hisilicon/sec/sec_algs.c | 31 +++++++++++++++++--------------
>  1 file changed, 17 insertions(+), 14 deletions(-)

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-11-09  9:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-05 12:35 [PATCH 0/2] crypto: hisilicon - A couple of fixes John Garry
2018-11-05 12:35 ` [PATCH 1/2] crypto: hisilicon - Fix NULL dereference for same dst and src John Garry
2018-11-05 12:35 ` [PATCH 2/2] crypto: hisilicon - Fix reference after free of memories on error path John Garry
2018-11-09  9:43 ` [PATCH 0/2] crypto: hisilicon - A couple of fixes Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).