|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patchesfix-77269 (last revision 2018-12-12 15:56 UTC by cmb@php.net)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
[2018-12-09 08:56 UTC] stas@php.net
[2018-12-09 12:07 UTC] cmb@php.net
-Assigned To:
+Assigned To: cmb
[2018-12-09 12:07 UTC] cmb@php.net
[2018-12-09 13:21 UTC] cmb@php.net
[2018-12-09 21:31 UTC] sscannell at ripstech dot com
[2018-12-09 22:19 UTC] cmb@php.net
-Status: Assigned
+Status: Analyzed
[2018-12-09 22:19 UTC] cmb@php.net
[2018-12-12 15:56 UTC] cmb@php.net
[2018-12-12 15:57 UTC] cmb@php.net
-Assigned To: cmb
+Assigned To: stas
-CVE-ID:
+CVE-ID: 2016-10166
[2018-12-12 15:57 UTC] cmb@php.net
[2018-12-16 00:45 UTC] stas@php.net
[2018-12-30 02:41 UTC] stas@php.net
[2018-12-30 02:43 UTC] stas@php.net
-PHP Version: 7.0.33
+PHP Version: 5.6.39
[2018-12-30 02:43 UTC] stas@php.net
[2018-12-30 14:06 UTC] cmb@php.net
[2018-12-30 19:38 UTC] stas@php.net
[2019-01-07 08:10 UTC] stas@php.net
[2019-01-07 08:10 UTC] stas@php.net
-Status: Analyzed
+Status: Closed
[2019-01-07 08:19 UTC] stas@php.net
[2019-01-07 08:19 UTC] stas@php.net
[2019-01-07 08:20 UTC] stas@php.net
[2019-01-07 08:20 UTC] stas@php.net
[2019-01-07 08:20 UTC] stas@php.net
[2019-01-07 08:20 UTC] stas@php.net
[2019-01-07 08:21 UTC] stas@php.net
[2019-01-07 08:21 UTC] stas@php.net
[2019-01-07 13:17 UTC] cmb@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 22:00:02 2025 UTC |
Description: ------------ When malicious user input is passed to the imagescale function of the gd extension, efree() will be called on uninitialized heap data. This can lead to use after free vulnerabilities if the heap is sprayed with the address of a known structure. The bug occurs in ext/gd/libgd/gd_interpolation.c in the function _gdContributionsAlloc(int line_size, int windows_size). The function will attempt to allocate helper structs and receives two parameters: the line size and the windows size. To prevent integer overflows, each parameter is passed to gd's overflow2() function before being used in the gdMalloc function. (gdMalloc is just #define gdMalloc emalloc). However, if the overflow2 check for windows size is positive, overflow_error is set to true, which leads to gd attempting to free all the lines allocated so far. The issue is that gd does not check if any lines have been allocated so far at all. By supplying input that leads to overflow2 being true, .Weights is freed, which is an unintialized pointer. if (overflow2(line_length, sizeof(ContributionType))) { gdFree(res); return NULL; } res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType)); if (res->ContribRow == NULL) { gdFree(res); return NULL; } for (u = 0 ; u < line_length ; u++) { if (overflow2(windows_size, sizeof(double))) { overflow_error = 1; } else { res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double)); } if (overflow_error == 1 || res->ContribRow[u].Weights == NULL) { unsigned int i; u--; for (i=0;i<=u;i++) { gdFree(res->ContribRow[i].Weights); } When the for loop is reached that frees the uninitialized pointers, i will be 0 and u too. However, before the for loop is entered u is decremented by one so it will turn into -1 , which leads to the condition i <=0 never being met. I have run the test script provided on my Debian production server with the latest version of php installed (7.0 line). The free() error occurs but the execution continues. I am not sure if that is because of the distribution or PHP version. The same code persists in php 7.2.13 and 5.6.39 although I have not managed to crash the 5.6.39 line so far Test script: --------------- <?php $img = imagecreate(pow(2, 27), 0x01); var_dump(imagescale($img, 0x01, 0x01, 20)); echo "Execution continues!\n"; Expected result: ---------------- No Crash Actual result: -------------- php fault.php bool(false) Execution continues! *** Error in `php': free(): invalid pointer: 0x00005597c21f2d80 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7fd6fa8f2bfb] /lib/x86_64-linux-gnu/libc.so.6(+0x76fc6)[0x7fd6fa8f8fc6] /lib/x86_64-linux-gnu/libc.so.6(+0x7780e)[0x7fd6fa8f980e] /usr/lib/x86_64-linux-gnu/libgd.so.3(gdImageDestroy+0x71)[0x7fd6f61bf921] php(+0x271141)[0x5597c1282141] php(list_entry_destructor+0x1a)[0x5597c12821ca] php(zend_hash_index_del+0xc6)[0x5597c127e076] php(zend_hash_graceful_reverse_destroy+0x111)[0x5597c127eea1] php(shutdown_executor+0x42b)[0x5597c125cbbb] php(zend_deactivate+0x6b)[0x5597c126cebb] php(php_request_shutdown+0x296)[0x5597c120a9f6] php(+0x2f28b0)[0x5597c13038b0] php(main+0x46e)[0x5597c10edebe] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7fd6fa8a22e1] php(_start+0x2a)[0x5597c10ee00a] ======= Memory map: ======== 5597c1011000-5597c13bb000 r-xp 00000000 fe:01 5781 /usr/bin/php7.0 5597c15ba000-5597c1630000 r--p 003a9000 fe:01 5781 /usr/bin/php7.0 5597c1630000-5597c1640000 rw-p 0041f000 fe:01 5781 /usr/bin/php7.0 5597c1640000-5597c165c000 rw-p 00000000 00:00 0 5597c20b5000-5597c2227000 rw-p 00000000 00:00 0 [heap] 7fd6e4000000-7fd6e4021000 rw-p 00000000 00:00 0 7fd6e4021000-7fd6e8000000 ---p 00000000 00:00 0 7fd6f1c28000-7fd6f1c2c000 r-xp 00000000 fe:01 131865 /usr/lib/php/20151012/tokenizer.so 7fd6f1c2c000-7fd6f1e2b000 ---p 00004000 fe:01 131865 /usr/lib/php/20151012/tokenizer.so 7fd6f1e2b000-7fd6f1e2c000 r--p 00003000 fe:01 131865 /usr/lib/php/20151012/tokenizer.so 7fd6f1e2c000-7fd6f1e2d000 rw-p 00004000 fe:01 131865 /usr/lib/php/20151012/tokenizer.so 7fd6f1e2d000-7fd6f1e30000 r-xp 00000000 fe:01 131863 /usr/lib/php/20151012/sysvshm.so ...