Subject: [alpine-aports] [PATCH] testing/php7.1: fix php bug #74105

From: Valery Kartel <[email-masked]>
Date: Wed, 22 Feb 2017 23:58:30 +0200

backport of php upstream patch
fix getrandom() call for images, deployed on kernel < 3.17
https://github.com/php/php-src/pull/2385
---
 testing/php7.1/APKBUILD        |   6 +-
 testing/php7.1/getrandom.patch | 128 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 2 deletions(-)
 create mode 100644 testing/php7.1/getrandom.patch

diff --git a/testing/php7.1/APKBUILD b/testing/php7.1/APKBUILD
index 7634b69c52..451dc8c42c 100644
--- a/testing/php7.1/APKBUILD
+++ b/testing/php7.1/APKBUILD
@@ -2,7 +2,7 @@
 # Maintainer: Valery Kartel <[email-masked]>
 pkgname=php7.1
 pkgver=7.1.2
-pkgrel=0
+pkgrel=1
 _apiver=20160303
 _suffix=${pkgname#php}
 _pkgreal=${pkgname%$_suffix}
@@ -28,6 +28,7 @@ source="http://php.net/distributions/$_pkgreal-$pkgver.tar.bz2
 	$_pkgreal-fpm.patch.in
 	includedir.patch.in
 	install-pear.patch
+	getrandom.patch
 	"
 # unimplemented extensions: com_dotnet interbase oci8 pdo_firebird pdo_oci
 _extensions="bcmath bz2 calendar ctype curl dba dom enchant exif ftp gd gettext gmp iconv imap:1 intl json
@@ -412,4 +413,5 @@ b25c0bcaae4ddc7e001a6484423dec48be8735168dc3ab7471f5a57ce631273f11514c924b368ff8
 809e584304365412ecf80eb2ebb613439342e9a1faf36d0b04c76e60b1bf1345812799a16ffad76dbd3aa5f00c55329a051b308e451301d6e8d673813e37856b  php-fpm.initd.in
 2b3d60e4c57929a7bc1875c83472a6be1b7695a623893d108f905e742fe72ddf7fec7bf7a42b332ac33304434620a0317fd79d4ad707be886825d4b0fd96b938  php-fpm.patch.in
 c7841eef58e1203cb1eb97efff96427d560c1c8d9945286e95dbecc7ccac20e0a29a333194032af9696961c317876d5b971f282644167ba6fe7135e9ac86447e  includedir.patch.in
-f1177cbf6b1f44402f421c3d317aab1a2a40d0b1209c11519c1158df337c8945f3a313d689c939768584f3e4edbe52e8bd6103fb6777462326a9d94e8ab1f505  install-pear.patch"
+f1177cbf6b1f44402f421c3d317aab1a2a40d0b1209c11519c1158df337c8945f3a313d689c939768584f3e4edbe52e8bd6103fb6777462326a9d94e8ab1f505  install-pear.patch
+da012a82c00f9dfd3b6e446e2c3e7da597079e9b428f53ca61b5e216c304e3c02e953a5fc2759e516580cb98f08e86b0f5b33ea8df99a8003ae33fcb431463b4  getrandom.patch"
diff --git a/testing/php7.1/getrandom.patch b/testing/php7.1/getrandom.patch
new file mode 100644
index 0000000000..205a226b4e
--- /dev/null
+++ b/testing/php7.1/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
+ 
-- 
2.11.1

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---