]> 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:59:50 +0000 (11:59 +0000)
committerAntony Dovgal <tony2001@php.net>
Fri, 4 Aug 2006 11:59:50 +0000 (11:59 +0000)
NEWS
ext/standard/scanf.c

diff --git a/NEWS b/NEWS
index 1d08e7207575667d86ecda04360604bd1e3e81a4..bdba7c0fb43a3231de58a0c7ee4f3d3cafded1e6 100644 (file)
--- 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)
index 6f41b092836988adc7f53101a93b84a13985540f..5dda4982212c53f04a10481ac76c331ff3ee7929 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,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;