summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/random.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index dc2f2c24c6ec..b691b9d59503 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1274,7 +1274,7 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}
-static ssize_t write_pool(struct iov_iter *iter)
+static ssize_t write_pool_user(struct iov_iter *iter)
{
u8 block[BLAKE2S_BLOCK_SIZE];
ssize_t ret = 0;
@@ -1289,7 +1289,13 @@ static ssize_t write_pool(struct iov_iter *iter)
mix_pool_bytes(block, copied);
if (!iov_iter_count(iter) || copied != sizeof(block))
break;
- cond_resched();
+
+ BUILD_BUG_ON(PAGE_SIZE % sizeof(block) != 0);
+ if (ret % PAGE_SIZE == 0) {
+ if (signal_pending(current))
+ break;
+ cond_resched();
+ }
}
memzero_explicit(block, sizeof(block));
@@ -1298,7 +1304,7 @@ static ssize_t write_pool(struct iov_iter *iter)
static ssize_t random_write_iter(struct kiocb *kiocb, struct iov_iter *iter)
{
- return write_pool(iter);
+ return write_pool_user(iter);
}
static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
@@ -1372,7 +1378,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
ret = import_single_range(WRITE, p, len, &iov, &iter);
if (unlikely(ret))
return ret;
- ret = write_pool(&iter);
+ ret = write_pool_user(&iter);
if (unlikely(ret < 0))
return ret;
/* Since we're crediting, enforce that it was all written into the pool. */