Skip to content

Commit ddf18e3

Browse files
committed
Review
1 parent ac0c9ad commit ddf18e3

File tree

5 files changed

+62
-43
lines changed

5 files changed

+62
-43
lines changed

Zend/zend_alloc.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ static size_t _real_page_size = ZEND_MM_PAGE_SIZE;
149149
# define ZEND_MM_HEAP_PROTECTION 1 /* protect heap against corruptions */
150150
#endif
151151

152+
#if ZEND_MM_HEAP_PROTECTION
153+
/* Define ZEND_MM_MIN_USEABLE_BIN_SIZE to the size of two pointers */
154+
# if UINTPTR_MAX == UINT64_MAX
155+
# define ZEND_MM_MIN_USEABLE_BIN_SIZE 16
156+
# elif UINTPTR_MAX == UINT32_MAX
157+
# define ZEND_MM_MIN_USEABLE_BIN_SIZE 8
158+
# else
159+
# error
160+
# endif
161+
# if ZEND_MM_MIN_USEABLE_BIN_SIZE < ZEND_MM_MIN_SMALL_SIZE
162+
# error
163+
# endif
164+
#else /* ZEND_MM_HEAP_PROTECTION */
165+
# define ZEND_MM_MIN_USEABLE_BIN_SIZE ZEND_MM_MIN_SMALL_SIZE
166+
#endif /* ZEND_MM_HEAP_PROTECTION */
167+
152168
#ifndef ZEND_MM_CHECK
153169
# define ZEND_MM_CHECK(condition, message) do { \
154170
if (UNEXPECTED(!(condition))) { \
@@ -1336,7 +1352,7 @@ static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_he
13361352

13371353
static zend_always_inline void zend_mm_set_next_free_slot(zend_mm_heap *heap, uint32_t bin_num, zend_mm_free_slot *slot, zend_mm_free_slot *next)
13381354
{
1339-
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_SMALL_SIZE);
1355+
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE);
13401356

