--- x/drivers/char/hw_random/core.c +++ y/drivers/char/hw_random/core.c @@ -213,6 +213,7 @@ static ssize_t rng_dev_read(struct file int err = 0; int bytes_read, len; struct hwrng *rng; + char rnd[32]; while (size) { rng = get_current_rng(); @@ -245,24 +246,28 @@ static ssize_t rng_dev_read(struct file err = -EAGAIN; goto out_unlock_reading; } + mutex_unlock(&reading_mutex); } else { len = data_avail; if (len > size) len = size; + if (len > 32) + len = 32; data_avail -= len; - if (copy_to_user(buf + ret, rng_buffer + data_avail, - len)) { + memcpy(rnd, rng_buffer + data_avail, len); + mutex_unlock(&reading_mutex); + + if (copy_to_user(buf + ret, rnd, len)) { err = -EFAULT; - goto out_unlock_reading; + goto out_put; } size -= len; ret += len; } - mutex_unlock(&reading_mutex); put_rng(rng); if (need_resched())