]> granicus.if.org Git - php/commitdiff
add safe_emalloc
authorSascha Schumann <sas@php.net>
Thu, 24 Apr 2003 03:35:06 +0000 (03:35 +0000)
committerSascha Schumann <sas@php.net>
Thu, 24 Apr 2003 03:35:06 +0000 (03:35 +0000)
Zend/zend_alloc.c
Zend/zend_alloc.h
Zend/zend_multiply.h [new file with mode: 0644]

index 48eb22b3cdb872d846aab540408854a71f7df10d..9df3fe78888d6f459dc7d559df63caf53919f628 100644 (file)
@@ -206,6 +206,34 @@ ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
        return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
 }
 
+#include "zend_multiply.h"
+
+ZEND_API void *_safe_emalloc(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_MAX - offset) {
+                       return emalloc_rel(lval + offset);
+               }
+       }
+
+       zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
+       return 0;
+}
+
+
 
 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
index 9c024e4f1824ac132c71772804c790fdb4e97f0e..dff79a89485fd863e5a6b7e74659329704f30064 100644 (file)
@@ -78,6 +78,7 @@ BEGIN_EXTERN_C()
 ZEND_API char *zend_strndup(const char *s, unsigned int length);
 
 ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
+ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
 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_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
@@ -86,6 +87,7 @@ ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZE
 
 /* Standard wrapper macros */
 #define emalloc(size)                                  _emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
+#define safe_emalloc(nmemb, size, offset)       _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
 #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)
@@ -95,6 +97,7 @@ ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZE
 
 /* Relay wrapper macros */
 #define emalloc_rel(size)                                      _emalloc((size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
+#define safe_emalloc_rel(nmemb, size, offset)   _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #define efree_rel(ptr)                                         _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
 #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)
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
new file mode 100644 (file)
index 0000000..d8304c2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 2003 Sascha Schumann                                   |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.00 of the Zend license,     |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.zend.com/license/2_00.txt.                                |
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@zend.com so we can mail you a copy immediately.              |
+   +----------------------------------------------------------------------+
+   | Author: Sascha Schumann <sascha@schumann.cx>                         |
+   +----------------------------------------------------------------------+
+*/
+
+#if defined(__i386__) && defined(__GNUC__)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {      \
+       __asm__ ("imul %3,%0\n"                                                                                 \
+               "adc $0,%1"                                                                                             \
+                       : "=r"(lval),"=r"(usedval)                                                              \
+                       : "0"(a), "r"(b), "1"(0));                                                              \
+       if (usedval) (dval) = (double) (a) * (double) (b);                              \
+} while (0)
+
+#else
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {      \
+       (dval) = (double) (a) * (double) (b);                                                   \
+                                                                                                                                       \
+       if ((dval) >= LONG_MAX || (dval) <= LONG_MIN) {                                 \
+               (usedval) = 1;                                                                                          \
+       } else {                                                                                                                \
+               (lval) = (a) * (b);                                                                                     \
+               (usedval) = 0;                                                                                          \
+       }                                                                                                                               \
+} while (0)
+
+#endif