php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59023 SEGFAULT - Queries with too many closing parentheses
Submitted: 2010-01-07 10:10 UTC Modified: 2010-02-05 05:13 UTC
From: nick dot telford at gmail dot com Assigned:
Status: Closed Package: sphinx (PECL)
PHP Version: 5.2.9 OS: Linux (CentOS 5.4)
Private report: No CVE-ID: None
 [2010-01-07 10:10 UTC] nick dot telford at gmail dot com
Description:
------------
When submitting a query to Sphinx, the client segfaults if the query contains any closing parentheses with no associated opening parentheses.

Example queries that work as expected:

something
(something)
(something

Example queries that cause a segfault:
something)
(something))

gdb backtrace (attained through apache):

Program received signal SIGSEGV, Segmentation fault.
php_sphinx_result_to_array (c=0x2ad90ac2c390, result=0x2ad90a9bf230, array=0x7fff22366cc0) at /var/tmp/sphinx/sphinx.c:179
179	/var/tmp/sphinx/sphinx.c: No such file or directory.
	in /var/tmp/sphinx/sphinx.c
(gdb) bt
#0  php_sphinx_result_to_array (c=0x2ad90ac2c390, result=0x2ad90a9bf230, array=0x7fff22366cc0) at /var/tmp/sphinx/sphinx.c:179
#1  0x00002ad9095fc4d3 in zim_SphinxClient_runQueries (ht=<value optimized out>, return_value=0x2ad90abd6930, return_value_ptr=<value optimized out>, this_ptr=<value optimized out>, return_value_used=<value optimized out>) at /var/tmp/sphinx/sphinx.c:1344
#2  0x00002ad9077ccb51 in ?? () from /usr/lib64/php/modules/dbg-php-5.2.so
#3  0x00002ad901e53a43 in ?? () from /etc/httpd/modules/libphp5.so
#4  0x00002ad901e4624c in execute () from /etc/httpd/modules/libphp5.so
#5  0x00002ad9077cfdb5 in ?? () from /usr/lib64/php/modules/dbg-php-5.2.so
#6  0x00002ad901e53684 in ?? () from /etc/httpd/modules/libphp5.so
#7  0x00002ad901e4624c in execute () from /etc/httpd/modules/libphp5.so
#8  0x00002ad9077cfdb5 in ?? () from /usr/lib64/php/modules/dbg-php-5.2.so
#9  0x00002ad901e53684 in ?? () from /etc/httpd/modules/libphp5.so
#10 0x00002ad901e4624c in execute () from /etc/httpd/modules/libphp5.so
#11 0x00002ad9077cfdb5 in ?? () from /usr/lib64/php/modules/dbg-php-5.2.so
#12 0x00002ad901e53684 in ?? () from /etc/httpd/modules/libphp5.so
#13 0x00002ad901e4624c in execute () from /etc/httpd/modules/libphp5.so
#14 0x00002ad9077cfdb5 in ?? () from /usr/lib64/php/modules/dbg-php-5.2.so
#15 0x00002ad901e53684 in ?? () from /etc/httpd/modules/libphp5.so
#16 0x00002ad901e4624c in execute () from /etc/httpd/modules/libphp5.so
#17 0x00002ad9077cfdb5 in ?? () from /usr/lib64/php/modules/dbg-php-5.2.so
#18 0x00002ad901e267e3 in zend_execute_scripts () from /etc/httpd/modules/libphp5.so
#19 0x00002ad901de6878 in php_execute_script () from /etc/httpd/modules/libphp5.so
#20 0x00002ad901ea937d in ?? () from /etc/httpd/modules/libphp5.so
#21 0x00002ad8fa799a4a in ap_run_handler () from /usr/sbin/httpd
#22 0x00002ad8fa79cec2 in ap_invoke_handler () from /usr/sbin/httpd
#23 0x00002ad8fa7a776a in ap_internal_redirect () from /usr/sbin/httpd
#24 0x00002ad9015fcbc0 in ?? () from /etc/httpd/modules/mod_rewrite.so
#25 0x00002ad8fa799a4a in ap_run_handler () from /usr/sbin/httpd
#26 0x00002ad8fa79cec2 in ap_invoke_handler () from /usr/sbin/httpd
#27 0x00002ad8fa7a7918 in ap_process_request () from /usr/sbin/httpd
#28 0x00002ad8fa7a4b50 in ?? () from /usr/sbin/httpd
#29 0x00002ad8fa7a0cb2 in ap_run_process_connection () from /usr/sbin/httpd
#30 0x00002ad8fa7ab859 in ?? () from /usr/sbin/httpd
#31 0x00002ad8fa7aba59 in ?? () from /usr/sbin/httpd
#32 0x00002ad8fa7ac577 in ap_mpm_run () from /usr/sbin/httpd
#33 0x00002ad8fa786e48 in main () from /usr/sbin/httpd

