]> granicus.if.org Git - php/commitdiff
add safe_realloc
authorStanislav Malyshev <stas@php.net>
Fri, 16 Feb 2007 18:06:28 +0000 (18:06 +0000)
committerStanislav Malyshev <stas@php.net>
Fri, 16 Feb 2007 18:06:28 +0000 (18:06 +0000)
Zend/zend_alloc.c
Zend/zend_alloc.h

index 10aa388448719a353ceac96532daf797a25676e5..ca5e84a8af2fdfee7d651bd271dbec9c8946d20e 100644 (file)
@@ -1520,6 +1520,7 @@ static void _zend_mm_free_int(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND
        if (!ZEND_MM_VALID_PTR(p)) {
                return;
        }
+
        mm_block = ZEND_MM_HEADER_OF(p);
        size = ZEND_MM_BLOCK_SIZE(mm_block);
        ZEND_MM_CHECK_PROTECTION(mm_block);
@@ -1947,6 +1948,57 @@ ZEND_API void *_safe_malloc(size_t nmemb, size_t size, size_t offset)
        return 0;
 }
 
+ZEND_API void *_safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
+{
+
+       if (nmemb < LONG_MAX
+                       && size < LONG_MAX
+                       && offset < LONG_MAX
+                       && nmemb >= 0
+                       && size >= 0
+                       && offset >= 0) {
+               long lval;
+               double dval;
+               int use_dval;
+
+               ZEND_SIGNED_MULTIPLY_LONG(nmemb, size, lval, dval, use_dval);
+
+               if (!use_dval
+                               && lval < (long) (LONG_MAX - offset)) {
+                       return erealloc_rel(ptr, lval + offset);
+               }
+       }
+
+       zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
+       return 0;
+}
+
+ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset)
+{
+
+       if (nmemb < LONG_MAX
+                       && size < LONG_MAX
+                       && offset < LONG_MAX
+                       && nmemb >= 0
+                       && size >= 0
+                       && offset >= 0) {
+               long lval;
+               double dval;
+               int use_dval;
+
+               ZEND_SIGNED_MULTIPLY_LONG(nmemb, size, lval, dval, use_dval);
+
+               if (!use_dval
+                               && lval < (long) (LONG_MAX - offset)) {
+                       return perealloc(ptr, lval + offset, 1);
+               }
+       }
+
+       zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
+       return 0;
+}
+
+
 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
        void *p;
index 8bc28b7cc853c7fe9ba0851384acba720359476b..397a0c09b5a0150de417795729980d4b69437735 100644 (file)
@@ -46,6 +46,8 @@ ZEND_API void *_safe_malloc(size_t nmemb, size_t size, size_t offset) ZEND_ATTRI
 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
+ZEND_API void *_safe_erelloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
+ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
 ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
 ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
 ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
@@ -56,6 +58,7 @@ ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_
 #define efree(ptr)                                                     _efree((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
 #define ecalloc(nmemb, size)                           _ecalloc((nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
 #define erealloc(ptr, size)                                    _erealloc((ptr), (size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
+#define safe_erealloc(ptr, nmemb, size, offset)        _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
 #define erealloc_recoverable(ptr, size)                _erealloc((ptr), (size), 1 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
 #define estrdup(s)                                                     _estrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
 #define estrndup(s, length)                                    _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
@@ -68,6 +71,7 @@ ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_
 #define ecalloc_rel(nmemb, size)                               _ecalloc((nmemb), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #define erealloc_rel(ptr, size)                                        _erealloc((ptr), (size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #define erealloc_recoverable_rel(ptr, size)            _erealloc((ptr), (size), 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
+#define safe_erealloc_rel(ptr, nmemb, size, offset)    _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #define estrdup_rel(s)                                                 _estrdup((s) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #define estrndup_rel(s, length)                                        _estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #define zend_mem_block_size_rel(ptr)                   _zend_mem_block_size((ptr) TSRMLS_CC ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
@@ -78,6 +82,7 @@ ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_
 #define pefree(ptr, persistent)  ((persistent)?free(ptr):efree(ptr))
 #define pecalloc(nmemb, size, persistent) ((persistent)?calloc((nmemb), (size)):ecalloc((nmemb), (size)))
 #define perealloc(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc((ptr), (size)))
+#define safe_perealloc(ptr, nmemb, size, offset, persistent)   ((persistent)?_safe_realloc((ptr), (nmemb), (size), (offset)):safe_erealloc((ptr), (nmemb), (size), (offset)))
 #define perealloc_recoverable(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc_recoverable((ptr), (size)))
 #define pestrdup(s, persistent) ((persistent)?strdup(s):estrdup(s))