Skip to content

Commit e6c570a

Browse files
authored
Prevent unsigned overflow in php_handle_swc() (phpGH-17678)
The multiplication of `ZSTR_LEN(bufz)` with the `factor` can easily overflow on LLP64 architectures, causing a smaller `buf` to be allocated than expected. While there are no security implications, calling `uncompress()` with the small buffer cannot be successful (`Z_BUF_ERROR`). We avoid such superfluous calls by bailing out of the loop early in case of an overflow condition. Note that `safe_emalloc()` would not help here, since that will not prevent 32bit unsigned overflow on 64bit architectures.
1 parent 650086f commit e6c570a

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

ext/standard/image.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,14 @@ static struct gfxinfo *php_handle_swc(php_stream * stream)
203203
*/
204204

205205
do {
206-
szlength = ZSTR_LEN(bufz) * (factor <<= 1);
206+
factor <<= 1;
207+
if (ZSTR_LEN(bufz) > ULONG_MAX / factor) {
208+
status = Z_MEM_ERROR;
209+
break;
210+
}
211+
szlength = (unsigned long) (ZSTR_LEN(bufz) * factor);
207212
buf = erealloc(buf, szlength);
208-
status = uncompress(buf, &szlength, (unsigned char *) ZSTR_VAL(bufz), ZSTR_LEN(bufz));
213+
status = uncompress(buf, &szlength, (unsigned char *) ZSTR_VAL(bufz), (unsigned long) ZSTR_LEN(bufz));
209214
} while ((status==Z_BUF_ERROR)&&(factor<maxfactor));
210215

211216
if (bufz) {

0 commit comments

Comments
 (0)