php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43128 Very long class name causes segfault
Submitted: 2007-10-29 17:25 UTC Modified: 2008-02-15 07:45 UTC
From: felipensp at gmail dot com Assigned: dmitry (profile)
Status: Closed Package: Reproducible crash
PHP Version: 5.3CVS-2007-10-29 (snap) OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: felipensp at gmail dot com
New email:
PHP Version: OS:

 

 [2007-10-29 17:25 UTC] felipensp at gmail dot com
Description:
------------
Long names cause segmentation fault in 'instanceof' and 'new' operators.

Reproduce code:
---------------
<?php

$a = str_repeat("a", 10000000);

# call_user_func($a); // Warning
# $a->$a();           // Fatal error

if ($a instanceof $a); // Segmentation fault
new $a;                // Segmentation fault


Expected result:
----------------
Warning / Fatal error

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1214703296 (LWP 4538)]
zend_lookup_class_ex (name=0xb6f4d018 'a' <repeats 200 times>..., 
    name_length=10000000, use_autoload=0, ce=0xbf9644d8)
    at /home/felipe/php5.3-200710261430/Zend/zend_execute_API.c:1078
1078    in /home/felipe/php5.3-200710261430/Zend/zend_execute_API.c



Backtrace:
----------------------------------------------

#0  zend_lookup_class_ex (name=0xb6ece018 'a' <repeats 200 times>..., 
    name_length=10000000, use_autoload=0, ce=0xbfb896f8)
    at /home/felipe/php5.3-200710261430/Zend/zend_execute_API.c:1078
#1  0x08277d9f in zend_fetch_class (
    class_name=0xb6ece018 'a' <repeats 200 times>..., class_name_len=10000000, 
    fetch_type=132) at /home/felipe/php5.3-200710261430/Zend/zend_execute_API.c:1548
#2  0x082c26c9 in ZEND_FETCH_CLASS_SPEC_CV_HANDLER (execute_data=0xbfb8982c)
    at /home/felipe/php5.3-200710261430/Zend/zend_vm_execute.h:1065
#3  0x0829ef1b in execute (op_array=0x84a6900)
    at /home/felipe/php5.3-200710261430/Zend/zend_vm_execute.h:87
#4  0x08281952 in zend_execute_scripts (type=8, retval=<value optimized out>, 
    file_count=3) at /home/felipe/php5.3-200710261430/Zend/zend.c:1137
#5  0x0823d841 in php_execute_script (primary_file=0xbfb8bbcc)
    at /home/felipe/php5.3-200710261430/main/main.c:2007
#6  0x08301c65 in main (argc=2, argv=0xbfb8bce4)
    at /home/felipe/php5.3-200710261430/sapi/cli/php_cli.c:1140


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-10-29 22:24 UTC] iliaa@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows (zip):
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip

For Windows (installer):

  http://snaps.php.net/win32/php5.2-win32-installer-latest.msi

I've tried both PHP 5.2 and 5.3 and cannot reproduce the crash.
 [2007-10-29 23:46 UTC] felipensp at gmail dot com
PHP 5.2.5RC2-dev (cli) (built: Oct 29 2007 21:22:10):

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1211684448 (LWP 31245)]
zend_lookup_class_ex (name=0xb722e018 'a' <repeats 200 times>..., 
    name_length=10000000, use_autoload=0, ce=0xbfa0c498)
    at /home/felipe/php5.2-200710292130/Zend/zend_execute_API.c:1046
1046            zend_str_tolower_copy(lc_name, name, name_length);
 [2007-10-30 00:14 UTC] crrodriguez at suse dot de
Always reproducible on linux64 bit hosts.
 [2007-10-30 08:21 UTC] derick@php.net
Segfaults for me too, looks like a stack smash with valgrind:


