Bugzilla – Bug 997208
VUL-0: CVE-2016-7126: php7: select_colors write out-of-bounds
Last modified: 2016-10-31 08:27:15 UTC
Description ============ Type mismatch parameters between ncolors and colorsWanted parameters at zif_imagetruecolortopalette and php_gd_gdImageTrueColorToPalette, ncolors is a 64 bit integer and colorsWanted is 32 bits, ncolors' value 0x1000000000000000 becomes 0 inside php_gd_gdImageTrueColorToPalette. Later, select_colors will not allocate enough memory and writes out of bounds. =============================================== PHP Source code: https://github.com/php/php-src/blob/PHP-7.0/ext/gd/libgd/gd_topal.c#L780 LOCAL (void) #ifdef ORIGINAL_LIB_JPEG select_colors (j_decompress_ptr cinfo, int desired_colors) #else select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors) #endif /* Master routine for color selection */ { boxptr boxlist; int numboxes; int i; /* Allocate workspace for box list */ #ifdef ORIGINAL_LIB_JPEG boxlist = (boxptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF (box)); #else boxlist = (boxptr) safe_emalloc(desired_colors, sizeof (box), 1); // desired_colors = 0 and reserved memory = 1 #endif /* Initialize one box containing whole space */ numboxes = 1; boxlist[0].c0min = 0; // write out of bounds boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; boxlist[0].c1min = 0; boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; boxlist[0].c2min = 0; boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; GDB output ========== USE_ZEND_ALLOC=0 gdb -q --args /home/operac/php-70-sinasan/sapi/cli/php -n poc.php Reading symbols from /home/operac/php-70-sinasan/sapi/cli/php...done. (gdb) b gd.c:1537 Breakpoint 1 at 0x549641: file /home/operac/php-70-sinasan/ext/gd/gd.c, line 1537. (gdb) b php_gd_gdImageTrueColorToPalette Breakpoint 2 at 0x569cce: file /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c, line 1768. (gdb) r Starting program: /home/operac/php-70-sinasan/sapi/cli/php -n poc.php Breakpoint 1, zif_imagetruecolortopalette (execute_data=0x7ffff7ed70e0, return_value=0x7ffff7ed70d0) at /home/operac/php-70-sinasan/ext/gd/gd.c:1537 1537 gdImageTrueColorToPalette(im, dither, ncolors); (gdb) p/x ncolors $1 = 0x1000000000000000 (gdb) c Continuing. Breakpoint 2, php_gd_gdImageTrueColorToPalette (im=0x139de70, dither=0, colorsWanted=0) at /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c:1768 1768 gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0); (gdb) p/x colorsWanted $2 = 0x0 <---- parameter casted to 32 bits (gdb) gdb) b select_colors Breakpoint 4 at 0x5686e5: file /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c, line 797. (gdb) c Continuing. Breakpoint 4, select_colors (oim=0x139de70, nim=0x139de70, cquantize=0x13a66c0, desired_colors=0) at /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c:797 797 boxlist = (boxptr) safe_emalloc(desired_colors, sizeof (box), 1); (gdb) b _safe_emalloc Breakpoint 5 at 0x86d716: file /home/operac/php-70-sinasan/Zend/zend_alloc.c, line 2518. (gdb) c Continuing. Breakpoint 5, _safe_emalloc (nmemb=0, size=40, offset=1, __zend_filename=0xd5ccd8 "/home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c", __zend_lineno=797, __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/operac/php-70-sinasan/Zend/zend_alloc.c:2518 2518 return emalloc_rel(safe_address(nmemb, size, offset)); (gdb) p nmemb $3 = 0 <------ reserved memory = (0 * 40) + 1 = 1 byte (gdb) c Program received signal SIGABRT, Aborted. (gdb) bt 0x00007ffff5f7e418 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff5f7e418 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 #1 0x00007ffff5f8001a in __GI_abort () at abort.c:89 #2 0x00007ffff5fc072a in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff60d96b0 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff5fc8f4a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=0x7ffff60d9728 "free(): invalid next size (fast)", action=3) at malloc.c:5007 #4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3868 #5 0x00007ffff5fccabc in __GI___libc_free (mem=<optimized out>) at malloc.c:2969 #6 0x000000000086d45b in _efree (ptr=0x13a5ba0, __zend_filename=0xd5ccd8 "/home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c", __zend_lineno=841, __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/operac/php-70-sinasan/Zend/zend_alloc.c:2461 #7 0x00000000005688e8 in select_colors (oim=0x139de70, nim=0x139de70, cquantize=0x13a66c0, desired_colors=0) at /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c:841 #8 0x000000000056a0c2 in gdImageTrueColorToPaletteBody (oim=0x139de70, dither=0, colorsWanted=0, cimP=0x0) at /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c:1942 #9 0x0000000000569ce5 in php_gd_gdImageTrueColorToPalette (im=0x139de70, dither=0, colorsWanted=0) at /home/operac/php-70-sinasan/ext/gd/libgd/gd_topal.c:1768 #10 0x000000000054965c in zif_imagetruecolortopalette (execute_data=0x7ffff7ed70e0, return_value=0x7ffff7ed70d0) at /home/operac/php-70-sinasan/ext/gd/gd.c:1537 #11 0x0000000000902021 in ZEND_DO_ICALL_SPEC_HANDLER () at /home/operac/php-70-sinasan/Zend/zend_vm_execute.h:586 #12 0x0000000000901a4d in execute_ex (ex=0x7ffff7ed7040) at /home/operac/php-70-sinasan/Zend/zend_vm_execute.h:414 #13 0x0000000000901b5e in zend_execute (op_array=0x13a5f90, return_value=0x0) at /home/operac/php-70-sinasan/Zend/zend_vm_execute.h:458 #14 0x00000000008a2be4 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/operac/php-70-sinasan/Zend/zend.c:1427 #15 0x000000000080b2f9 in php_execute_script (primary_file=0x7fffffffd1f0) at /home/operac/php-70-sinasan/main/main.c:2494 #16 0x000000000096acf3 in do_cli (argc=3, argv=0x124e710) at /home/operac/php-70-sinasan/sapi/cli/php_cli.c:974 #17 0x000000000096bec1 in main (argc=3, argv=0x124e710) at /home/operac/php-70-sinasan/sapi/cli/php_cli.c:1344 ====================== This issue doesn't affect upstream libgd, overflow2 function check will prevent it: https://github.com/libgd/libgd/blob/master/src/gd_topal.c#L686 LOCAL (void) select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors) /* Master routine for color selection */ { boxptr boxlist; int numboxes; int i; /* Allocate workspace for box list */ /* This can't happen because we clamp desired_colors at gdMaxColors, but anyway */ if (overflow2(desired_colors, sizeof (box))) { return; } https://github.com/libgd/libgd/blob/master/src/gd_security.c#L21 int overflow2(int a, int b) { if(a <= 0 || b <= 0) { gd_error_ex(GD_WARNING, "one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n"); return 1; } if(a > INT_MAX / b) { gd_error_ex(GD_WARNING, "product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); return 1; } return 0; } Test script: --------------- <?php $img=imagecreatetruecolor(10, 10); imagetruecolortopalette($img, false, PHP_INT_MAX / 8); Expected result: ---------------- No crash Actual result: -------------- ASan output: ==25164==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000039790 at pc 0x000000a04930 bp 0x7fff2424a5e0 sp 0x7fff2424a5d0 WRITE of size 4 at 0x602000039790 thread T0 #0 0xa0492f in select_colors /home/operac/php-70/ext/gd/libgd/gd_topal.c:801 #1 0xa0492f in gdImageTrueColorToPaletteBody /home/operac/php-70/ext/gd/libgd/gd_topal.c:1942 #2 0x967dac in zif_imagetruecolortopalette /home/operac/php-70/ext/gd/gd.c:1537 #3 0x1da38da in ZEND_DO_ICALL_SPEC_HANDLER /home/operac/php-70/Zend/zend_vm_execute.h:586 #4 0x1b4c335 in execute_ex /home/operac/php-70/Zend/zend_vm_execute.h:414 #5 0x1df9dc8 in zend_execute /home/operac/php-70/Zend/zend_vm_execute.h:458 #6 0x194764a in zend_execute_scripts /home/operac/php-70/Zend/zend.c:1427 #7 0x16b8347 in php_execute_script /home/operac/php-70/main/main.c:2494 #8 0x1e02126 in do_cli /home/operac/php-70/sapi/cli/php_cli.c:974 #9 0x467378 in main /home/operac/php-70/sapi/cli/php_cli.c:1344 #10 0x7f67c285782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #11 0x467a48 in _start (/ramdisk/php-fuzz/phuzzer/php-70/sapi/cli/php+0x467a48) 0x602000039791 is located 0 bytes to the right of 1-byte region [0x602000039790,0x602000039791) allocated by thread T0 here: #0 0x7f67c475d54a in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9854a) #1 0xa00444 in select_colors /home/operac/php-70/ext/gd/libgd/gd_topal.c:797 #2 0xa00444 in gdImageTrueColorToPaletteBody /home/operac/php-70/ext/gd/libgd/gd_topal.c:1942 #3 0x967dac in zif_imagetruecolortopalette /home/operac/php-70/ext/gd/gd.c:1537 #4 0x1da38da in ZEND_DO_ICALL_SPEC_HANDLER /home/operac/php-70/Zend/zend_vm_execute.h:586 #5 0x1b4c335 in execute_ex /home/operac/php-70/Zend/zend_vm_execute.h:414 #6 0x1df9dc8 in zend_execute /home/operac/php-70/Zend/zend_vm_execute.h:458 #7 0x194764a in zend_execute_scripts /home/operac/php-70/Zend/zend.c:1427 #8 0x16b8347 in php_execute_script /home/operac/php-70/main/main.c:2494 #9 0x1e02126 in do_cli /home/operac/php-70/sapi/cli/php_cli.c:974 #10 0x467378 in main /home/operac/php-70/sapi/cli/php_cli.c:1344 #11 0x7f67c285782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) SUMMARY: AddressSanitizer: heap-buffer-overflow /home/operac/php-70/ext/gd/libgd/gd_topal.c:801 select_colors References: https://bugs.php.net/bug.php?id=72697 https://github.com/php/php-src/commit/b6f13a5ef9d6280cf984826a5de012a32c396cd4?w=1
bugbot adjusting priority
Packages submitted.
This is an autogenerated message for OBS integration: This bug (997208) was mentioned in https://build.opensuse.org/request/show/425708 13.2 / php5
SUSE-SU-2016:2328-1: An update that fixes 18 vulnerabilities is now available. Category: security (important) Bug References: 987530,991426,991427,991428,991429,991430,991433,991437,997206,997207,997208,997210,997211,997220,997225,997230,997257 CVE References: CVE-2014-3587,CVE-2016-3587,CVE-2016-5399,CVE-2016-6288,CVE-2016-6289,CVE-2016-6290,CVE-2016-6291,CVE-2016-6296,CVE-2016-6297,CVE-2016-7124,CVE-2016-7125,CVE-2016-7126,CVE-2016-7127,CVE-2016-7128,CVE-2016-7129,CVE-2016-7130,CVE-2016-7131,CVE-2016-7132 Sources used: SUSE Linux Enterprise Server 11-SP2-LTSS (src): php53-5.3.17-55.1 SUSE Linux Enterprise Debuginfo 11-SP2 (src): php53-5.3.17-55.1
openSUSE-SU-2016:2337-1: An update that fixes 10 vulnerabilities is now available. Category: security (important) Bug References: 997206,997207,997208,997210,997211,997220,997225,997230,997248,997257 CVE References: CVE-2016-7124,CVE-2016-7125,CVE-2016-7126,CVE-2016-7127,CVE-2016-7128,CVE-2016-7129,CVE-2016-7130,CVE-2016-7131,CVE-2016-7132,CVE-2016-7134 Sources used: openSUSE 13.2 (src): php5-5.6.1-75.2
SUSE-SU-2016:2408-1: An update that fixes 24 vulnerabilities is now available. Category: security (important) Bug References: 987530,987580,988032,991422,991424,991426,991427,991428,991429,991430,991433,991434,991437,997206,997207,997208,997210,997211,997220,997225,997230,997248,997257 CVE References: CVE-2014-3587,CVE-2016-3587,CVE-2016-5399,CVE-2016-6128,CVE-2016-6161,CVE-2016-6207,CVE-2016-6288,CVE-2016-6289,CVE-2016-6290,CVE-2016-6291,CVE-2016-6292,CVE-2016-6295,CVE-2016-6296,CVE-2016-6297,CVE-2016-7124,CVE-2016-7125,CVE-2016-7126,CVE-2016-7127,CVE-2016-7128,CVE-2016-7129,CVE-2016-7130,CVE-2016-7131,CVE-2016-7132,CVE-2016-7134 Sources used: SUSE Linux Enterprise Software Development Kit 12-SP1 (src): php5-5.5.14-73.1 SUSE Linux Enterprise Module for Web Scripting 12 (src): php5-5.5.14-73.1
openSUSE-SU-2016:2451-1: An update that fixes 24 vulnerabilities is now available. Category: security (important) Bug References: 987530,987580,988032,991422,991424,991426,991427,991428,991429,991430,991433,991434,991437,997206,997207,997208,997210,997211,997220,997225,997230,997248,997257 CVE References: CVE-2014-3587,CVE-2016-3587,CVE-2016-5399,CVE-2016-6128,CVE-2016-6161,CVE-2016-6207,CVE-2016-6288,CVE-2016-6289,CVE-2016-6290,CVE-2016-6291,CVE-2016-6292,CVE-2016-6295,CVE-2016-6296,CVE-2016-6297,CVE-2016-7124,CVE-2016-7125,CVE-2016-7126,CVE-2016-7127,CVE-2016-7128,CVE-2016-7129,CVE-2016-7130,CVE-2016-7131,CVE-2016-7132,CVE-2016-7134 Sources used: openSUSE Leap 42.1 (src): php5-5.5.14-59.1
SUSE-SU-2016:2459-1: An update that fixes 16 vulnerabilities is now available. Category: security (important) Bug References: 997206,997207,997208,997210,997211,997220,997225,997230,997257,999679,999680,999682,999684,999685,999819,999820 CVE References: CVE-2016-7124,CVE-2016-7125,CVE-2016-7126,CVE-2016-7127,CVE-2016-7128,CVE-2016-7129,CVE-2016-7130,CVE-2016-7131,CVE-2016-7132,CVE-2016-7411,CVE-2016-7412,CVE-2016-7413,CVE-2016-7414,CVE-2016-7416,CVE-2016-7417,CVE-2016-7418 Sources used: SUSE OpenStack Cloud 5 (src): php53-5.3.17-84.1 SUSE Manager Proxy 2.1 (src): php53-5.3.17-84.1 SUSE Manager 2.1 (src): php53-5.3.17-84.1 SUSE Linux Enterprise Software Development Kit 11-SP4 (src): php53-5.3.17-84.1 SUSE Linux Enterprise Server 11-SP4 (src): php53-5.3.17-84.1 SUSE Linux Enterprise Server 11-SP3-LTSS (src): php53-5.3.17-84.1 SUSE Linux Enterprise Point of Sale 11-SP3 (src): php53-5.3.17-84.1 SUSE Linux Enterprise Debuginfo 11-SP4 (src): php53-5.3.17-84.1 SUSE Linux Enterprise Debuginfo 11-SP3 (src): php53-5.3.17-84.1
SUSE-SU-2016:2460-1: An update that solves 29 vulnerabilities and has two fixes is now available. Category: security (important) Bug References: 1001950,987580,988032,991422,991424,991426,991427,991428,991429,991430,991434,991437,995512,997206,997207,997208,997210,997211,997220,997225,997230,997247,997248,997257,999313,999679,999680,999684,999685,999819,999820 CVE References: CVE-2016-4473,CVE-2016-5399,CVE-2016-6128,CVE-2016-6161,CVE-2016-6207,CVE-2016-6289,CVE-2016-6290,CVE-2016-6291,CVE-2016-6292,CVE-2016-6295,CVE-2016-6296,CVE-2016-6297,CVE-2016-7124,CVE-2016-7125,CVE-2016-7126,CVE-2016-7127,CVE-2016-7128,CVE-2016-7129,CVE-2016-7130,CVE-2016-7131,CVE-2016-7132,CVE-2016-7133,CVE-2016-7134,CVE-2016-7412,CVE-2016-7413,CVE-2016-7414,CVE-2016-7416,CVE-2016-7417,CVE-2016-7418 Sources used: SUSE Linux Enterprise Software Development Kit 12-SP1 (src): php7-7.0.7-15.1 SUSE Linux Enterprise Module for Web Scripting 12 (src): php7-7.0.7-15.1
released