From: Antony Dovgal Date: Fri, 4 Aug 2006 11:59:50 +0000 (+0000) Subject: MFH: fix #38322 (reading past array in sscanf() leads to arbitary code execution) X-Git-Tag: php-4.4.4RC1~13 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d377d05ece6bbb7e29dabdd041483ebf5ce7798;p=php MFH: fix #38322 (reading past array in sscanf() leads to arbitary code execution) --- diff --git a/NEWS b/NEWS index 1d08e72075..bdba7c0fb4 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ PHP 4 NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2006, Version 4.4.4 +- Fixed bug #38322 (reading past array in sscanf() leads to arbitary code + execution). (Tony) - Fixed bug #38278 (session_cache_expire()'s value does not match phpinfo's session.cache_expire). (Tony) - Fixed bug #38251 (socket_select() and invalid arguments). (Tony) diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index 6f41b09283..5dda498221 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -732,7 +732,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format, if (*end == '$') { format = end+1; ch = format++; - objIndex = varStart + value; + objIndex = varStart + value - 1; } } @@ -762,8 +762,10 @@ PHPAPI int php_sscanf_internal( char *string, char *format, switch (*ch) { case 'n': if (!(flags & SCAN_SUPPRESS)) { - if (numVars) { - current = args[objIndex++]; + if (numVars && objIndex >= argCount) { + break; + } else if (numVars) { + current = args[objIndex++]; zval_dtor( *current ); ZVAL_LONG( *current, (long)(string - baseString) ); } else { @@ -883,8 +885,10 @@ PHPAPI int php_sscanf_internal( char *string, char *format, } } if (!(flags & SCAN_SUPPRESS)) { - if (numVars) { - current = args[objIndex++]; + if (numVars && objIndex >= argCount) { + break; + } else if (numVars) { + current = args[objIndex++]; zval_dtor( *current ); ZVAL_STRINGL( *current, string, end-string, 1); } else { @@ -922,7 +926,9 @@ PHPAPI int php_sscanf_internal( char *string, char *format, goto done; } if (!(flags & SCAN_SUPPRESS)) { - if (numVars) { + if (numVars && objIndex >= argCount) { + break; + } else if (numVars) { current = args[objIndex++]; zval_dtor( *current ); ZVAL_STRINGL( *current, string, end-string, 1); @@ -1079,8 +1085,10 @@ PHPAPI int php_sscanf_internal( char *string, char *format, value = (int) (*fn)(buf, NULL, base); if ((flags & SCAN_UNSIGNED) && (value < 0)) { sprintf(buf, "%u", value); /* INTL: ISO digit */ - if (numVars) { - /* change passed value type to string */ + if (numVars && objIndex >= argCount) { + break; + } else if (numVars) { + /* change passed value type to string */ current = args[objIndex++]; convert_to_string( *current ); ZVAL_STRING( *current, buf, 1 ); @@ -1088,7 +1096,9 @@ PHPAPI int php_sscanf_internal( char *string, char *format, add_index_string(*return_value, objIndex++, buf, 1); } } else { - if (numVars) { + if (numVars && objIndex >= argCount) { + break; + } else if (numVars) { current = args[objIndex++]; convert_to_long( *current ); Z_LVAL(**current) = value; @@ -1196,7 +1206,9 @@ PHPAPI int php_sscanf_internal( char *string, char *format, double dvalue; *end = '\0'; dvalue = zend_strtod(buf, NULL); - if (numVars) { + if (numVars && objIndex >= argCount) { + break; + } else if (numVars) { current = args[objIndex++]; convert_to_double( *current ); Z_DVAL_PP( current ) = dvalue;