==7344== Warning: client switching stacks?  SP change: 0x7FEFFD9A0 --> 0x7FE674310
==7344==          to suppress, use: --max-stackframe=10000016 or greater
==7344== Invalid write of size 8
==7344==    at 0x85D4D3: zend_lookup_class_ex (zend_execute_API.c:1046)
==7344==  Address 0x7FE674308 is on thread 1's stack
==7344== 
==7344== Process terminating with default action of signal 11 (SIGSEGV)
==7344==  Access not within mapped region at address 0x7FE674308
==7344==    at 0x85D4D3: zend_lookup_class_ex (zend_execute_API.c:1046)
==7344== 
==7344== Invalid write of size 8
==7344==    at 0x4A1E310: _vgnU_freeres (vg_preloaded.c:56)
==7344==  Address 0x7FE674300 is on thread 1's stack
==7344== 
==7344== Process terminating with default action of signal 11 (SIGSEGV)
==7344==  Access not within mapped region at address 0x7FE674300

Which makes sense, as lc_name in 
zend_lookup_class_ex() is allocated on line 1045 with:

    lc_name = do_alloca(name_length + 1);
    zend_str_tolower_copy(lc_name, name, name_length);

SPL and Reflection have the same problem in the files:

ext/spl/php_spl.c
ext/reflection/php_reflection.c

A possible fix would be to set an arbitrary limit on the name of classes here...

 [2007-10-30 10:37 UTC] crrodriguez at suse dot de
Index: Zend/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.331.2.20.2.24.2.8
diff -u -p -r1.331.2.20.2.24.2.8 zend_execute_API.c
--- Zend/zend_execute_API.c     7 Oct 2007 05:22:03 -0000       1.331.2.20.2.24.2.8
+++ Zend/zend_execute_API.c     30 Oct 2007 10:14:29 -0000
@@ -1073,6 +1073,10 @@ ZEND_API int zend_lookup_class_ex(const
        if (name == NULL || !name_length) {
                return FAILURE;
        }
+
+       if(name_length >= ZEND_MAX_CLASSNAME_LEN) {
+               zend_error(E_ERROR, "Class name cannot be longer than %d", ZEND_MAX_CLASSNAME_LEN);
+       }

        lc_free = lc_name = do_alloca(name_length + 1);
        zend_str_tolower_copy(lc_name, name, name_length);
Index: Zend/zend.h
===================================================================
RCS file: /repository/ZendEngine2/zend.h,v
retrieving revision 1.293.2.11.2.9.2.7
diff -u -p -r1.293.2.11.2.9.2.7 zend.h
--- Zend/zend.h 7 Oct 2007 05:22:02 -0000       1.293.2.11.2.9.2.7
+++ Zend/zend.h 30 Oct 2007 10:14:29 -0000
@@ -712,7 +712,7 @@ END_EXTERN_C()


 #define ZEND_MAX_RESERVED_RESOURCES    4
-
+#define ZEND_MAX_CLASSNAME_LEN                 65535
 #include "zend_operators.h"
 #include "zend_variables.h"


ZEND_MAX_CLASSNAME_LEN being the same as java, not to mention that I dont see any reason why such insane long naming will be useful :-)

HTH.
 [2007-10-30 10:48 UTC] derick@php.net
That would already allocate 64kb on the stack, I doubt that will work on all systems. I would suggest a somewhat smaller limit, say 1024?
 [2007-10-30 11:42 UTC] crrodriguez at suse dot de
Yes, an smaller limit like 1024 looks OK and is still high enough to avoid annoying insane coders ;-)
 [2007-11-13 09:59 UTC] dmitry@php.net
The suggested patch is going to fix only one place, however the same stack overflow may be reached using several other places which use do_alloca(). I'll try to think about general solution.
 [2007-11-14 23:34 UTC] jani@php.net
See also bug #43298

 [2007-11-22 13:34 UTC] dmitry@php.net
Fixed in CVS HEAD and PHP_5_3.
 [2008-02-15 07:45 UTC] dmitry@php.net
Fixed in PHP_5_2 too.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC