From: Dmitry Stogov Date: Mon, 18 Dec 2006 11:39:34 +0000 (+0000) Subject: Fixed random generation of cookies and canaries X-Git-Tag: RELEASE_1_0_0RC1~670 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d7652abef84c23e281cc528b0673867045fd169;p=php Fixed random generation of cookies and canaries --- diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index d6330a689c..6dae2a01b3 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -390,3 +390,10 @@ AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[ ]) +AC_MSG_CHECKING(whether /dev/urandom exists) +if test -r "/dev/urandom" && test -c "/dev/urandom"; then + AC_DEFINE([HAVE_DEV_URANDOM], 1, [Define if the target system has /dev/urandom device]) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 1bd6731da7..2b74d990b1 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -32,6 +32,13 @@ # include #endif +#ifdef ZEND_WIN32 +# define _WIN32_WINNT 0x0400 +# include +# include +#endif + + #ifndef ZEND_USE_MALLOC_MM # define ZEND_USE_MALLOC_MM ZEND_DEBUG #endif @@ -712,6 +719,53 @@ static void zend_mm_free_cache(zend_mm_heap *heap) } #endif +static void zend_mm_random(unsigned char *buf, size_t size) +{ + size_t i = 0; + unsigned char t; + +#ifdef ZEND_WIN32 + HCRYPTPROV hCryptProv; + + if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) { + do { + BOOL ret = CryptGenRandom(hCryptProv, size, buf); + CryptReleaseContext(hCryptProv, 0); + if (ret) { + while (i < size && buf[i] != 0) { + i++; + } + if (i == size) { + return; + } + } + } while (0); + } +#elif defined(HAVE_DEV_URANDOM) + int fd = open("/dev/urandom", 0); + + if (fd >= 0) { + if (read(fd, buf, size) == size) { + while (i < size && buf[i] != 0) { + i++; + } + if (i == size) { + close(fd); + return; + } + } + close(fd); + } +#endif + t = (unsigned char)getpid(); + while (i < size) { + do { + buf[i] = ((unsigned char)rand()) ^ t; + } while (buf[i] == 0); + t = buf[i++] << 1; + } +} + /* Notes: * - This function may alter the block_sizes values to match platform alignment * - This function does *not* perform sanity checks on the arguments @@ -739,36 +793,15 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, #if ZEND_MM_HEAP_PROTECTION if (_mem_block_start_magic == 0) { - int r; - do { - r = rand(); - } while (!(r&0xff000000) || - !(r&0x00ff0000) || - !(r&0x0000ff00) || - !(r&0x000000ff)); - _mem_block_start_magic = r; + zend_mm_random((unsigned char*)&_mem_block_start_magic, sizeof(_mem_block_start_magic)); } if (_mem_block_end_magic == 0) { - int r; - do { - r = rand(); - } while (!(r&0xff000000) || - !(r&0x00ff0000) || - !(r&0x0000ff00) || - !(r&0x000000ff)); - _mem_block_end_magic = r; + zend_mm_random((unsigned char*)&_mem_block_end_magic, sizeof(_mem_block_end_magic)); } #endif #if ZEND_MM_COOKIES if (_zend_mm_cookie == 0) { - int r; - do { - r = rand(); - } while (!(r&0xff000000) || - !(r&0x00ff0000) || - !(r&0x0000ff00) || - !(r&0x000000ff)); - _zend_mm_cookie = r; + zend_mm_random((unsigned char*)&_zend_mm_cookie, sizeof(_zend_mm_cookie)); } #endif