php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch Fix-Multi-Thread-Allocation-Alignment-Memory-Failure for Reproducible crash Bug #77194

Patch version 2018-11-29 16:46 UTC

Return to Bug #77194 | Download this patch
Patch Revisions:

Developer: svbussww@126.com

--- zend_alloc.c	2018-11-06 18:33:06.000000000 +0800
+++ zend_alloc2.c	2018-11-29 16:38:24.984304800 +0800
@@ -422,9 +422,7 @@
 
 static void *zend_mm_mmap_fixed(void *addr, size_t size)
 {
-#ifdef _WIN32
-	return VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
-#else
+#ifndef _WIN32
 	/* MAP_FIXED leads to discarding of the old mapping, so it can't be used. */
 	void *ptr = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON /*| MAP_POPULATE | MAP_HUGETLB*/, -1, 0);
 
@@ -445,14 +443,14 @@
 #endif
 }
 
-static void *zend_mm_mmap(size_t size)
+static void *zend_mm_mmap(size_t size, size_t alignment)
 {
 #ifdef _WIN32
-	void *ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+	void *ptr = _aligned_malloc(size, alignment);
 
 	if (ptr == NULL) {
 #if ZEND_MM_ERROR
-		stderr_last_error("VirtualAlloc() failed");
+		stderr_last_error("aligned_malloc() failed");
 #endif
 		return NULL;
 	}
@@ -484,11 +482,7 @@
 static void zend_mm_munmap(void *addr, size_t size)
 {
 #ifdef _WIN32
-	if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
-#if ZEND_MM_ERROR
-		stderr_last_error("VirtualFree() failed");
-#endif
-	}
+	_aligned_free(addr);
 #else
 	if (munmap(addr, size) != 0) {
 #if ZEND_MM_ERROR
@@ -706,32 +700,22 @@
 
 static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
 {
-	void *ptr = zend_mm_mmap(size);
+	void *ptr = zend_mm_mmap(size, alignment);
 
 	if (ptr == NULL) {
 		return NULL;
-	} else if (ZEND_MM_ALIGNED_OFFSET(ptr, alignment) == 0) {
+	}
+#ifndef _WIN32
+	else if (ZEND_MM_ALIGNED_OFFSET(ptr, alignment) == 0) {
 #ifdef MADV_HUGEPAGE
 	    madvise(ptr, size, MADV_HUGEPAGE);
 #endif
-		return ptr;
 	} else {
 		size_t offset;
 
 		/* chunk has to be aligned */
 		zend_mm_munmap(ptr, size);
-		ptr = zend_mm_mmap(size + alignment - REAL_PAGE_SIZE);
-#ifdef _WIN32
-		offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment);
-		zend_mm_munmap(ptr, size + alignment - REAL_PAGE_SIZE);
-		ptr = zend_mm_mmap_fixed((void*)((char*)ptr + (alignment - offset)), size);
-		offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment);
-		if (offset != 0) {
-			zend_mm_munmap(ptr, size);
-			return NULL;
-		}
-		return ptr;
-#else
+		ptr = zend_mm_mmap(size + alignment - REAL_PAGE_SIZE, 0);
 		offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment);
 		if (offset != 0) {
 			offset = alignment - offset;
@@ -745,9 +729,9 @@
 # ifdef MADV_HUGEPAGE
 	    madvise(ptr, size, MADV_HUGEPAGE);
 # endif
-#endif
-		return ptr;
 	}
+#endif
+	return ptr;
 }
 
 static void *zend_mm_chunk_alloc(zend_mm_heap *heap, size_t size, size_t alignment)
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sat Dec 05 22:01:23 2020 UTC