Reproduce code:
---------------
$sphinx = new SphinxClient();
$sphinx->setSetver('localhost', 3312);
$sphinx->addQuery('something)');
$results = $sphinx->runQueries();
var_dump($results);

// SphinxClient::query() has the same problem, but out code uses batched queries, so that is what I've used in the reproduce code

Expected result:
----------------
array(
)

(or an array of results, if you happen to have a dataset that will match that query)

Actual result:
--------------
segmentation fault

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-01-09 03:38 UTC] tony at daylessday dot org
Please try newer Sphinx client library version first (you'll probably need to rebuild the extension, too).
The extension doesn't care how much brackets you use, so it seems that the client lib returns b0rked query result.
Would be nice if you rebuild the library with CFLAGS="-g2 -O0", the extension (and PHP) with --enable-debug and post `bt full` result here.
 [2010-01-25 04:47 UTC] nick dot telford at gmail dot com
My test script is missing something vital, should be:
<?php
$sphinx = new SphinxClient();
$sphinx->setServer('localhost', 3312);
$sphinx->setMatchMode(SPH_MATCH_EXTENDED2);
$sphinx->addQuery('something)');
$results = $sphinx->runQueries();
var_dump($results);

It's only caused if the match mode is set to SPH_MATCH_EXTENDED2. I believe you're right and that this is a libsphinxclient issue. Unless I hear otherwise from you, I'm going to flag this up as an issue with them.

Thanks for your help, the following is a full backtrace, taken as instructed:

[Thread debugging using libthread_db enabled]
[New Thread 0x2b76c199ff50 (LWP 11326)]

Program received signal SIGSEGV, Segmentation fault.
0x00000000005e3eae in php_sphinx_result_to_array (c=0x2b76c52079e0, result=0x7bdbd18, array=0x7fffb8b84c60) at /home/alex/build/php-5.2.11_tm/ext/sphinx/sphinx.c:179
179         add_next_index_string(tmp, result->fields[i], 1);
(gdb) bt full
#0  0x00000000005e3eae in php_sphinx_result_to_array (c=0x2b76c52079e0, result=0x7bdbd18, array=0x7fffb8b84c60) at /home/alex/build/php-5.2.11_tm/ext/sphinx/sphinx.c:179
    tmp = (zval *) 0x7c9d788
    tmp_element = (zval *) 0x6fe9bb
    sub_element = (zval *) 0x7bb91b8
    sub_sub_element = (zval *) 0x722e50
    i = 0
    j = 0
#1  0x00000000005e8b95 in zim_SphinxClient_runQueries (ht=0, return_value=0x7bb0f88, return_value_ptr=0x0, this_ptr=0x7bb0f18, return_value_used=1) at /home/alex/build/php-5.2.11_tm/ext/sphinx/sphinx.c:1344
    c = (php_sphinx_client *) 0x2b76c52079e0
    results = (sphinx_result *) 0x7bdbd18
    i = 0
    num_results = 1
    single_result = (zval *) 0x7bb91b8
#2  0x000000000074892a in zend_do_fcall_common_helper_SPEC (execute_data=0x7fffb8b85150) at /home/alex/build/php-5.2.11_tm/Zend/zend_vm_execute.h:200
    return_reference = 0 '\0'
    opline = (zend_op *) 0x2b76c51f6fd0
    original_return_value = (zval **) 0x71b393
    current_scope = (zend_class_entry *) 0x7c61e00
    current_this = (zval *) 0x7bb0f18
    return_value_used = 1
    should_change_scope = 1 '\001'
    ctor_opline = (zend_op *) 0x74b069
#3  0x00000000007496d5 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7fffb8b85150) at /home/alex/build/php-5.2.11_tm/Zend/zend_vm_execute.h:322
No locals.
#4  0x00000000007483cb in execute (op_array=0x2b76c5207600) at /home/alex/build/php-5.2.11_tm/Zend/zend_vm_execute.h:92
    execute_data = {opline = 0x2b76c51f6fd0, function_state = {function_symbol_table = 0x0, function = 0x7b683e0, reserved = {0x7bb9650, 0x7fffb8b85190, 0xc0cd4f98a04f5e18, 0x1807bb1ba8}}, fbc = 0x7b683e0, 
  op_array = 0x2b76c5207600, object = 0x7bb0f18, Ts = 0x7fffb8b84dd0, CVs = 0x7fffb8b84d90, original_in_execution = 1 '\001', symbol_table = 0x7bea8e8, prev_execute_data = 0x7fffb8b85d50, old_error_reporting = 0x0}
#5  0x0000000000748ab9 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fffb8b85d50) at /home/alex/build/php-5.2.11_tm/Zend/zend_vm_execute.h:234
    opline = (zend_op *) 0x7bb2d48
    original_return_value = (zval **) 0x7fffb8b85e48
    current_scope = (zend_class_entry *) 0x0
    current_this = (zval *) 0x0
    return_value_used = 1
    should_change_scope = 1 '\001'
    ctor_opline = (zend_op *) 0x326161bbc0
#6  0x00000000007496d5 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7fffb8b85d50) at /home/alex/build/php-5.2.11_tm/Zend/zend_vm_execute.h:322
No locals.
#7  0x00000000007483cb in execute (op_array=0x7baf1d0) at /home/alex/build/php-5.2.11_tm/Zend/zend_vm_execute.h:92
    execute_data = {opline = 0x7bb2d48, function_state = {function_symbol_table = 0x7bea8e8, function = 0x2b76c5207600, reserved = {0x7baf310, 0x7fffb8b85db0, 0x712ae3, 0x0}}, fbc = 0x2b76c5207600, op_array = 0x7baf1d0, 
  object = 0x7bb0f18, Ts = 0x7fffb8b85320, CVs = 0x7fffb8b852e0, original_in_execution = 0 '\0', symbol_table = 0xce2848, prev_execute_data = 0x0, old_error_reporting = 0x0}
#8  0x000000000071f47a in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/alex/build/php-5.2.11_tm/Zend/zend.c:1134
    files = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fffb8b85f60, reg_save_area = 0x7fffb8b85ea0}}
    i = 1
    file_handle = (zend_file_handle *) 0x7fffb8b883a0
    orig_op_array = (zend_op_array *) 0x0
    orig_retval_ptr_ptr = (zval **) 0x0
    local_retval = (zval *) 0x0
