Skip to content

Commit 0a96aa6

Browse files
smalyshevJulien Pauli
authored andcommitted
Fix bug #69403 and other int overflows
1 parent bbe4b87 commit 0a96aa6

File tree

3 files changed

+24
-15
lines changed

3 files changed

+24
-15
lines changed

Zend/zend_alloc.c

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

986986
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
987-
/* Could mean that the key container does not exist, let try
987+
/* Could mean that the key container does not exist, let try
988988
again by asking for a new one */
989989
if (GetLastError() == NTE_BAD_KEYSET) {
990990
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
@@ -1348,7 +1348,7 @@ static int zend_mm_check_ptr(zend_mm_heap *heap, void *ptr, int silent ZEND_FILE
13481348
}
13491349
if (!silent) {
13501350
TSRMLS_FETCH();
1351-
1351+
13521352
zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
13531353
zend_debug_alloc_output("---------------------------------------\n");
13541354
zend_debug_alloc_output("%s(%d) : Block "PTR_FMT" status:\n" ZEND_FILE_LINE_RELAY_CC, ptr);
@@ -2175,7 +2175,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
21752175
#if ZEND_MM_CACHE
21762176
if (ZEND_MM_SMALL_SIZE(true_size)) {
21772177
size_t index = ZEND_MM_BUCKET_INDEX(true_size);
2178-
2178+
21792179
if (heap->cache[index] != NULL) {
21802180
zend_mm_free_block *best_fit;
21812181
zend_mm_free_block **cache;
@@ -2188,7 +2188,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
21882188
heap->cache[index] = best_fit->prev_free_block;
21892189
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
21902190
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
2191-
2191+
21922192
ptr = ZEND_MM_DATA_OF(best_fit);
21932193

21942194
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
@@ -2470,7 +2470,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
24702470
: "%0"(res),
24712471
"rm"(size),
24722472
"rm"(offset));
2473-
2473+
24742474
if (UNEXPECTED(overflow)) {
24752475
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
24762476
return 0;
@@ -2619,21 +2619,21 @@ ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
26192619

26202620
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
26212621
{
2622-
int length;
2622+
size_t length;
26232623
char *p;
26242624
#ifdef ZEND_SIGNALS
26252625
TSRMLS_FETCH();
26262626
#endif
26272627

26282628
HANDLE_BLOCK_INTERRUPTIONS();
26292629

2630-
length = strlen(s)+1;
2631-
p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2630+
length = strlen(s);
2631+
p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
26322632
if (UNEXPECTED(p == NULL)) {
26332633
HANDLE_UNBLOCK_INTERRUPTIONS();
26342634
return p;
26352635
}
2636-
memcpy(p, s, length);
2636+
memcpy(p, s, length+1);
26372637
HANDLE_UNBLOCK_INTERRUPTIONS();
26382638
return p;
26392639
}
@@ -2647,7 +2647,7 @@ ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_
26472647

26482648
HANDLE_BLOCK_INTERRUPTIONS();
26492649

2650-
p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2650+
p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
26512651
if (UNEXPECTED(p == NULL)) {
26522652
HANDLE_UNBLOCK_INTERRUPTIONS();
26532653
return p;
@@ -2668,7 +2668,7 @@ ZEND_API char *zend_strndup(const char *s, uint length)
26682668

26692669
HANDLE_BLOCK_INTERRUPTIONS();
26702670

2671-
p = (char *) malloc(length+1);
2671+
p = (char *) malloc(safe_address(length, 1, 1));
26722672
if (UNEXPECTED(p == NULL)) {
26732673
HANDLE_UNBLOCK_INTERRUPTIONS();
26742674
return p;

Zend/zend_operators.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,14 +1319,19 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
13191319
zend_error(E_ERROR, "String size overflow");
13201320
}
13211321

1322-
Z_STRVAL_P(result) = erealloc(Z_STRVAL_P(result), res_len+1);
1322+
Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1);
13231323

13241324
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
13251325
Z_STRVAL_P(result)[res_len]=0;
13261326
Z_STRLEN_P(result) = res_len;
13271327
} else {
13281328
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
1329-
char *buf = (char *) emalloc(length + 1);
1329+
char *buf;
1330+
1331+
if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
1332+
zend_error(E_ERROR, "String size overflow");
1333+
}
1334+
buf = (char *) safe_emalloc(length, 1, 1);
13301335

13311336
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
13321337
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));

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
*/
@@ -1454,7 +1454,7 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen
14541454
}
14551455
#if defined(PHP_WIN32) || defined(NETWARE)
14561456
/* Catch relative paths in c:file.txt style. They're not to confuse
1457-
with the NTFS streams. This part ensures also, that no drive
1457+
with the NTFS streams. This part ensures also, that no drive
14581458
letter traversing happens. */
14591459
} else if ((*c == ':' && (c - comp == 1))) {
14601460
if (state == 0) {
@@ -4910,6 +4910,10 @@ PHP_FUNCTION(str_repeat)
49104910

49114911
/* Initialize the result string */
49124912
result_len = input_len * mult;
4913+
if(result_len > INT_MAX) {
4914+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, maximum %d allowed", INT_MAX);
4915+
RETURN_EMPTY_STRING();
4916+
}
49134917
result = (char *)safe_emalloc(input_len, mult, 1);
49144918

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

0 commit comments

Comments
 (0)