From d830a1f6f0534a07df5d22b35ab0842f979bea4f Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Fri, 24 Dec 2021 18:27:24 +0000 Subject: [PATCH] random extension macOs handling update. Not such as fix but taking more precautions. Indeed, the arc4random has two little flaws in this platform, one already caught upfront by the extension (ie size 0), also internal use of ccrng_generate which can silently fail in few rare cases. Closes #7824. --- NEWS | 3 ++- ext/standard/config.m4 | 6 ++++++ ext/standard/random.c | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index fa89c45c695..f9632c86d90 100644 --- a/NEWS +++ b/NEWS @@ -35,7 +35,8 @@ PHP NEWS syntaxe of a valid file). (Dmitry) - Standard: - . Fixed the crypt_sha256/512 api build with clang > 12. (David Carier) + . Fixed the crypt_sha256/512 api build with clang > 12. (David Carlier) + . Uses CCRandomGenerateBytes instead of arc4random_buf on macOs. (David Carlier). 07 Jul 2022, PHP 8.0.21 diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 301540db58d..d43cf8d9475 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -385,6 +385,12 @@ dnl Check for arc4random on BSD systems dnl AC_CHECK_DECLS([arc4random_buf]) +dnl +dnl Check for CCRandomGenerateBytes +dnl header absent in previous macOs releases +dnl +AC_CHECK_HEADERS([CommonCrypto/CommonRandom.h]) + dnl dnl Check for argon2 dnl diff --git a/ext/standard/random.c b/ext/standard/random.c index 526347f5658..64fd63de778 100644 --- a/ext/standard/random.c +++ b/ext/standard/random.c @@ -35,6 +35,10 @@ # include # endif #endif +#if HAVE_COMMONCRYPTO_COMMONRANDOM_H +# include +# include +#endif #if __has_feature(memory_sanitizer) # include @@ -94,6 +98,19 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw) } return FAILURE; } +#elif HAVE_COMMONCRYPTO_COMMONRANDOM_H + /* + * Purposely prioritized upon arc4random_buf for modern macOs releases + * arc4random api on this platform uses `ccrng_generate` which returns + * a status but silented to respect the "no fail" arc4random api interface + * the vast majority of the time, it works fine ; but better make sure we catch failures + */ + if (CCRandomGenerateBytes(bytes, size) != kCCSuccess) { + if (should_throw) { + zend_throw_exception(zend_ce_exception, "Error generating bytes", 0); + } + return FAILURE; + } #elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001) || defined(__APPLE__)) arc4random_buf(bytes, size); #else