@@ -470,7 +470,7 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
470
470
/* Defer to CryptGenRandom on Windows */
471
471
if (php_win32_get_random_bytes (bytes , size ) == FAILURE ) {
472
472
if (should_throw ) {
473
- zend_throw_exception (zend_ce_exception , "Could not gather sufficient random data " , 0 );
473
+ zend_throw_exception (zend_ce_exception , "Failed to retrieve randomness from the operating system (BCryptGenRandom) " , 0 );
474
474
}
475
475
return FAILURE ;
476
476
}
@@ -483,7 +483,7 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
483
483
*/
484
484
if (CCRandomGenerateBytes (bytes , size ) != kCCSuccess ) {
485
485
if (should_throw ) {
486
- zend_throw_exception (zend_ce_exception , "Error generating bytes " , 0 );
486
+ zend_throw_exception (zend_ce_exception , "Failed to retrieve randomness from the operating system (CCRandomGenerateBytes) " , 0 );
487
487
}
488
488
return FAILURE ;
489
489
}
@@ -496,6 +496,8 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
496
496
/* Linux getrandom(2) syscall or FreeBSD/DragonFlyBSD getrandom(2) function*/
497
497
/* Keep reading until we get enough entropy */
498
498
while (read_bytes < size ) {
499
+ errno = 0 ;
500
+
499
501
/* Below, (bytes + read_bytes) is pointer arithmetic.
500
502
501
503
bytes read_bytes size
@@ -522,7 +524,7 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
522
524
/* Try again */
523
525
continue ;
524
526
} else {
525
- /* If the syscall fails, fall back to reading from /dev/urandom */
527
+ /* If the syscall fails, fall back to reading from /dev/urandom */
526
528
break ;
527
529
}
528
530
}
@@ -539,15 +541,22 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
539
541
struct stat st ;
540
542
541
543
if (fd < 0 ) {
544
+ errno = 0 ;
542
545
# if HAVE_DEV_URANDOM
543
546
fd = open ("/dev/urandom" , O_RDONLY );
544
547
# endif
545
548
if (fd < 0 ) {
546
549
if (should_throw ) {
547
- zend_throw_exception (zend_ce_exception , "Cannot open source device" , 0 );
550
+ if (errno != 0 ) {
551
+ zend_throw_exception_ex (zend_ce_exception , 0 , "Cannot open /dev/urandom: %s" , strerror (errno ));
552
+ } else {
553
+ zend_throw_exception_ex (zend_ce_exception , 0 , "Cannot open /dev/urandom" );
554
+ }
548
555
}
549
556
return FAILURE ;
550
557
}
558
+
559
+ errno = 0 ;
551
560
/* Does the file exist and is it a character device? */
552
561
if (fstat (fd , & st ) != 0 ||
553
562
# ifdef S_ISNAM
@@ -558,14 +567,19 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
558
567
) {
559
568
close (fd );
560
569
if (should_throw ) {
561
- zend_throw_exception (zend_ce_exception , "Error reading from source device" , 0 );
570
+ if (errno != 0 ) {
571
+ zend_throw_exception_ex (zend_ce_exception , 0 , "Error reading from /dev/urandom: %s" , strerror (errno ));
572
+ } else {
573
+ zend_throw_exception_ex (zend_ce_exception , 0 , "Error reading from /dev/urandom" );
574
+ }
562
575
}
563
576
return FAILURE ;
564
577
}
565
578
RANDOM_G (random_fd ) = fd ;
566
579
}
567
580
568
581
for (read_bytes = 0 ; read_bytes < size ; read_bytes += (size_t ) n ) {
582
+ errno = 0 ;
569
583
n = read (fd , bytes + read_bytes , size - read_bytes );
570
584
if (n <= 0 ) {
571
585
break ;
@@ -574,7 +588,11 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
574
588
575
589
if (read_bytes < size ) {
576
590
if (should_throw ) {
577
- zend_throw_exception (zend_ce_exception , "Could not gather sufficient random data" , 0 );
591
+ if (errno != 0 ) {
592
+ zend_throw_exception_ex (zend_ce_exception , 0 , "Could not gather sufficient random data: %s" , strerror (errno ));
593
+ } else {
594
+ zend_throw_exception_ex (zend_ce_exception , 0 , "Could not gather sufficient random data" );
595
+ }
578
596
}
579
597
return FAILURE ;
580
598
}
0 commit comments