Skip to content

Commit c591f02

Browse files
committed
Fix bug #69403 and other int overflows
1 parent be9b2a9 commit c591f02

File tree

3 files changed

+25
-16
lines changed

3 files changed

+25
-16
lines changed

Zend/zend_alloc.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ static void zend_mm_random(unsigned char *buf, size_t size) /* {{{ */
980980
int has_context = 0;
981981

982982
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
983-
/* Could mean that the key container does not exist, let try
983+
/* Could mean that the key container does not exist, let try
984984
again by asking for a new one */
985985
if (GetLastError() == NTE_BAD_KEYSET) {
986986
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
@@ -1344,7 +1344,7 @@ static int zend_mm_check_ptr(zend_mm_heap *heap, void *ptr, int silent ZEND_FILE
13441344
}
13451345
if (!silent) {
13461346
TSRMLS_FETCH();
1347-
1347+
13481348
zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
13491349
zend_debug_alloc_output("---------------------------------------\n");
13501350
zend_debug_alloc_output("%s(%d) : Block "PTR_FMT" status:\n" ZEND_FILE_LINE_RELAY_CC, ptr);
@@ -2171,7 +2171,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
21712171
#if ZEND_MM_CACHE
21722172
if (ZEND_MM_SMALL_SIZE(true_size)) {
21732173
size_t index = ZEND_MM_BUCKET_INDEX(true_size);
2174-
2174+
21752175
if (heap->cache[index] != NULL) {
21762176
zend_mm_free_block *best_fit;
21772177
zend_mm_free_block **cache;
@@ -2184,7 +2184,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
21842184
heap->cache[index] = best_fit->prev_free_block;
21852185
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
21862186
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
2187-
2187+
21882188
ptr = ZEND_MM_DATA_OF(best_fit);
21892189

21902190
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
@@ -2466,7 +2466,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
24662466
: "%0"(res),
24672467
"rm"(size),
24682468
"rm"(offset));
2469-
2469+
24702470
if (UNEXPECTED(overflow)) {
24712471
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
24722472
return 0;
@@ -2575,21 +2575,21 @@ ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
25752575

25762576
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
25772577
{
2578-
int length;
2578+
size_t length;
25792579
char *p;
25802580
#ifdef ZEND_SIGNALS
25812581
TSRMLS_FETCH();
25822582
#endif
25832583

25842584
HANDLE_BLOCK_INTERRUPTIONS();
25852585

2586-
length = strlen(s)+1;
2587-
p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2586+
length = strlen(s);
2587+
p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
25882588
if (UNEXPECTED(p == NULL)) {
25892589
HANDLE_UNBLOCK_INTERRUPTIONS();
25902590
return p;
25912591
}
2592-
memcpy(p, s, length);
2592+
memcpy(p, s, length+1);
25932593
HANDLE_UNBLOCK_INTERRUPTIONS();
25942594
return p;
25952595
}
@@ -2603,7 +2603,7 @@ ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_
26032603

26042604
HANDLE_BLOCK_INTERRUPTIONS();
26052605

2606-
p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2606+
p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
26072607
if (UNEXPECTED(p == NULL)) {
26082608
HANDLE_UNBLOCK_INTERRUPTIONS();
26092609
return p;
@@ -2624,7 +2624,7 @@ ZEND_API char *zend_strndup(const char *s, uint length)
26242624

26252625
HANDLE_BLOCK_INTERRUPTIONS();
26262626

2627-
p = (char *) malloc(length+1);
2627+
p = (char *) malloc(safe_address(length, 1, 1));
26282628
if (UNEXPECTED(p == NULL)) {
26292629
HANDLE_UNBLOCK_INTERRUPTIONS();
26302630
return p;

Zend/zend_operators.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,14 +1264,19 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
12641264
zend_error(E_ERROR, "String size overflow");
12651265
}
12661266

1267-
Z_STRVAL_P(result) = erealloc(Z_STRVAL_P(result), res_len+1);
1267+
Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1);
12681268

12691269
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
12701270
Z_STRVAL_P(result)[res_len]=0;
12711271
Z_STRLEN_P(result) = res_len;
12721272
} else {
12731273
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
1274-
char *buf = (char *) emalloc(length + 1);
1274+
char *buf;
1275+
1276+
if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
1277+
zend_error(E_ERROR, "String size overflow");
1278+
}
1279+
buf = (char *) safe_emalloc(length, 1, 1);
12751280

12761281
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
12771282
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
@@ -2067,7 +2072,7 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
20672072
} else if (ret2!=IS_DOUBLE) {
20682073
if (oflow1) {
20692074
ZVAL_LONG(result, oflow1);
2070-
return;
2075+
return;
20712076
}
20722077
dval2 = (double) lval2;
20732078
} else if (dval1 == dval2 && !zend_finite(dval1)) {

ext/standard/string.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
| license@php.net so we can mail you a copy immediately. |
1414
+----------------------------------------------------------------------+
1515
| Authors: Rasmus Lerdorf <rasmus@php.net> |
16-
| Stig Sæther Bakken <ssb@php.net> |
16+
| Stig S�ther Bakken <ssb@php.net> |
1717
| Zeev Suraski <zeev@zend.com> |
1818
+----------------------------------------------------------------------+
1919
*/
@@ -1443,7 +1443,7 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen
14431443
}
14441444
#if defined(PHP_WIN32) || defined(NETWARE)
14451445
/* Catch relative paths in c:file.txt style. They're not to confuse
1446-
with the NTFS streams. This part ensures also, that no drive
1446+
with the NTFS streams. This part ensures also, that no drive
14471447
letter traversing happens. */
14481448
} else if ((*c == ':' && (c - comp == 1))) {
14491449
if (state == 0) {
@@ -4949,6 +4949,10 @@ PHP_FUNCTION(str_repeat)
49494949

49504950
/* Initialize the result string */
49514951
result_len = input_len * mult;
4952+
if(result_len > INT_MAX) {
4953+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, maximum %d allowed", INT_MAX);
4954+
RETURN_EMPTY_STRING();
4955+
}
49524956
result = (char *)safe_emalloc(input_len, mult, 1);
49534957

49544958
/* Heavy optimization for situations where input string is 1 byte long */

0 commit comments

Comments
 (0)