Skip to content

Commit 1016df1

Browse files
author
Ilia Alshanetsky
committed
Various security fixes backported from 5.2
# part 1
1 parent fc45bcc commit 1016df1

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

Zend/zend_alloc.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,15 @@ static long mem_block_end_magic = MEM_BLOCK_END_MAGIC;
7272
#define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0)
7373
# endif
7474

75-
#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\
75+
#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \
76+
if (file) { \
77+
fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \
78+
} else { \
79+
fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \
80+
} \
81+
exit(1); \
82+
} \
83+
AG(allocated_memory) += rs;\
7684
if (AG(memory_limit)<AG(allocated_memory)) {\
7785
int php_mem_limit = AG(memory_limit); \
7886
AG(allocated_memory) -= rs; \
@@ -127,7 +135,7 @@ static long mem_block_end_magic = MEM_BLOCK_END_MAGIC;
127135
#endif
128136

129137
#define DECLARE_CACHE_VARS() \
130-
unsigned int real_size; \
138+
size_t real_size; \
131139
unsigned int cache_index
132140

133141
#define REAL_SIZE(size) ((size+7) & ~0x7)
@@ -142,12 +150,16 @@ static long mem_block_end_magic = MEM_BLOCK_END_MAGIC;
142150

143151
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
144152
{
145-
zend_mem_header *p;
153+
zend_mem_header *p = NULL;
146154
DECLARE_CACHE_VARS();
147155
TSRMLS_FETCH();
148156

149157
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
150158

159+
if (size > INT_MAX || SIZE < size) {
160+
goto emalloc_error;
161+
}
162+
151163
#if !ZEND_DISABLE_MEMORY_CACHE
152164
if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
153165
p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]];
@@ -184,6 +196,8 @@ ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
184196
}
185197
#endif
186198

199+
emalloc_error:
200+
187201
HANDLE_BLOCK_INTERRUPTIONS();
188202

189203
if (!p) {
@@ -357,6 +371,13 @@ ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LIN
357371
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
358372

359373
HANDLE_BLOCK_INTERRUPTIONS();
374+
375+
if (size > INT_MAX || SIZE < size) {
376+
REMOVE_POINTER_FROM_LIST(p);
377+
p = NULL;
378+
goto erealloc_error;
379+
}
380+
360381
#if MEMORY_LIMIT
361382
CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size));
362383
if (AG(allocated_memory) > AG(allocated_memory_peak)) {
@@ -365,6 +386,7 @@ ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LIN
365386
#endif
366387
REMOVE_POINTER_FROM_LIST(p);
367388
p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
389+
erealloc_error:
368390
if (!p) {
369391
if (!allow_failure) {
370392
fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);

0 commit comments

Comments
 (0)