Skip to content

Commit 678ecff

Browse files
committed
Fix memory leak on overflow in _php_stream_scandir()
On overflow, only the array is freed, but not the strings. Closes phpGH-17789.
1 parent 3021658 commit 678ecff

File tree

2 files changed

+14
-11
lines changed

2 files changed

+14
-11
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ PHP NEWS
4141

4242
- Streams:
4343
. Fixed bug GH-17650 (realloc with size 0 in user_filters.c). (nielsdos)
44+
. Fix memory leak on overflow in _php_stream_scandir(). (nielsdos)
4445

4546
- Windows:
4647
. Fixed phpize for Windows 11 (24H2). (bwoebi)

main/streams/streams.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,25 +2469,19 @@ PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], in
24692469
vector_size = 10;
24702470
} else {
24712471
if(vector_size*2 < vector_size) {
2472-
/* overflow */
2473-
php_stream_closedir(stream);
2474-
efree(vector);
2475-
return -1;
2472+
goto overflow;
24762473
}
24772474
vector_size *= 2;
24782475
}
2479-
vector = (zend_string **) safe_erealloc(vector, vector_size, sizeof(char *), 0);
2476+
vector = (zend_string **) safe_erealloc(vector, vector_size, sizeof(zend_string *), 0);
24802477
}
24812478

24822479
vector[nfiles] = zend_string_init(sdp.d_name, strlen(sdp.d_name), 0);
24832480

2484-
nfiles++;
2485-
if(vector_size < 10 || nfiles == 0) {
2486-
/* overflow */
2487-
php_stream_closedir(stream);
2488-
efree(vector);
2489-
return -1;
2481+
if(vector_size < 10 || nfiles + 1 == 0) {
2482+
goto overflow;
24902483
}
2484+
nfiles++;
24912485
}
24922486
php_stream_closedir(stream);
24932487

@@ -2497,5 +2491,13 @@ PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], in
24972491
qsort(*namelist, nfiles, sizeof(zend_string *), (int(*)(const void *, const void *))compare);
24982492
}
24992493
return nfiles;
2494+
2495+
overflow:
2496+
php_stream_closedir(stream);
2497+
for (unsigned int i = 0; i < nfiles; i++) {
2498+
zend_string_efree(vector[i]);
2499+
}
2500+
efree(vector);
2501+
return -1;
25002502
}
25012503
/* }}} */

0 commit comments

Comments
 (0)