#9  0x00000000006c48d1 in php_execute_script (primary_file=0x7fffb8b883a0) at /home/alex/build/php-5.2.11_tm/main/main.c:2020
    realfile = "/var/www/tweetmeme4/public/index.php\000\177\000\000&#65533;&#65533;&#65533;", '\0' <repeats 13 times>, "&#65533;\205&#65533;&#65533;&#65533;\177", '\0' <repeats 26 times>, "\025&#65533;@a2\000\000\000\001", '\0' <repeats 31 times>, "hB\200a2\000\000\000&#65533;&#65533;aa2\000\000\000&#65533;p&#65533;&#65533;&#65533;\177\000\000\222(Aa2\000\000\000&#65533;Qz\000\000\000\000\000\000&#65533;\237\000\000\000\000\000\220A&#65533;\a\000\000\000\000Z&#65533;r\000\000\000\000\000\200\027&#65533;a2\000\000\000\004\000\000\000\000\000\000\000\200\027&#65533;a2\000\000\000&#65533;\021\206a2\000\000\000&#65533;&#65533;aa2\000\000\000\000Rz\000\000\000\000\000"...
    __orig_bailout = (jmp_buf *) 0x7fffb8b88210
    __bailout = {{__jmpbuf = {216382159808, -8268687197646134416, 0, 140736292488640, 0, 0, -8268687197646111424, -8268671372701490093}, __mask_was_saved = 0, __saved_mask = {__val = {140736292487232, 140736292487232, 7334446, 
        129857264, 3099099248, 0, 2452426326016, 10666792, 129688824, 140736292487504, 8018297, 10666792, 524, 0, 0, 3}}}}
    prepend_file_p = (zend_file_handle *) 0x0
    append_file_p = (zend_file_handle *) 0x0
    prepend_file = {type = 0 '\0', filename = 0x0, opened_path = 0x0, handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, reader = 0, closer = 0, fteller = 0, interactive = 0}}, free_filename = 0 '\0'}
    append_file = {type = 0 '\0', filename = 0x0, opened_path = 0x0, handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, reader = 0, closer = 0, fteller = 0, interactive = 0}}, free_filename = 0 '\0'}
    old_cwd = 0x7fffb8b85f80 ""
    retval = 0
