mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] hwrng: cctrng - fix destination offset in cctrng_read()
@ 2026-10-15 10:39 Thorsten Blum
  2026-10-26  5:55 ` [PATCH] hwrng: cctrng - Lock read and writer of circular buffer Herbert Xu
  2026-11-06 11:26 ` [PATCH] hwrng: cctrng - fix destination offset in cctrng_read() Herbert Xu
  0 siblings, 2 replies; 3+ messages in thread
From: Thorsten Blum @ 2026-10-15 10:39 UTC (permalink / raw)
  To: Hadar Gat, Olivia Mackall, Herbert Xu
  Cc: Thorsten Blum, linux-crypto, linux-kernel

cctrng_read() copies random data in two steps when a read wraps around
the end of the circular buffer.

Use the correct destination offset for the second copy instead of
overwriting the start of the destination buffer.

Fixes: a583ed310bb6 ("hwrng: cctrng - introduce Arm CryptoCell driver")
Cc: stable@vger.kernel.org
Signed-off-by: Thorsten Blum <blum@kernel.org>
---
 drivers/char/hw_random/cctrng.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c
index a6925211c3b5..e070581237e5 100644
--- a/drivers/char/hw_random/cctrng.c
+++ b/drivers/char/hw_random/cctrng.c
@@ -237,7 +237,7 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 		cnt_w = CIRC_CNT(drvdata->circ.head,
 				 drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
 		size = min((cnt_w<<2), left);
-		memcpy(data, &(buf[drvdata->circ.tail]), size);
+		memcpy(data + copied, &buf[drvdata->circ.tail], size);
 		copied += size;
 		circ_idx_inc(&drvdata->circ.tail, size);
 	}

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

* [PATCH] hwrng: cctrng - Lock read and writer of circular buffer
  2026-10-15 10:39 [PATCH] hwrng: cctrng - fix destination offset in cctrng_read() Thorsten Blum
@ 2026-10-26  5:55 ` Herbert Xu
  2026-11-06 11:26 ` [PATCH] hwrng: cctrng - fix destination offset in cctrng_read() Herbert Xu
  1 sibling, 0 replies; 3+ messages in thread
From: Herbert Xu @ 2026-10-26  5:55 UTC (permalink / raw)
  To: Thorsten Blum; +Cc: Hadar Gat, Olivia Mackall, linux-crypto, linux-kernel

On Thu, Oct 15, 2026 at 12:39:34PM +0200, Thorsten Blum wrote:
> cctrng_read() copies random data in two steps when a read wraps around
> the end of the circular buffer.
> 
> Use the correct destination offset for the second copy instead of
> overwriting the start of the destination buffer.
> 
> Fixes: a583ed310bb6 ("hwrng: cctrng - introduce Arm CryptoCell driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Thorsten Blum <blum@kernel.org>
> ---
>  drivers/char/hw_random/cctrng.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Sashiko complained about the lack of memory barries in the circular
buffer code.  This is taking a spinlock on the read-path, so it might
as well do it for both reading and writing.

I've also changed it to a mutex and added support for the wait flag.

---8<---
The circular buffer handling in cctrng is buggy as it doesn't use
any synchronisation mechanism between the reader and the writer.

As this isn't performance-critical, simply change it to use a mutex
that covers both reading and writing.

While adding an inclusion for linux/err.h and linux/mutex.h, also
sort the headers alphabetically to avoid potential duplicates.

Fixes: a583ed310bb6 ("hwrng: cctrng - introduce Arm CryptoCell driver")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c
index 03401ee59a8e..ef49e0195ee9 100644
--- a/drivers/char/hw_random/cctrng.c
+++ b/drivers/char/hw_random/cctrng.c
@@ -1,21 +1,23 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (C) 2019-2020 ARM Limited or its affiliates. */
 
-#include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/circ_buf.h>
 #include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/fips.h>
+#include <linux/kernel.h>
 #include <linux/hw_random.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irqreturn.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/irqreturn.h>
 #include <linux/workqueue.h>
-#include <linux/circ_buf.h>
-#include <linux/completion.h>
-#include <linux/of.h>
-#include <linux/bitfield.h>
-#include <linux/fips.h>
 
 #include "cctrng.h"
 
@@ -68,8 +70,8 @@ struct cctrng_drvdata {
 	/* pending_hw - 1 when HW is pending, 0 when it is idle */
 	atomic_t pending_hw;
 
-	/* protects against multiple concurrent consumers of data_buf */
-	spinlock_t read_lock;
+	/* protects data_buf */
+	struct mutex lock;
 };
 
 
@@ -213,11 +215,8 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 	size_t size;
 	size_t left;
 
-	if (!spin_trylock(&drvdata->read_lock)) {
-		/* concurrent consumers from data_buf cannot be served */
-		dev_dbg_ratelimited(dev, "unable to hold lock\n");
-		return 0;
-	}
+	if (mutex_lock_interruptible(&drvdata->lock))
+		return -ERESTARTSYS;
 
 	/* copy till end of data buffer (without wrap back) */
 	cnt_w = CIRC_CNT_TO_END(drvdata->circ.head,
@@ -237,7 +236,7 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 		circ_idx_inc(&drvdata->circ.tail, size);
 	}
 
-	spin_unlock(&drvdata->read_lock);
+	mutex_unlock(&drvdata->lock);
 
 	if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
 		if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
@@ -347,6 +346,7 @@ static void cc_trng_compwork_handler(struct work_struct *w)
 	}
 
 	/* read EHR data from registers */
