php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63159 Passing > 1 additional module to php_module_startup causes a segfault
Submitted: 2012-09-25 02:06 UTC Modified: 2013-12-04 02:23 UTC
Votes:3
Avg. Score:4.3 ± 0.9
Reproduced:2 of 3 (66.7%)
Same Version:0 (0.0%)
Same OS:1 (50.0%)
From: slangley at google dot com Assigned: pollita
Status: Closed Package: Reproducible crash
PHP Version: 5.4.7 OS: N/A
Private report: No CVE-ID:
 [2012-09-25 02:06 UTC] slangley at google dot com
Description:
------------
This was reported in 2004 but seemingly never fixed?

http://marc.info/?l=php-internals&m=110257814320454&w=2

php_module_startup expects a pointer to an array of structures of 
zend_module_entry. This gets passed to php_register_extensions which expects an 
array of points to structures of zend_module_entry. php_register_extensions then 
tries to use pointer arithmetic to walk along the passed array, which will cause a 
seg fault.

I will make a pull request on github with this fix.

Test script:
---------------
Write a SAPI, pass > 2 additional modules to php_module_startup.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-09-25 09:42 UTC] laruence@php.net
I am not sure, is this just a wrong usage of ZEND API?
 [2012-09-25 10:34 UTC] slangley at google dot com
Not sure how that might be ...

Here's the signature for php_module_startup

int php_module_startup(sapi_module_struct *sf, zend_module_entry 
*additional_modules, uint num_additional_modules);

The parameter num_additional_modules suggests that more then one module_entry 
can be passed in the additional_modules argument, but it's only a pointer not an 
array of pointers.

Here's the signature for php_register_extensions, which is called from 
php_module_startup.

int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC);

This more correctly takes an array of pointers.

I don't know why this wasn't fixed when first reported in 2004 - I couldn't find 
any more information than the thread I linked.
 [2013-01-28 00:56 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2013-01-28 00:56 UTC] stas@php.net
Could you add some (short) code that would help to reproduce the problem?
 [2013-01-28 09:21 UTC] slangley at google dot com
Sure - this will result in a segfault.

int register_moules(sapi_module_struct* sapi_module) {

  zend_module_entry modules[] = {
      my_module_1_entry,
      my_module_2_entry,
  };
  int module_count = sizeof(modules) / sizeof(zend_module_entry);

  return php_module_startup(sapi_module, modules, module_count);
}
 [2013-01-28 09:41 UTC] pajoye@php.net
Works just fine here.

Which architecture do you use? Maybe some rounding issues? 

However I would suggest you to manually set the modules count to the right numbers 
instead, to avoid any kind of architecture specific troubles.
 [2013-01-28 10:25 UTC] slangley at google dot com
Suggest you look again - it is not possible to get past this line without 
segfaulting if there is more than one extension.

https://github.com/php/php-src/blob/master/main/main.c#L2191
 [2013-01-28 10:28 UTC] pajoye@php.net
http://lxr.php.net/xref/PHP_5_4/main/main.c#1910 looks perfectly fine to me.

Which value do you actually pass as count? Also provide a backtrace.
 [2013-01-28 10:35 UTC] slangley at google dot com
I'll grab you a stack trace when I'm in to office tomorrow (need to remove my 
patch to get it to crash :)).... However you can pretty easily walk through the 
code.

int php_module_startup(sapi_module_struct *sf, zend_module_entry 
*additional_modules, uint num_additional_modules)

Takes a pointer to an array of zend_module_entry.

int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC)


takes a pointer to an array of zend_module_entry pointers.

inside php_register_extensions it uses pointer arithmetic to enumerate the 
extensions. However, because php_module_startup has a pointer to an array of 
zend_module_entry rather than a pointer to an array of pointers of 
zend_module_entry it causes a segfault.

https://github.com/php/php-src/blob/master/main/main.c#L1961

https://github.com/php/php-src/blob/master/main/main.c#L1909
 [2013-01-28 10:44 UTC] pajoye@php.net
oh, stupid me, coffee++ :-)

You must be the 1st to call it with more than one ;-)
 [2013-01-28 10:46 UTC] slangley at google dot com
Well according to this I'm not :) 

http://marc.info/?l=php-internals&m=110121150631159&w=2
 [2013-02-18 00:36 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
 [2013-05-20 08:24 UTC] stas@php.net
-Status: No Feedback +Status: Open
 [2013-12-04 02:23 UTC] pollita@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: pollita
 [2013-12-04 02:23 UTC] pollita@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

https://github.com/php/php-src/commit/00a7b1ff7fed49df51d0392d47aa79f63bf1c66e
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 19:02:15 2014 UTC