php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73638 Denial of Service in GD related
Submitted: 2016-12-02 01:32 UTC Modified: 2016-12-06 08:24 UTC
From: whitehat002 at hotmail dot com Assigned:
Status: Not a bug Package: GD related
PHP Version: 7.0.13 OS: all
Private report: No CVE-ID: None
 [2016-12-02 01:32 UTC] whitehat002 at hotmail dot com
Description:
------------
The php_imagettftext_common function in ext/gd/gd.c allows attackers to cause a denial of service.The imageftbbox function,the imagettftext function,the imagefttext function and the imagettfbbox function call php_imagettftext_common function.So,these four functions will cause denial of service no matter which function.
The php_imagettftext_common function of the source codeļ¼š

static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int extended)
{
	zval *IM, *EXT = NULL;
	gdImagePtr im=NULL;
	zend_long col = -1, x = 0, y = 0;
	size_t str_len, fontname_len;
	int i, brect[8];
	double ptsize, angle;
	char *str = NULL, *fontname = NULL;
	char *error = NULL;
	int argc = ZEND_NUM_ARGS();
	gdFTStringExtra strex = {0};

	if (mode == TTFTEXT_BBOX) {
		if (argc < 4 || argc > ((extended) ? 5 : 4)) {
			ZEND_WRONG_PARAM_COUNT();
		} else if (zend_parse_parameters(argc, "ddss|a", &ptsize, &angle, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) {
			RETURN_FALSE;
		}
	} else {
		if (argc < 8 || argc > ((extended) ? 9 : 8)) {
			ZEND_WRONG_PARAM_COUNT();
		} else if (zend_parse_parameters(argc, "rddlllss|a", &IM, &ptsize, &angle, &x, &y, &col, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) {
			RETURN_FALSE;
		}
		if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
			RETURN_FALSE;
		}
	}

	/* convert angle to radians */
	angle = angle * (M_PI/180);

	if (extended && EXT) {	/* parse extended info */
		zval *item;
		zend_string *key;

		/* walk the assoc array */
		ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(EXT), key, item) {
			if (key == NULL) {
				continue;
			}
			if (strcmp("linespacing", ZSTR_VAL(key)) == 0) {
				strex.flags |= gdFTEX_LINESPACE;
				strex.linespacing = zval_get_double(item);
			}
		} ZEND_HASH_FOREACH_END();
	}

#ifdef VIRTUAL_DIR
	{
		char tmp_font_path[MAXPATHLEN];

		if (!VCWD_REALPATH(fontname, tmp_font_path)) {
			fontname = NULL;
		}
	}
#endif /* VIRTUAL_DIR */

	PHP_GD_CHECK_OPEN_BASEDIR(fontname, "Invalid font filename");

#ifdef HAVE_GD_FREETYPE
	if (extended) {
		error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex);
	}
	else
		error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str);

#endif /* HAVE_GD_FREETYPE */

	if (error) {
		php_error_docref(NULL, E_WARNING, "%s", error);
		RETURN_FALSE;
	}

	array_init(return_value);

	/* return array with the text's bounding box */
	for (i = 0; i < 8; i++) {
		add_next_index_long(return_value, brect[i]);
	}
}

The reason for this vulnreability is not yet found.My guess is that the gdImageStringFTEx function has led to the vulnerability.This function has been exposed to a denial of Service Vulnerability.

Tested in 5.6.x and  PHP 7.0.13, but should affect a lot more versions.

Test script:
---------------
<?php

ini_set('memory_limit',-1);

$a=str_repeat("A",999999999);
$im = imagecreatetruecolor(300, 100);
//imageftbbox(10,20,'./Tuffy.ttf',$a);
imagettftext($im, 20, 0, 11, 21, 255, './Tuffy.ttf', $a);
?> 

Expected result:
----------------
no crash

