Messages in this thread Patch in this message | | | Subject | [PATCH] random: wait for system_wq before pushing entropy into output pools | From | Konstantin Khlebnikov <> | Date | Thu, 20 Nov 2014 16:54:21 +0400 |
| |
First prototype of tool which injects random delays in random places (implemented on top of kernel address sanitizer by Andrey Ryabinin) have caught race right at the first try.
credit_entropy_bits() schedules work for pushing entropy from one pool into another too early, when system_wq isn't yet created. It's called from add_interrupt_randomness, so this path starts working right after enabling interrupts in start_kernel, but system workqueues are initialized much later in early_initcall(init_workqueues). It's impossible to create them earlier because threads have to be forked from kthreadd.
This patch skips pushing if system_wq isn't here yet. Delaying this till SYSTEM_RUNNING state might lead to significant lost of precious entropy.
Signed-off-by: Konstantin Khlebnikov <k.khlebnikov@samsung.com> Reported-and-tested-by: Andrey Ryabinin <a.ryabinin@samsung.com> --- drivers/char/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c index 04645c0..d4a684f 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -683,7 +683,7 @@ retry: * full. */ if (entropy_bits > random_write_wakeup_bits && - r->initialized && + system_wq && r->initialized && r->entropy_total >= 2*random_read_wakeup_bits) { static struct entropy_store *last = &blocking_pool; struct entropy_store *other = &blocking_pool; @@ -695,7 +695,7 @@ retry: last = other; if (last->entropy_count <= 3 * last->poolinfo->poolfracbits / 4) { - schedule_work(&last->push_work); + queue_work(system_wq, &last->push_work); r->entropy_total = 0; } }
| |