@@ -1274,39 +1274,31 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
12741274 return crng_ready () ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM ;
12751275}
12761276
1277- static int write_pool (const char __user * ubuf , size_t len )
1277+ static ssize_t write_pool (struct iov_iter * iter )
12781278{
1279- size_t block_len ;
1280- int ret = 0 ;
12811279 u8 block [BLAKE2S_BLOCK_SIZE ];
1280+ ssize_t ret = 0 ;
1281+ size_t copied ;
12821282
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 ;
12921292 cond_resched ();
12931293 }
12941294
1295- out :
12961295 memzero_explicit (block , sizeof (block ));
1297- return ret ;
1296+ return ret ? ret : - EFAULT ;
12981297}
12991298
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 )
13021300{
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 );
13101302}
13111303
13121304static 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)
13451337
13461338static long random_ioctl (struct file * f , unsigned int cmd , unsigned long arg )
13471339{
1348- int size , ent_count ;
13491340 int __user * p = (int __user * )arg ;
1350- int retval ;
1341+ int ent_count ;
13511342
13521343 switch (cmd ) {
13531344 case RNDGETENTCNT :
@@ -1364,20 +1355,32 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
13641355 return - EINVAL ;
13651356 credit_init_bits (ent_count );
13661357 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+
13681364 if (!capable (CAP_SYS_ADMIN ))
13691365 return - EPERM ;
13701366 if (get_user (ent_count , p ++ ))
13711367 return - EFAULT ;
13721368 if (ent_count < 0 )
13731369 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 ))
13751380 return - EFAULT ;
1376- retval = write_pool ((const char __user * )p , size );
1377- if (retval < 0 )
1378- return retval ;
13791381 credit_init_bits (ent_count );
13801382 return 0 ;
1383+ }
13811384 case RNDZAPENTCNT :
13821385 case RNDCLEARPOOL :
13831386 /* No longer has any effect. */
@@ -1403,7 +1406,7 @@ static int random_fasync(int fd, struct file *filp, int on)
14031406
14041407const struct file_operations random_fops = {
14051408 .read_iter = random_read_iter ,
1406- .write = random_write ,
1409+ .write_iter = random_write_iter ,
14071410 .poll = random_poll ,
14081411 .unlocked_ioctl = random_ioctl ,
14091412 .compat_ioctl = compat_ptr_ioctl ,
@@ -1413,7 +1416,7 @@ const struct file_operations random_fops = {
14131416
14141417const struct file_operations urandom_fops = {
14151418 .read_iter = urandom_read_iter ,
1416- .write = random_write ,
1419+ .write_iter = random_write_iter ,
14171420 .unlocked_ioctl = random_ioctl ,
14181421 .compat_ioctl = compat_ptr_ioctl ,
14191422 .fasync = random_fasync ,
0 commit comments