13411357
slot->next_free_slot = next;
13421358
ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, bin_num) = zend_mm_encode_free_slot(heap, next);
@@ -1419,7 +1435,7 @@ static zend_never_inline void *zend_mm_alloc_small_slow(zend_mm_heap *heap, uint
14191435

14201436
static zend_always_inline void *zend_mm_alloc_small(zend_mm_heap *heap, int bin_num ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
14211437
{
1422-
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_SMALL_SIZE);
1438+
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE);
14231439

14241440
#if ZEND_MM_STAT
14251441
do {
@@ -1441,7 +1457,7 @@ static zend_always_inline void *zend_mm_alloc_small(zend_mm_heap *heap, int bin_
14411457

14421458
static zend_always_inline void zend_mm_free_small(zend_mm_heap *heap, void *ptr, int bin_num)
14431459
{
1444-
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_SMALL_SIZE);
1460+
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE);
14451461

14461462
zend_mm_free_slot *p;
14471463

@@ -1493,8 +1509,8 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
14931509
{
14941510
void *ptr;
14951511
#if ZEND_MM_HEAP_PROTECTION
1496-
if (size < ZEND_MM_MIN_SMALL_SIZE) {
1497-
size = ZEND_MM_MIN_SMALL_SIZE;
1512+
if (size < ZEND_MM_MIN_USEABLE_BIN_SIZE) {
1513+
size = ZEND_MM_MIN_USEABLE_BIN_SIZE;
14981514
}
14991515
#endif /* ZEND_MM_HEAP_PROTECTION */
15001516
#if ZEND_DEBUG
@@ -1719,8 +1735,8 @@ static zend_always_inline void *zend_mm_realloc_heap(zend_mm_heap *heap, void *p
17191735
int page_num = (int)(page_offset / ZEND_MM_PAGE_SIZE);
17201736
zend_mm_page_info info = chunk->map[page_num];
17211737
#if ZEND_MM_HEAP_PROTECTION
1722-
if (size < ZEND_MM_MIN_SMALL_SIZE) {
1723-
size = ZEND_MM_MIN_SMALL_SIZE;
1738+
if (size < ZEND_MM_MIN_USEABLE_BIN_SIZE) {
1739+
size = ZEND_MM_MIN_USEABLE_BIN_SIZE;
17241740
}
17251741
#endif /* ZEND_MM_HEAP_PROTECTION */
17261742
#if ZEND_DEBUG
@@ -2759,14 +2775,16 @@ ZEND_API bool is_zend_ptr(const void *ptr)
27592775
# define ZEND_MM_CUSTOM_DEALLOCATOR(ptr)
27602776
#endif
27612777

2762-
# define _ZEND_BIN_ALLOCATOR(_num, _size, _elements, _pages, x, y) \
2778+
# define _ZEND_BIN_ALLOCATOR(_num, _size, _elements, _pages, _min_size, y) \
27632779
ZEND_API void* ZEND_FASTCALL _emalloc_ ## _size(void) { \
2764-
ZEND_ASSERT(_size >= ZEND_MM_MIN_SMALL_SIZE); \
27652780
ZEND_MM_CUSTOM_ALLOCATOR(_size); \
2781+
if (_size < _min_size) { \
2782+
return _emalloc_ ## _min_size(); \
2783+
} \
27662784
return zend_mm_alloc_small(AG(mm_heap), _num ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
27672785
}
27682786

2769-
ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR, x, y)
2787+
ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR, ZEND_MM_MIN_USEABLE_BIN_SIZE, y)
27702788

27712789
ZEND_API void* ZEND_FASTCALL _emalloc_large(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
27722790
{
@@ -2781,10 +2799,13 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size)
27812799
}
27822800

27832801
#if ZEND_DEBUG
2784-
# define _ZEND_BIN_FREE(_num, _size, _elements, _pages, x, y) \
2802+
# define _ZEND_BIN_FREE(_num, _size, _elements, _pages, _min_size, y) \
27852803
ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \
2786-
ZEND_ASSERT(_size >= ZEND_MM_MIN_SMALL_SIZE); \
27872804
ZEND_MM_CUSTOM_DEALLOCATOR(ptr); \
2805+
if (_size < _min_size) { \
2806+
_efree_ ## _min_size(ptr); \
2807+
return; \
2808+
} \
27882809
{ \
27892810
size_t page_offset = ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE); \
27902811
zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE); \
@@ -2796,10 +2817,13 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size)
27962817
} \
27972818
}
27982819
#else
2799-
# define _ZEND_BIN_FREE(_num, _size, _elements, _pages, x, y) \
2820+
# define _ZEND_BIN_FREE(_num, _size, _elements, _pages, _min_size, y) \
28002821
ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \
2801-
ZEND_ASSERT(_size >= ZEND_MM_MIN_SMALL_SIZE); \
28022822
ZEND_MM_CUSTOM_DEALLOCATOR(ptr); \
2823+
if (_size < _min_size) { \
2824+
_efree_ ## _min_size(ptr); \
2825+
return; \
2826+
} \
28032827
{ \
28042828
zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE); \
28052829
ZEND_MM_CHECK(chunk->heap == AG(mm_heap), "zend_mm_heap corrupted"); \
@@ -2808,7 +2832,7 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size)
28082832
}
28092833
#endif
28102834

2811-
ZEND_MM_BINS_INFO(_ZEND_BIN_FREE, x, y)
2835+
ZEND_MM_BINS_INFO(_ZEND_BIN_FREE, ZEND_MM_MIN_USEABLE_BIN_SIZE, y)
28122836