#10 0x00000000007a69a5 in main (argc=2, argv=0x7fffb8b885c8) at /home/alex/build/php-5.2.11_tm/sapi/cli/php_cli.c:1162
    __orig_bailout = (jmp_buf *) 0x0
---Type <return> to continue, or q <return> to quit---
    __bailout = {{__jmpbuf = {216382159808, -8268687197646133568, 0, 140736292488640, 0, 0, -8268687197646134464, -8268671372700828223}, __mask_was_saved = 0, __saved_mask = {__val = {140736292487808, 4287062190, 140736292488208, 
        140736292488232, 216384158344, 0, 47789054223584, 47789052002304, 216421996075, 216384207904, 216421919048, 4294967296, 4294968490, 140736292488272, 216379984919, 140736292488288}}}}
    exit_status = 0
    c = -1
    file_handle = {type = 2 '\002', filename = 0x7fffb8b88c0c "index.php", opened_path = 0x0, handle = {fd = 129856336, fp = 0x7bd7350, stream = {handle = 0x7bd7350, reader = 0x738e44 <zend_stream_stdio_reader>, 
      closer = 0x738e70 <zend_stream_stdio_closer>, fteller = 0x738e97 <zend_stream_stdio_fteller>, interactive = 0}}, free_filename = 0 '\0'}
    behavior = 1
    reflection_what = 0x0
    orig_optind = 1
    orig_optarg = 0x0
    arg_free = 0x7fffb8b88c0c "index.php"
    arg_excp = (char **) 0x7fffb8b885d0
    script_file = 0x7fffb8b88c0c "index.php"
    interactive = 0
    module_started = 1
    request_started = 1
    lineno = 1
    exec_direct = 0x0
    exec_run = 0x0
    exec_begin = 0x0
    exec_end = 0x0
    param_error = 0x0
    hide_argv = 0
    ini_entries_len = 110
 [2010-01-26 08:07 UTC] santiago739 at gmail dot com
I can't reproduce SEGFAULT using your reproduce code. For me 
it works fine on both libsphinxclient (from sphinx 0.9.8 and 
0.9.9). 
Could you specify the version of libsphinxclient and 
PECL/Sphinx you use?
 [2010-01-26 12:31 UTC] nick dot telford at gmail dot com
libsphinxclient - 0.9.9
pecl/sphinx - 1.0.3

