View Issue Details

IDProjectCategoryView StatusLast Update
0000931Xdebugpublic2013-05-22 03:51
Reporterpayden Assigned Toderick  
PrioritynormalSeveritycrashReproducibilityalways
Status closedResolutionfixed 
Product Version2.2.1 
Target Version2.2.3Fixed in Version2.2.3 
Summary0000931: xdebug_str_add does not check for NULL str before calling strlen on it.
Description

I suppose it may just be assumed that calling code should never call xdebug_str_add with a NULL str, but the case is definitely not checked and it has happened in the wild. Serialization of a closure is definitely not allowed in PHP and throws an exception (PHP Bug #64168). When this happens xdebug_str_add gets called with NULL str. I haven't studied xdebug code extensively, but it looks like XG(last_exception_trace) is null in xdebug_error_cb which is called from zend_error_va in zend_exceptions.c. Let me just shut up and post the backtrace:

#0 __strlen_sse2_bsf () at ../sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S:51
#1 0xb6d13b6e in xdebug_str_add (xs=xs@entry=0xbfffdda8, str=0x0, f=f@entry=0)
at /home/payden/xdebug/xdebug_str.c:33
0000002 0xb6d13380 in xdebug_error_cb (type=1,
error_filename=0xb706f294 "[no active file]", error_lineno=0,
format=0x88c86bd "Uncaught %s\n thrown",
args=0xbfffde20 "h\364\006\267L\336\377\277")
at /home/payden/xdebug/xdebug_stack.c:639
0000003 0x083ff070 in zend_error_va (type=type@entry=1,
file=0xb706f294 "[no active file]", lineno=0,
format=format@entry=0x88c86bd "Uncaught %s\n thrown")
at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:791
0000004 0x0840119a in zend_exception_error (exception=0xb706f2f4,
severity=severity@entry=1)
at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:831
0000005 0x08401369 in zend_throw_exception_internal (exception=0xb706f2f4)
at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:110
0000006 zend_throw_exception_internal (exception=0xb706f2f4)
at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:84
0000007 0x08401442 in zend_throw_exception (exception_ce=0x89cafd8,
exception_ce@entry=0x0,

I dunno, it seems awfully trivial, but should there just be a:

if (!str) {
return;
}

at the beginning of xdebug_add_str?

Steps To Reproduce

Tested with PHP-5.4.12 and Xdebug 2.2.1 and 2.2.0

<?php
session_start();
$_SESSION['test'] = function() { };

TagsNo tags attached.
Operating SystemUbuntu 12.10 32-bit
PHP Version5.4.10-5.4.14

Activities

payden

2013-03-04 03:28

reporter   ~0002435

I've looked into this a bit and I'm unsure whether this would be classified as an xdebug problem or PHP problem, but essentially this segfault
is going to happen anytime there is an exception thrown without a stack frame and xdebug is enabled, (I think). In Zend/zend_exceptions.c
line 110 zend_exception_error calls zend_error_va which calls zend_error_cb which is xdebug_error_cb with xdebug enabled. xdebug_error_cb
calls xdebug_str_add with XG(last_exception_trace) = NULL which eventually causes a strlen(NULL). XG(last_exception_trace) gets set in
xdebug_throw_exception_hook which is never called in the case of an exception without a stack. Trivial solution is to check for NULL in
xdebug_str_add which I've submitted a pull request to do this to xdebug. I think it should probably check for NULL anyway. It's not like
it's expensive? Maybe, I'm mistaken there though. IMHO it seems that xdebug should handle the case of xdebug_error_cb being called with
last_exception_trace = NULL or PHP should ensure zend_throw_exception_hook is called before zend_error_cb? I've tried putting the
zend_throw_exception_hook call ahead of the zend_error_cb in zend_exceptions.c and xdebug seems to handle that okay. I get the following in
that case:

Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in [no active file] on line 0

Exception: Serialization of 'Closure' is not allowed in [no active file] on line 0

This is similar to what I get when I have a script just throw an uncaught exception except there is no stack trace from xdebug. (Obviously)

I'm still a PHP internals newbie though, so I'm not sure if that is the "right" thing to do.

Backtrace:

PHP-5.4.12/xdebug-2.2.1

(gdb) bt
#0 __strlen_sse2_bsf () at ../sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S:51
#1 0xb6d13b0e in xdebug_str_add (xs=xs@entry=0xbfffdd88, str=0x0, f=f@entry=0) at /home/payden/payden-xdebug/xdebug_str.c:33
0000002 0xb6d13320 in xdebug_error_cb (type=1, error_filename=0xb706f2c8 "[no active file]", error_lineno=0, format=0x88c867d "Uncaught %s\n
thrown",
args=0xbfffde00 "\020\002\a\267,\336\377\277") at /home/payden/payden-xdebug/xdebug_stack.c:639
0000003 0x083ff040 in zend_error_va (type=type@entry=1, file=0xb706f2c8 "[no active file]", lineno=0, format=format@entry=0x88c867d "Uncaught %s\n
thrown")
at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:791
0000004 0x0840116a in zend_exception_error (exception=0xb706ec54, severity=severity@entry=1) at /home/payden/.src/php-
5.4.12/Zend/zend_exceptions.c:831
0000005 0x08401339 in zend_throw_exception_internal (exception=0xb706ec54) at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:110
0000006 zend_throw_exception_internal (exception=0xb706ec54) at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:84
0000007 0x08401412 in zend_throw_exception (exception_ce=0x89caff8, exception_ce@entry=0x0, message=0xb706f124 "Serialization of 'Closure' is not
allowed",
code=code@entry=0) at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:758
0000008 0x08401505 in zend_throw_exception_ex (exception_ce=exception_ce@entry=0x0, code=code@entry=0,
format=format@entry=0x88c82ac "Serialization of '%s' is not allowed") at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:772
0000009 0x083fe722 in zend_class_serialize_deny (object=0xb706ec8c, buffer=0xbfffdf64, buf_len=0xbfffdf68, data=0xb706fea0)
at /home/payden/.src/php-5.4.12/Zend/zend_interfaces.c:487
0000010 0x0832ab5d in php_var_serialize_intern (buf=buf@entry=0xbfffe024, struc=0xb706ec8c, var_hash=0xb706fea0)
at /home/payden/.src/php-5.4.12/ext/standard/var.c:777
0000011 0x0833092b in php_var_serialize (buf=buf@entry=0xbfffe024, struc=0xb706f450, var_hash=var_hash@entry=0xbfffe010)
at /home/payden/.src/php-5.4.12/ext/standard/var.c:899
0000012 0x0826e654 in ps_srlzr_encode_php (newstr=0xbfffe06c, newlen=0xbfffe0ac) at /home/payden/.src/php-5.4.12/ext/session/session.c:857
0000013 0x0826a4e8 in php_session_encode (newlen=newlen@entry=0xbfffe0ac) at /home/payden/.src/php-5.4.12/ext/session/session.c:203
0000014 0x0826a5a3 in php_session_save_current_state () at /home/payden/.src/php-5.4.12/ext/session/session.c:487
0000015 php_session_flush () at /home/payden/.src/php-5.4.12/ext/session/session.c:1453
0000016 0x0826b405 in zm_deactivate_session (type=1, module_number=32) at /home/payden/.src/php-5.4.12/ext/session/session.c:2144
0000017 0x083eea0c in zend_deactivate_modules () at /home/payden/.src/php-5.4.12/Zend/zend_API.c:2335
0000018 0x0838a445 in php_request_shutdown (dummy=dummy@entry=0x0) at /home/payden/.src/php-5.4.12/main/main.c:1769
0000019 0x08487e6f in do_cli (argc=0, argc@entry=2, argv=0x7) at /home/payden/.src/php-5.4.12/sapi/cli/php_cli.c:1171
0000020 0x08070047 in main (argc=2, argv=0xbffff764) at /home/payden/.src/php-5.4.12/sapi/cli/php_cli.c:1364
(gdb) f 5
0000005 0x08401339 in zend_throw_exception_internal (exception=0xb706ec54) at /home/payden/.src/php-5.4.12/Zend/zend_exceptions.c:110
110 zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
(gdb) print executor_globals.current_execute_data
$3 = (struct _zend_execute_data *) 0x0

derick

2013-05-19 18:32

administrator   ~0002476

Your fix hides the symptom, but I've made sure that your code example now works.

Issue History

Date Modified Username Field Change
2013-03-04 00:37 payden New Issue
2013-03-04 03:28 payden Note Added: 0002435
2013-05-19 18:32 derick Note Added: 0002476
2013-05-19 18:32 derick Status new => closed
2013-05-19 18:32 derick Assigned To => derick
2013-05-19 18:32 derick Resolution open => fixed
2013-05-19 18:32 derick Fixed in Version => 2.2.3
2013-05-22 03:51 derick Target Version => 2.2.3
2016-07-31 12:35 derick Category Debug client (console) => debugclient (debugging tool)
2016-07-31 12:35 derick Category debugclient (debugging tool) => (No Category)