diff options
author | Valery Kartel <valery.kartel@gmail.com> | 2017-02-22 23:56:53 +0200 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2017-02-23 07:30:31 +0000 |
commit | 20bcce774e8053510a4245944e8d759e36745ebe (patch) | |
tree | 7caff7dea97c322c4c8141ab1a15047135f11261 /community/php7/getrandom.patch | |
parent | 431936ce663de7637512c1eeeb5be35a12a270a8 (diff) | |
download | aports-20bcce774e8053510a4245944e8d759e36745ebe.tar.bz2 aports-20bcce774e8053510a4245944e8d759e36745ebe.tar.xz |
community/php7: fix php bug #74105
backport of php upstream patch
fix getrandom() call for images, deployed on kernel < 3.17
https://github.com/php/php-src/pull/2385
Diffstat (limited to 'community/php7/getrandom.patch')
-rw-r--r-- | community/php7/getrandom.patch | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/community/php7/getrandom.patch b/community/php7/getrandom.patch new file mode 100644 index 0000000000..205a226b4e --- /dev/null +++ b/community/php7/getrandom.patch @@ -0,0 +1,128 @@ +--- a/ext/standard/random.c ++++ b/ext/standard/random.c +@@ -93,14 +93,13 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw) + } + #elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001)) + arc4random_buf(bytes, size); +-#elif defined(__linux__) && defined(SYS_getrandom) +- /* Linux getrandom(2) syscall */ ++#else + size_t read_bytes = 0; +- size_t amount_to_read = 0; + ssize_t n; +- ++#if defined(__linux__) && defined(SYS_getrandom) ++ /* Linux getrandom(2) syscall */ + /* Keep reading until we get enough entropy */ +- do { ++ while (read_bytes < size) { + /* Below, (bytes + read_bytes) is pointer arithmetic. + + bytes read_bytes size +@@ -110,11 +109,17 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw) + amount_to_read + + */ +- amount_to_read = size - read_bytes; ++ size_t amount_to_read = size - read_bytes; + n = syscall(SYS_getrandom, bytes + read_bytes, amount_to_read, 0); + + if (n == -1) { +- if (errno == EINTR || errno == EAGAIN) { ++ if (errno == ENOSYS) { ++ /* This can happen if PHP was compiled against a newer kernel where getrandom() ++ * is available, but then runs on an older kernel without getrandom(). If this ++ * happens we simply fall back to reading from /dev/urandom. */ ++ ZEND_ASSERT(read_bytes == 0); ++ break; ++ } else if (errno == EINTR || errno == EAGAIN) { + /* Try again */ + continue; + } +@@ -130,53 +135,52 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw) + } + + read_bytes += (size_t) n; +- } while (read_bytes < size); +-#else +- int fd = RANDOM_G(fd); +- struct stat st; +- size_t read_bytes = 0; +- ssize_t n; ++ } ++#endif ++ if (read_bytes < size) { ++ int fd = RANDOM_G(fd); ++ struct stat st; + +- if (fd < 0) { ++ if (fd < 0) { + #if HAVE_DEV_URANDOM +- fd = open("/dev/urandom", O_RDONLY); ++ fd = open("/dev/urandom", O_RDONLY); + #endif +- if (fd < 0) { +- if (should_throw) { +- zend_throw_exception(zend_ce_exception, "Cannot open source device", 0); ++ if (fd < 0) { ++ if (should_throw) { ++ zend_throw_exception(zend_ce_exception, "Cannot open source device", 0); ++ } ++ return FAILURE; + } +- return FAILURE; +- } +- /* Does the file exist and is it a character device? */ +- if (fstat(fd, &st) != 0 || ++ /* Does the file exist and is it a character device? */ ++ if (fstat(fd, &st) != 0 || + # ifdef S_ISNAM +- !(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) ++ !(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) + # else +- !S_ISCHR(st.st_mode) ++ !S_ISCHR(st.st_mode) + # endif +- ) { +- close(fd); +- if (should_throw) { +- zend_throw_exception(zend_ce_exception, "Error reading from source device", 0); ++ ) { ++ close(fd); ++ if (should_throw) { ++ zend_throw_exception(zend_ce_exception, "Error reading from source device", 0); ++ } ++ return FAILURE; + } +- return FAILURE; ++ RANDOM_G(fd) = fd; + } +- RANDOM_G(fd) = fd; +- } + +- while (read_bytes < size) { +- n = read(fd, bytes + read_bytes, size - read_bytes); +- if (n <= 0) { +- break; ++ for (read_bytes = 0; read_bytes < size; read_bytes += (size_t) n) { ++ n = read(fd, bytes + read_bytes, size - read_bytes); ++ if (n <= 0) { ++ break; ++ } + } +- read_bytes += n; +- } + +- if (read_bytes < size) { +- if (should_throw) { +- zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); ++ if (read_bytes < size) { ++ if (should_throw) { ++ zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); ++ } ++ return FAILURE; + } +- return FAILURE; + } + #endif + |