Browse Source

add safe_emalloc

migration/unlabaled-1.3.2
Sascha Schumann 24 years ago
parent
commit
04d2905fb5
  1. 28
      Zend/zend_alloc.c
  2. 3
      Zend/zend_alloc.h
  3. 42
      Zend/zend_multiply.h

28
Zend/zend_alloc.c

@ -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)
{

3
Zend/zend_alloc.h

@ -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)

42
Zend/zend_multiply.h

@ -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
Loading…
Cancel
Save