diff options
author | Theodore Ts'o <tytso@mit.edu> | 2019-05-22 12:02:16 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2019-05-26 00:11:49 -0400 |
commit | 58be0106c5306b939b07b4b8bf00669a20593f4b (patch) | |
tree | d606e36cf1ad7fc39da0a980db7d718f3730b875 /drivers/char/random.c | |
parent | b7d5dc21072cda7124d13eae2aefb7343ef94197 (diff) |
random: fix soft lockup when trying to read from an uninitialized blocking pool
Fixes: eb9d1bf079bb: "random: only read from /dev/random after its pool has received 128 bits"
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r-- | drivers/char/random.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index a42b3d764da8..5d5ea4ce1442 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -772,8 +772,11 @@ retry: | |||
772 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | 772 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
773 | goto retry; | 773 | goto retry; |
774 | 774 | ||
775 | if (has_initialized) | 775 | if (has_initialized) { |
776 | r->initialized = 1; | 776 | r->initialized = 1; |
777 | wake_up_interruptible(&random_read_wait); | ||
778 | kill_fasync(&fasync, SIGIO, POLL_IN); | ||
779 | } | ||
777 | 780 | ||
778 | trace_credit_entropy_bits(r->name, nbits, | 781 | trace_credit_entropy_bits(r->name, nbits, |
779 | entropy_count >> ENTROPY_SHIFT, _RET_IP_); | 782 | entropy_count >> ENTROPY_SHIFT, _RET_IP_); |
@@ -789,6 +792,13 @@ retry: | |||
789 | entropy_bits = r->entropy_count >> ENTROPY_SHIFT; | 792 | entropy_bits = r->entropy_count >> ENTROPY_SHIFT; |
790 | } | 793 | } |
791 | 794 | ||
795 | /* initialize the blocking pool if necessary */ | ||
796 | if (entropy_bits >= random_read_wakeup_bits && | ||
797 | !other->initialized) { | ||
798 | schedule_work(&other->push_work); | ||
799 | return; | ||
800 | } | ||
801 | |||
792 | /* should we wake readers? */ | 802 | /* should we wake readers? */ |
793 | if (entropy_bits >= random_read_wakeup_bits && | 803 | if (entropy_bits >= random_read_wakeup_bits && |
794 | wq_has_sleeper(&random_read_wait)) { | 804 | wq_has_sleeper(&random_read_wait)) { |
@@ -1936,8 +1946,8 @@ _random_read(int nonblock, char __user *buf, size_t nbytes) | |||
1936 | return -EAGAIN; | 1946 | return -EAGAIN; |
1937 | 1947 | ||
1938 | wait_event_interruptible(random_read_wait, | 1948 | wait_event_interruptible(random_read_wait, |
1939 | ENTROPY_BITS(&input_pool) >= | 1949 | blocking_pool.initialized && |
1940 | random_read_wakeup_bits); | 1950 | (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)); |
1941 | if (signal_pending(current)) | 1951 | if (signal_pending(current)) |
1942 | return -ERESTARTSYS; | 1952 | return -ERESTARTSYS; |
1943 | } | 1953 | } |