28132837
ZEND_API void ZEND_FASTCALL _efree_large(void *ptr, size_t size)
28142838
{

Zend/zend_alloc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ZEND_API ZEND_ATTRIBUTE_MALLOC void* ZEND_FASTCALL _emalloc_large(size_t size) Z
9090
ZEND_API ZEND_ATTRIBUTE_MALLOC void* ZEND_FASTCALL _emalloc_huge(size_t size) ZEND_ATTRIBUTE_ALLOC_SIZE(1);
9191

9292
# define _ZEND_BIN_ALLOCATOR_SELECTOR_START(_num, _size, _elements, _pages, size, y) \
93-
((size <= _size && _size >= ZEND_MM_MIN_SMALL_SIZE) ? _emalloc_ ## _size() :
93+
((size <= _size) ? _emalloc_ ## _size() :
9494
# define _ZEND_BIN_ALLOCATOR_SELECTOR_END(_num, _size, _elements, _pages, size, y) \
9595
)
9696

@@ -115,7 +115,7 @@ ZEND_API void ZEND_FASTCALL _efree_large(void *, size_t size);
115115
ZEND_API void ZEND_FASTCALL _efree_huge(void *, size_t size);
116116

117117
# define _ZEND_BIN_DEALLOCATOR_SELECTOR_START(_num, _size, _elements, _pages, ptr, size) \
118-
if (size <= _size && _size >= ZEND_MM_MIN_SMALL_SIZE) { _efree_ ## _size(ptr); } else
118+
if (size <= _size) { _efree_ ## _size(ptr); } else
119119

120120
# define ZEND_DEALLOCATOR(ptr, size) \
121121
ZEND_MM_BINS_INFO(_ZEND_BIN_DEALLOCATOR_SELECTOR_START, ptr, size) \

Zend/zend_alloc_sizes.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,12 @@
1919
#ifndef ZEND_ALLOC_SIZES_H
2020
#define ZEND_ALLOC_SIZES_H
2121

22-
#ifndef ZEND_MM_HEAP_PROTECTION
23-
# define ZEND_MM_HEAP_PROTECTION 1 /* protect heap against corruptions */
24-
#endif
25-
2622
#define ZEND_MM_CHUNK_SIZE ((size_t) (2 * 1024 * 1024)) /* 2 MB */
2723
#define ZEND_MM_PAGE_SIZE (4 * 1024) /* 4 KB */
2824
#define ZEND_MM_PAGES (ZEND_MM_CHUNK_SIZE / ZEND_MM_PAGE_SIZE) /* 512 */
2925
#define ZEND_MM_FIRST_PAGE (1)
3026

31-
#if ZEND_MM_HEAP_PROTECTION
32-
# define ZEND_MM_MIN_SMALL_SIZE (sizeof(void*) * 2)
33-
#else
34-
# define ZEND_MM_MIN_SMALL_SIZE 8
35-
#endif
27+
#define ZEND_MM_MIN_SMALL_SIZE 8
3628
#define ZEND_MM_MAX_SMALL_SIZE 3072
3729
#define ZEND_MM_MAX_LARGE_SIZE (ZEND_MM_CHUNK_SIZE - (ZEND_MM_PAGE_SIZE * ZEND_MM_FIRST_PAGE))
3830

Zend/zend_portability.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,16 @@ char *alloca();
269269
# define ZEND_ATTRIBUTE_UNUSED
270270
#endif
271271

272+
#if ZEND_GCC_VERSION >= 3003 || __has_attribute(nonnull)
273+
/* All pointer arguments must be non-null */
274+
# define ZEND_ATTRIBUTE_NONNULL __attribute__((nonnull))
275+
/* Specified arguments must be non-null (1-based) */
276+
# define ZEND_ATTRIBUTE_NONNULL_ARGS(...) __attribute__((nonnull(__VA_ARGS__)))
277+
#else
278+
# define ZEND_ATTRIBUTE_NONNULL
279+
# define ZEND_ATTRIBUTE_NONNULL_ARGS(...)
280+
#endif
281+
272282
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
273283
# define ZEND_COLD __attribute__((cold))
274284
# ifdef __OPTIMIZE__

ext/random/csprng.c

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,17 @@
6262
# include <sanitizer/msan_interface.h>
6363
#endif
6464

65-
#define php_random_bytes_error(...) do { \
66-
if (errstr) { \
67-
snprintf(errstr, errstr_size, __VA_ARGS__); \
68-
} \
69-
} while (0)
70-
7165
#ifndef PHP_WIN32
7266
static zend_atomic_int random_fd = ZEND_ATOMIC_INT_INITIALIZER(-1);
7367
#endif
7468

69+
ZEND_ATTRIBUTE_NONNULL
7570
PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, size_t errstr_size)
7671
{
7772
#ifdef PHP_WIN32
7873
/* Defer to CryptGenRandom on Windows */
7974
if (php_win32_get_random_bytes(bytes, size) == FAILURE) {
80-
php_random_bytes_error("Failed to retrieve randomness from the operating system (BCryptGenRandom)");
75+
snprintf(errstr, errstr_size, "Failed to retrieve randomness from the operating system (BCryptGenRandom)");
8176
return FAILURE;
8277
}
8378
#elif HAVE_COMMONCRYPTO_COMMONRANDOM_H
@@ -88,7 +83,7 @@ PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, s
8883
* the vast majority of the time, it works fine ; but better make sure we catch failures
8984
*/
9085
if (CCRandomGenerateBytes(bytes, size) != kCCSuccess) {
91-
php_random_bytes_error("Failed to retrieve randomness from the operating system (CCRandomGenerateBytes)");
86+
snprintf(errstr, errstr_size, "Failed to retrieve randomness from the operating system (CCRandomGenerateBytes)");
9287
return FAILURE;
9388
}
9489
#elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001 && __NetBSD_Version__ < 1000000000) || \
@@ -162,9 +157,9 @@ PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, s
162157
fd = open("/dev/urandom", O_RDONLY);
163158
if (fd < 0) {
164159
if (errno != 0) {
165-
php_random_bytes_error("Cannot open /dev/urandom: %s", strerror(errno));
160+
snprintf(errstr, errstr_size, "Cannot open /dev/urandom: %s", strerror(errno));
166161
} else {
167-
php_random_bytes_error("Cannot open /dev/urandom");
162+
snprintf(errstr, errstr_size, "Cannot open /dev/urandom");
168163
}
169164
return FAILURE;
170165
}
@@ -180,9 +175,9 @@ PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, s
180175
) {
181176
close(fd);
182177
if (errno != 0) {
183-
php_random_bytes_error("Error reading from /dev/urandom: %s", strerror(errno));
178+
snprintf(errstr, errstr_size, "Error reading from /dev/urandom: %s", strerror(errno));
184179
} else {
185-
php_random_bytes_error("Error reading from /dev/urandom");
180+
snprintf(errstr, errstr_size, "Error reading from /dev/urandom");
186181
}
187182
return FAILURE;
188183
}
@@ -201,9 +196,9 @@ PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, s
201196

202197
if (n <= 0) {
203198
if (errno != 0) {
204-
php_random_bytes_error("Could not gather sufficient random data: %s", strerror(errno));
199+
snprintf(errstr, errstr_size, "Could not gather sufficient random data: %s", strerror(errno));
205200
} else {
206-
php_random_bytes_error("Could not gather sufficient random data");
201+
snprintf(errstr, errstr_size, "Could not gather sufficient random data");
207202
}
208203
return FAILURE;
209204
}
@@ -219,9 +214,7 @@ PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, s
219214
PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw)
220215
{
221216
char errstr[128];
222-
223-
zend_result result = php_random_bytes_ex(bytes, size,
224-
should_throw ? errstr : NULL, should_throw ? sizeof(errstr) : 0);
217+
zend_result result = php_random_bytes_ex(bytes, size, errstr, sizeof(errstr));
225218

226219
if (result == FAILURE && should_throw) {
227220
zend_throw_exception(random_ce_Random_RandomException, errstr, 0);

0 commit comments

Comments
 (0)