[PATCH 2/2] [RFC] hwrng: fix khwrng registration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If we have a register/unregister too fast, it can happen that the kthread
is not yet started when kthread_stop is called, and this seems to leave a
corrupted or uninitialized kthread struct. This is detected by the
WARN_ON at kernel/kthread.c:75 and later causes a page domain fault.

Wait for the kthread to start the same way as drivers/base/devtmpfs.c
does wait for kdevtmpfs thread to start using setup_done completion.

Signed-off-by: Marek Vasut <marex@xxxxxxx>
---
This is a follow-up on second part of V2 of work by Luca Dariz:
https://lore.kernel.org/all/AM6PR06MB5400DAFE0551F1D468B728FBAB889@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
---
Cc: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx>
Cc: Harald Freudenberger <freude@xxxxxxxxxxxxx>
Cc: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Cc: Li Zhijian <lizhijian@xxxxxxxxxxx>
Cc: Masahiro Yamada <masahiroy@xxxxxxxxxx>
Cc: Olivia Mackall <olivia@xxxxxxxxxxx>
Cc: linux-crypto@xxxxxxxxxxxxxxx
---
 drivers/char/hw_random/core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 5be26f4e9d975..bb1f4ba602b1d 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -55,6 +55,7 @@ MODULE_PARM_DESC(default_quality,
 static void drop_current_rng(void);
 static int hwrng_init(struct hwrng *rng);
 static int hwrng_fillfn(void *unused);
+static DECLARE_COMPLETION(setup_done);
 
 static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
 			       int wait);
@@ -472,6 +473,7 @@ static int hwrng_fillfn(void *unused)
 	size_t entropy, entropy_credit = 0; /* in 1/1024 of a bit */
 	long rc;
 
+	complete(&setup_done);
 	while (!kthread_should_stop()) {
 		unsigned short quality;
 		struct hwrng *rng;
@@ -669,13 +671,15 @@ static int __init hwrng_modinit(void)
 	if (ret)
 		goto err_miscdev;
 
-	hwrng_fill = kthread_create(hwrng_fillfn, NULL, "hwrng");
+	hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
 	if (IS_ERR(hwrng_fill)) {
 		ret = PTR_ERR(hwrng_fill);
 		pr_err("hwrng_fill thread creation failed (%d)\n", ret);
 		goto err_kthread;
 	}
 
+	wait_for_completion(&setup_done);
+
 	ret = kthread_park(hwrng_fill);
 	if (ret)
 		goto err_park;
-- 
2.45.2





[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]
  Powered by Linux