]> granicus.if.org Git - php/commitdiff
MFH: fix #38322 (reading past array in sscanf() leads to arbitary code execution)
authorAntony Dovgal <tony2001@php.net>
Fri, 4 Aug 2006 11:50:15 +0000 (11:50 +0000)
committerAntony Dovgal <tony2001@php.net>
Fri, 4 Aug 2006 11:50:15 +0000 (11:50 +0000)
NEWS
ext/standard/scanf.c

diff --git a/NEWS b/NEWS
index d4a60e7d988f4e79ce8acf9f4cb2f3f393b807b6..0e49206f26dbacd5d69c842e0de0e0acafec6801 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,8 @@ PHP                                                                        NEWS
 - Fixed phpinfo() cutoff of variables at \0. (Ilia)
 - Fixed a bug in the filter extension that prevented magic_quotes_gpc from
   being applied when RAW filter is used. (Ilia)
+- Fixed bug #38322 (reading past array in sscanf() leads to arbitary code 
+  execution). (Tony)
 - Fixed bug #38303 (spl_autoload_register() supress all errors silently).
   (Ilia)
 - Fixed bug #38289 (segfault in session_decode() when _SESSION is NULL). 
index 870a06888157c6d8d80b31506bcac1588336849e..b21668836a6ec5ef64045bc32c0d41631358ecee 100644 (file)
@@ -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,7 +762,9 @@ PHPAPI int php_sscanf_internal(     char *string, char *format,
                switch (*ch) {
                        case 'n':
                                if (!(flags & SCAN_SUPPRESS)) {
-                                       if (numVars) {
+                                       if (numVars && objIndex >= argCount) {
+                                               break;
+                                       } else if (numVars) {
                                                zend_uint refcount;
 
                                                current = args[objIndex++];
@@ -888,7 +890,9 @@ PHPAPI int php_sscanf_internal(     char *string, char *format,
                                        }
                                }
                                if (!(flags & SCAN_SUPPRESS)) {
-                                       if (numVars) {
+                                       if (numVars && objIndex >= argCount) {
+                                               break;
+                                       } else if (numVars) {
                                                zend_uint refcount;
 
                                                current = args[objIndex++];
@@ -932,7 +936,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);
@@ -1089,7 +1095,9 @@ 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) {
+                                               if (numVars && objIndex >= argCount) {
+                                                       break;
+                                               } else if (numVars) {
                                                  /* change passed value type to string */
                                                   current = args[objIndex++];
                                                   convert_to_string( *current );
@@ -1098,7 +1106,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;
@@ -1206,7 +1216,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;