Both were compiled from source to enable to debug flags.

Probably worth noting our distro/arch: 
CentOS 5.4 x86_64

Kernel:
2.6.18-164.6.1.el5
 [2010-01-26 12:33 UTC] nick dot telford at gmail dot com
Just to clarify, are you using the reproduce code from my second comment (3rd in thread)?

My original reproduce code was wrong and missing a crucial line: $sphinx->setMatchMode(SPH_MATCH_EXTENDED2);
 [2010-01-29 05:19 UTC] santiago739 at gmail dot com
Yes, I used code from you last comment. 
Do you have the same issue with cli-sapi and libphp5?

Thanks for your response.
 [2010-01-29 09:46 UTC] santiago739 at gmail dot com
In addition, it would be great if you print these variables 
after backtrace (in GDB) and post result here:

p *result
p i
p result->fields[i]
 [2010-01-29 11:01 UTC] nick dot telford at gmail dot com
Requested values:
(gdb) p *result
$1 = {error = 0xcc38de7 "index <index name>: syntax error, unexpected ')', expecting $end near ')'", warning = 0x0, status = 1, num_fields = 1025534068, fields = 0x0, num_attrs = 1953702944, attr_names = 0x0, attr_types = 0x0, num_matches = 1965301800, 
  values_pool = 0x0, total = 538970683, total_found = 1868963872, time_msec = 606609522, num_words = 540876905, words = 0x0}
(gdb) p i
$2 = 1
(gdb) p result->fields[i]
Cannot access memory at address 0x8
(gdb) p result->fields
$3 = (char **) 0x0

Note: <index name> is in place of the name of the real index for obfuscation purposes.

Seems that the client is returning a valid error state to me, I'm not sure if that's expected. I'm assuming that the syntax error is in the query, and not the index configuration. Nevertheless, I will check out index config to see if there's anything there that might explain it.
 [2010-01-29 11:14 UTC] nick dot telford at gmail dot com
Ok, now I know what the problem actually is, I've managed to ascertain:

- There is no bug in libsphinxclient
- There is no problem with parentheses specifically, it's just invalid queries.
- pecl/sphinx doesn't (apparently) detect query errors.

Therefore, it seems that the only real bug here is that pecl/sphinx needs to detect errors (result->status == 1) and relay the error to the client instead of attempting to parse a (non-existent) result set.

Would you like me to raise this as another, separate bug (closing this one) or edit the summary of this one?
 [2010-01-31 08:48 UTC] santiago739 at gmail dot com
It seems that result->num_fields contains garbage and it causes segfault.
Please, try this this patch (thanks Tony)
http://dev.daylessday.org/diff/pecl_bug17007.diff
 [2010-02-03 06:50 UTC] nick dot telford at gmail dot com
Applied the patch, it appears to fix the problem.

Regardless, this does feel a little like a workaround for an upstream bug. Should we report this with libsphinxclient?

Also, by the looks of the patch it doesn't relay the error back to the calling code. This is a shame, since libsphinxclient goes to some length to report the nature of the parse error, it might be nice to be able to access this information when if the query fails.

Can I assume that this patch will be applied in the next stable release of pecl/sphinx?

Cheers for your help and hard work guys.
 [2010-02-05 03:49 UTC] santiago739 at gmail dot com
1. I'm not sure that this is a bug in libsphinxclient. I 
would say it's a kind of undocumented behavior.

2. With this patch I expect the same error message and 
result array as with native PHP API.

3. Sure. this bug will be fixed in the next release 
PECL/Sphinx
 [2010-02-05 05:13 UTC] santiago739 at gmail dot com
This bug has been fixed in SVN.

In case this was a documentation problem, the fix will show up at the
end of next Sunday (CET) on pecl.php.net.

In case this was a pecl.php.net website problem, the change will show
up on the website in short time.
 
Thank you for the report, and for helping us make PECL better.


 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Dec 07 00:03:49 2021 UTC