Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15b66cd5 authored by Herbert Xu's avatar Herbert Xu
Browse files

hwrng: core - Fix current_rng init/cleanup race yet again



The kref solution is still buggy because we were only focusing
on the register/unregister race.  The same race affects the
setting of current_rng through sysfs.

This patch fixes it by using kref_get_unless_zero.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 77584ee5
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -105,7 +105,6 @@ static inline void cleanup_rng(struct kref *kref)
static void set_current_rng(struct hwrng *rng)
{
	BUG_ON(!mutex_is_locked(&rng_mutex));
	kref_get(&rng->ref);
	current_rng = rng;
}

@@ -150,6 +149,9 @@ static void put_rng(struct hwrng *rng)

static inline int hwrng_init(struct hwrng *rng)
{
	if (kref_get_unless_zero(&rng->ref))
		goto skip_init;

	if (rng->init) {
		int ret;

@@ -157,6 +159,11 @@ static inline int hwrng_init(struct hwrng *rng)
		if (ret)
			return ret;
	}

	kref_init(&rng->ref);
	reinit_completion(&rng->cleanup_done);

skip_init:
	add_early_randomness(rng);

	current_quality = rng->quality ? : default_quality;
@@ -467,6 +474,9 @@ int hwrng_register(struct hwrng *rng)
			goto out_unlock;
	}

	init_completion(&rng->cleanup_done);
	complete(&rng->cleanup_done);

	old_rng = current_rng;
	err = 0;
	if (!old_rng) {
@@ -494,8 +504,6 @@ int hwrng_register(struct hwrng *rng)
		add_early_randomness(rng);
	}

	init_completion(&rng->cleanup_done);

out_unlock:
	mutex_unlock(&rng_mutex);
out: