aboutsummaryrefslogtreecommitdiffstats
path: root/community/php7/getrandom.patch
diff options
context:
space:
mode:
authorValery Kartel <valery.kartel@gmail.com>2017-02-22 23:56:53 +0200
committerTimo Teräs <timo.teras@iki.fi>2017-02-23 07:30:31 +0000
commit20bcce774e8053510a4245944e8d759e36745ebe (patch)
tree7caff7dea97c322c4c8141ab1a15047135f11261 /community/php7/getrandom.patch
parent431936ce663de7637512c1eeeb5be35a12a270a8 (diff)
downloadaports-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.patch128
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
+