+	mutex_lock(&drvdata->lock);
 	for (i = 0; i < CC_TRNG_EHR_IN_WORDS; i++) {
 		/* calc word ptr in data_buf */
 		u32 *buf = (u32 *)drvdata->circ.buf;
@@ -358,6 +358,7 @@ static void cc_trng_compwork_handler(struct work_struct *w)
 		 * returned, restart the entropy collection.
 		 */
 		if (buf[drvdata->circ.head] == 0) {
+			mutex_unlock(&drvdata->lock);
 			dev_dbg(dev, "Got 0 value in EHR. active_rosc %u\n",
 				drvdata->active_rosc);
 			goto next_rosc;
@@ -365,6 +366,7 @@ static void cc_trng_compwork_handler(struct work_struct *w)
 
 		circ_idx_inc(&drvdata->circ.head, 1<<2);
 	}
+	mutex_unlock(&drvdata->lock);
 
 	atomic_set(&drvdata->pending_hw, 0);
 
@@ -499,7 +501,7 @@ static int cctrng_probe(struct platform_device *pdev)
 
 	INIT_WORK(&drvdata->compwork, cc_trng_compwork_handler);
 	INIT_WORK(&drvdata->startwork, cc_trng_startwork_handler);
-	spin_lock_init(&drvdata->read_lock);
+	mutex_init(&drvdata->lock);
 
 	/* register the driver isr function */
 	rc = devm_request_irq(dev, irq, cc_isr, IRQF_SHARED, "cctrng", drvdata);
-- 
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] 3+ messages in thread

* Re: [PATCH] hwrng: cctrng - fix destination offset in cctrng_read()
  2026-10-15 10:39 [PATCH] hwrng: cctrng - fix destination offset in cctrng_read() Thorsten Blum
  2026-10-26  5:55 ` [PATCH] hwrng: cctrng - Lock read and writer of circular buffer Herbert Xu
@ 2026-11-06 11:26 ` Herbert Xu
  1 sibling, 0 replies; 3+ messages in thread
From: Herbert Xu @ 2026-11-06 11:26 UTC (permalink / raw)
  To: Thorsten Blum; +Cc: Hadar Gat, Olivia Mackall, linux-crypto, linux-kernel

On Thu, Oct 15, 2026 at 12:39:34PM +0200, Thorsten Blum wrote:
> cctrng_read() copies random data in two steps when a read wraps around
> the end of the circular buffer.
> 
> Use the correct destination offset for the second copy instead of
> overwriting the start of the destination buffer.
> 
> Fixes: a583ed310bb6 ("hwrng: cctrng - introduce Arm CryptoCell driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Thorsten Blum <blum@kernel.org>
> ---
>  drivers/char/hw_random/cctrng.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Patch 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] 3+ messages in thread

end of thread, other threads:[~2026-11-06 11:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-15 10:39 [PATCH] hwrng: cctrng - fix destination offset in cctrng_read() Thorsten Blum
2026-10-26  5:55 ` [PATCH] hwrng: cctrng - Lock read and writer of circular buffer Herbert Xu
2026-11-06 11:26 ` [PATCH] hwrng: cctrng - fix destination offset in cctrng_read() Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®