@@ -1274,39 +1274,31 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
1274
1274
return crng_ready () ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM ;
1275
1275
}
1276
1276
1277
- static int write_pool (const char __user * ubuf , size_t len )
1277
+ static ssize_t write_pool (struct iov_iter * iter )
1278
1278
{
1279
- size_t block_len ;
1280
- int ret = 0 ;
1281
1279
u8 block [BLAKE2S_BLOCK_SIZE ];
1280
+ ssize_t ret = 0 ;
1281
+ size_t copied ;
1282
1282
1283
- while ( len ) {
1284
- block_len = min ( len , sizeof ( block )) ;
1285
- if ( copy_from_user ( block , ubuf , block_len )) {
1286
- ret = - EFAULT ;
1287
- goto out ;
1288
- }
1289
- len -= block_len ;
1290
- ubuf += block_len ;
1291
- mix_pool_bytes ( block , block_len ) ;
1283
+ if ( unlikely (! iov_iter_count ( iter )))
1284
+ return 0 ;
1285
+
1286
+ for (;;) {
1287
+ copied = copy_from_iter ( block , sizeof ( block ), iter ) ;
1288
+ ret += copied ;
1289
+ mix_pool_bytes ( block , copied ) ;
1290
+ if (! iov_iter_count ( iter ) || copied != sizeof ( block ))
1291
+ break ;
1292
1292
cond_resched ();
1293
1293
}
1294
1294
1295
- out :
1296
1295
memzero_explicit (block , sizeof (block ));
1297
- return ret ;
1296
+ return ret ? ret : - EFAULT ;
1298
1297
}
1299
1298
1300
- static ssize_t random_write (struct file * file , const char __user * ubuf ,
1301
- size_t len , loff_t * ppos )
1299
+ static ssize_t random_write_iter (struct kiocb * kiocb , struct iov_iter * iter )
1302
1300
{
1303
- int ret ;
1304
-
1305
- ret = write_pool (ubuf , len );
1306
- if (ret )
1307
- return ret ;
1308
-
1309
- return (ssize_t )len ;
1301
+ return write_pool (iter );
1310
1302
}
1311
1303
1312
1304
static ssize_t urandom_read_iter (struct kiocb * kiocb , struct iov_iter * iter )
@@ -1345,9 +1337,8 @@ static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
1345
1337
1346
1338
static long random_ioctl (struct file * f , unsigned int cmd , unsigned long arg )
1347
1339
{
1348
- int size , ent_count ;
1349
1340
int __user * p = (int __user * )arg ;
1350
- int retval ;
1341
+ int ent_count ;
1351
1342
1352
1343
switch (cmd ) {
1353
1344
case RNDGETENTCNT :
@@ -1364,20 +1355,32 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
1364
1355
return - EINVAL ;
1365
1356
credit_init_bits (ent_count );
1366
1357
return 0 ;
1367
- case RNDADDENTROPY :
1358
+ case RNDADDENTROPY : {
1359
+ struct iov_iter iter ;
1360
+ struct iovec iov ;
1361
+ ssize_t ret ;
1362
+ int len ;
1363
+
1368
1364
if (!capable (CAP_SYS_ADMIN ))
1369
1365
return - EPERM ;
1370
1366
if (get_user (ent_count , p ++ ))
1371
1367
return - EFAULT ;
1372
1368
if (ent_count < 0 )
1373
1369
return - EINVAL ;
1374
- if (get_user (size , p ++ ))
1370
+ if (get_user (len , p ++ ))
1371
+ return - EFAULT ;
1372
+ ret = import_single_range (WRITE , p , len , & iov , & iter );
1373
+ if (unlikely (ret ))
1374
+ return ret ;
1375
+ ret = write_pool (& iter );
1376
+ if (unlikely (ret < 0 ))
1377
+ return ret ;
1378
+ /* Since we're crediting, enforce that it was all written into the pool. */
1379
+ if (unlikely (ret != len ))
1375
1380
return - EFAULT ;
1376
- retval = write_pool ((const char __user * )p , size );
1377
- if (retval < 0 )
1378
- return retval ;
1379
1381
credit_init_bits (ent_count );
1380
1382
return 0 ;
1383
+ }
1381
1384
case RNDZAPENTCNT :
1382
1385
case RNDCLEARPOOL :
1383
1386
/* No longer has any effect. */
@@ -1403,7 +1406,7 @@ static int random_fasync(int fd, struct file *filp, int on)
1403
1406
1404
1407
const struct file_operations random_fops = {
1405
1408
.read_iter = random_read_iter ,
1406
- .write = random_write ,
1409
+ .write_iter = random_write_iter ,
1407
1410
.poll = random_poll ,
1408
1411
.unlocked_ioctl = random_ioctl ,
1409
1412
.compat_ioctl = compat_ptr_ioctl ,
@@ -1413,7 +1416,7 @@ const struct file_operations random_fops = {
1413
1416
1414
1417
const struct file_operations urandom_fops = {
1415
1418
.read_iter = urandom_read_iter ,
1416
- .write = random_write ,
1419
+ .write_iter = random_write_iter ,
1417
1420
.unlocked_ioctl = random_ioctl ,
1418
1421
.compat_ioctl = compat_ptr_ioctl ,
1419
1422
.fasync = random_fasync ,
0 commit comments