Permalink
Browse files

add safe_emalloc

  • Loading branch information...
1 parent d2833dc commit 04d2905fb55f9bb1c32ce2ed110f50a37b35c5a2 Sascha Schumann committed Apr 24, 2003
Showing with 73 additions and 0 deletions.
  1. +28 −0 Zend/zend_alloc.c
  2. +3 −0 Zend/zend_alloc.h
  3. +42 −0 Zend/zend_multiply.h
View
@@ -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)
{
View
@@ -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)
View
@@ -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

0 comments on commit 04d2905

Please sign in to comment.