From 04d2905fb55f9bb1c32ce2ed110f50a37b35c5a2 Mon Sep 17 00:00:00 2001 From: Sascha Schumann Date: Thu, 24 Apr 2003 03:35:06 +0000 Subject: [PATCH] add safe_emalloc --- Zend/zend_alloc.c | 28 ++++++++++++++++++++++++++++ Zend/zend_alloc.h | 3 +++ Zend/zend_multiply.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 Zend/zend_multiply.h diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 48eb22b3cd..9df3fe7888 100644 --- a/Zend/zend_alloc.c +++ b/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) { diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 9c024e4f18..dff79a8948 100644 --- a/Zend/zend_alloc.h +++ b/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) diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h new file mode 100644 index 0000000000..d8304c26e3 --- /dev/null +++ b/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 | + +----------------------------------------------------------------------+ +*/ + +#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 -- 2.50.1