Actual result:
--------------
CPU resources are consumed.

 PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                                    
  1688 root      20   0 1176696 754496   2548 R 90.7 75.5   1:04.88 php7.0                                                                                                                                                     
  1160 www-data  20   0  226148  48684   2316 S  8.0  4.9  14:15.78 celery                                                                                                                                                     
    56 root      20   0       0      0      0 S  0.3  0.0   0:18.34 kworker/0:2                                                                                                                                                
     1 root      20   0   33480      8      8 S  0.0  0.0   0:01.33 init                                                                                                                                                       
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd                                                                                                                                                   
     3 root      20   0       0      0      0 S  0.0  0.0   0:00.36 ksoftirqd/0                                                                                                                                                
     4 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0                                                                                                                                                
     5 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H                                                                                                                                               
     7 root      20   0       0      0      0 S  0.0  0.0   0:00.52 rcu_sched                                                                                                                                                  
     8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_bh                                                                                                                                                     
     9 root      20   0       0      0      0 R  0.0  0.0   0:00.60 rcuos/0                                                                                                                                                    
    10 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcuob/0                                                                                                                                                    
    11 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0                                                                                                                                                
    12 root      rt   0       0      0      0 S  0.0  0.0   0:00.02 watchdog/0                                                                                                                                                 
    13 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 khelper                                                                                                                                                    
    14 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kdevtmpfs                                                                                                                                                  
    15 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 netns                                                                                                                                                      
    16 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 perf                                                                                                                                                       
    17 root      20   0       0      0      0 S  0.0  0.0   0:00.00 khungtaskd                                                                                                                                                 
    18 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 writeback                                                                                                                                                  
    19 root      25   5       0      0      0 S  0.0  0.0   0:00.00 ksmd                                                                                                                                                       
    20 root      39  19       0      0      0 S  0.0  0.0   0:00.30 khugepaged                                                                                                                                                 
    21 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 crypto                                                                                                                                                     
    22 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kintegrityd                                                                                                                                                
    23 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 bioset                                                                                                                                                     
    24 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kblockd                                                                                                                                                    
    25 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 ata_sff                                                                                                                                                    
    26 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 md                                                                                                                                                         
    27 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 devfreq_wq                                                                                                                                                 
    31 root      20   0       0      0      0 S  0.0  0.0   0:01.35 kswapd0                                                                                                                                                    
    32 root      20   0       0      0      0 S  0.0  0.0   0:00.00 fsnotify_mark                                                                                                                                              
    33 root      20   0       0      0      0 S  0.0  0.0   0:00.00 ecryptfs-kthrea                                                                                                                                            
    44 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kthrotld                                                                                                                                                   
    45 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 acpi_thermal_pm                                                                                                                                            
    46 root      20   0       0      0      0 S  0.0  0.0   0:00.01 scsi_eh_0                            


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-02 02:27 UTC] whitehat002 at hotmail dot com
array ImageTTFText(int im, int size, int angle, int x, int y, int col, string fontfile, string text);

The parameter of vulnreability is string text.
 [2016-12-05 03:17 UTC] whitehat002 at hotmail dot com
Why didn't people deal with the problem for a long time?
 [2016-12-06 05:57 UTC] stas@php.net
-Status: Open +Status: Feedback -Type: Security +Type: Bug
 [2016-12-06 05:57 UTC] stas@php.net
Not sure where is the problem here. You're trying to render a huge string. It takes a long time. Where's the problem exactly?
 [2016-12-06 06:39 UTC] whitehat002 at hotmail dot com
-Status: Feedback +Status: Open
 [2016-12-06 06:39 UTC] whitehat002 at hotmail dot com
I mean I give in a huge string, CPU will be seriously consumed. Isn't it a security bug?
 [2016-12-06 06:48 UTC] whitehat002 at hotmail dot com
The problem is not very determined, I was found through the black box testing.
 [2016-12-06 08:24 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2016-12-06 08:24 UTC] requinix@php.net
Security bugs are about external users causing problems with code that has been otherwise written properly and safely. This code is (hypothetically) taking unverified input and performing an operation that necessarily uses system resources to complete, and PHP will dutifully attempt to execute it as it was written. It doesn't know that a string 99999999 bytes long is "too long" to render.

The memory_limit would protect you from problems like this so don't set it to be unlimited. post_max_size will protect you from "large" request bodies so make sure that's set appropriately for your application. Finally and most importantly, you should always perform sanity checks - if not thorough validation - on user input before acting upon it.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 09:01:27 2024 UTC