Bug 26390

Summary: dbus-1.3.0 segfaults when running testsuite on IRIX
Product: dbus Reporter: Stuart Shelton <srcshelton>
Component: coreAssignee: Havoc Pennington <hp>
Status: RESOLVED DUPLICATE QA Contact: John (J5) Palmieri <johnp>
Severity: major    
Priority: medium    
Version: 1.3.x (devel)   
Hardware: SGI   
OS: IRIX   
Whiteboard:
i915 platform: i915 features:

Description Stuart Shelton 2010-02-02 08:35:57 UTC
The 'dbus-daemon' executable segfaults when running with '--introspect', and the dbus test-suite fails in a similar way.

The host system is a dual-processor SGI Octane/IP30 with 8GB RAM running a 64-bit IRIX 6.5.30 kernel with MIPSpro Compilers 7.4.4m, targeting the n32 ABI and mips4 ISA.

'make check' output:

Making check in dbus
make[1]: Entering directory `work/dbus-1.3.0-tests-build/dbus'
make  check-am
make[2]: Entering directory `work/dbus-1.3.0-tests-build/dbus'
make  check-TESTS
make[3]: Entering directory `work/dbus-1.3.0-tests-build/dbus'
Test data in ../test/data
dbus-test: running string tests
dbus-test: checking for memleaks
dbus-test: running sysdeps tests
dbus-test: checking for memleaks
dbus-test: running data-slot tests
dbus-test: checking for memleaks
dbus-test: running misc tests
dbus-test: checking for memleaks
dbus-test: running address tests
/opt/gentoo/bin/bash: line 4: 296283 Segmentation fault      (core dumped) DBUS_TEST_DATA=../test/data DBUS_TEST_HOMEDIR=../dbus ${dir}$tst
FAIL: dbus-test
==================
1 of 1 test failed
==================
make[3]: *** [check-TESTS] Error 1
make[3]: Leaving directory `work/dbus-1.3.0-tests-build/dbus'
make[2]: *** [check-am] Error 2
make[2]: Leaving directory `work/dbus-1.3.0-tests-build/dbus'
make[1]: *** [check] Error 2
make[1]: Leaving directory `work/dbus-1.3.0-tests-build/dbus'
make: *** [check-recursive] Error 1


Debugger analysis of core:

$ dbx dbus-test core
dbx version 7.3.4 (86441_Nov11 MR) Nov 11 2002 11:31:55
Core from signal SIGSEGV: Segmentation violation
(dbx) where

Thread 0x10000
>  0 realfree(0x100b8810, 0x100b8d48, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["/xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/malloc.c":527, 0xfa448a8]
   1 __malloc(0x28, 0x100b8d48, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["/xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/malloc.c":297, 0xfa4468c]
   2 _malloc(0x26, 0x100b8d48, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["/xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/malloc.c":186, 0xfa44514]
   3 dbus_malloc(0x100b8810, 0x100b8d48, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-memory.c":471, 0x10014aa0]
   4 _dbus_strdup(0x1009ded8, 0x100b8d48, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-internals.c":406, 0x1004dfe4]
   5 dbus_set_error(0x7ffb7c10, 0x1009ded8, 0x1009dfe0, 0x25, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-errors.c":402, 0x1003eca8]
   6 append_unescaped_value(0x7ffb7be0, 0x100b8d48, 0x100adfd3, 0x2, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-address.c":299, 0x1005e35c]
   7 dbus_address_unescape_value(0x100b8810, 0x7ffb7c10, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-address.c":631, 0x1005ebe8]
   8 _dbus_address_test(0x100b87d0, 0x100b8d48, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-address.c":749, 0x1005ee74]
   9 run_test(0x100adc68, 0x100b8d48, 0x1005ecf0, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-test.c":64, 0x100118fc]
   10 dbus_internal_do_not_use_run_tests(0x100b8810, 0x0, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-test.c":121, 0x10011b18]
   11 main(0x1, 0x7ffb7cf4, 0x7ff9cab1, 0x20616435, 0x100b8800, 0xfb4f990, 0x0, 0x0) ["work/dbus-1.3.0/dbus/dbus-test-main.c":51, 0x10011714]
   12 __start() ["/xlv55/kudzu-apr12/work/irix/lib/libc/libc_n32_M4/csu/crt1text.s":177, 0x10011678]
(dbx) quit

This occurs even when compiling at -O0, so this isn't an over-optimisation problem (as can sometimes rarely be the case when using the MIPSpro compiler to build at -O2).

If there's any additional tests I can run to help to narrow this down, please let me know.
Comment 1 John (J5) Palmieri 2010-02-02 08:49:07 UTC
This is happening in the address test when unescaping one of test values at line 724 in dbus/dbus-address.c.  Can you break on that line and find out which of the test cases coming from the escape_tests array (line 664) we are segfaulting on?
Comment 2 John (J5) Palmieri 2010-02-02 09:04:52 UTC
Note that it is line 297 where there seems to be an error in the address. The parser sees the escape '%' sign and then checks to see if there are two more characters in the rest of the unescaped string.  For some reason on IRIX it thinks we are past the end of the string.  Either escaped_len is being calculated wrong (all of the test cases do have correct addresses and shouldn't hit the D-Bus error codepath) or we are trashing the stack somewhere else and it is manifesting itself at this point in the code.

From the traceback, the crash seems to be happening when constructing the error but I'm guessing the real bug is somewhere higher, e.g. I'm leaning towards a trashed stack.  Endien-ness issues somewhere perhaps?  
Comment 3 Stuart Shelton 2010-02-03 07:19:17 UTC
Incidentally, because I seem to have forgotten to include it before, the stack-track of the segfault of 'dbus-daemon --introspect' is:

$ dbx work/dbus-1.3.0-build/bus/dbus-daemon
dbx version 7.3.4 (86441_Nov11 MR) Nov 11 2002 11:31:55
Executable work/dbus-1.3.0-build/bus/dbus-daemon
(dbx) run --introspect
Process 675056 (dbus-daemon) started
Process 675056 Thread 0x10000 (dbus-daemon) stopped on signal SIGBUS: Bus error (default) at [__malloc:284 +0x8,0xfa44740]
         Source (of /xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/malloc.c) not available for Process 675056
(dbx) where

Thread 0x10000
>  0 __malloc(0x260, 0xfa40000, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["/xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/malloc.c":284, 0xfa44740]
   1 _realloc(0x1009f958, 0x260, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["/xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/malloc.c":408, 0xfa49fc4]
   2 dbus_realloc(0x1009f958, 0x25c, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/dbus/dbus-memory.c":601, 0x10035dd4]
   3 reallocate_for_length(0x7ffb7df0, 0x129, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/dbus/dbus-string.c":364, 0x10047920]
   4 set_length(0x7ffb7df0, 0x129, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/dbus/dbus-string.c":404, 0x10047a60]
   5 _dbus_string_lengthen(0x7ffb7df0, 0x4, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/dbus/dbus-string.c":872, 0x10048054]
   6 append(0x7ffb7df0, 0x100958c8, 0x4, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/dbus/dbus-string.c":1020, 0x1004840c]
   7 _dbus_string_append(0x7ffb7df0, 0x100958c8, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/dbus/dbus-string.c":1050, 0x100484f4]
   8 write_args_for_direction(0x7ffb7df0, 0x10095890, 0x0, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/bus/driver.c":1755, 0x1002a9ac]
   9 bus_driver_generate_introspect_string(0x7ffb7df0, 0xfa40000, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/bus/driver.c":1800, 0x1002ac70]
   10 introspect(0x0, 0xfa40000, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/bus/main.c":101, 0x10034b48]
   11 main(0x2, 0x7ffb7ef4, 0x25c, 0x0, 0x75, 0x1009fa9d, 0x74, 0x0) ["work/dbus-1.3.0/bus/main.c":285, 0x10035370]
   12 __start() ["/xlv55/kudzu-apr12/work/irix/lib/libc/libc_n32_M4/csu/crt1text.s":177, 0x100137d8]


Judicious insertion of printf() statements in dbus/dbus-address.c reveals that the issue actually arises on the second iteration of the tests of illegal unescape sequences:

To start with, i==0 and 'unescaped = dbus_address_unescape_value ("%a", &error);' is called and succeeds.  The next iteration i==1 and 'unescaped = dbus_address_unescape_value ("%q", &error);' causes the segfault - this function never returns.  This is around line 749.

Placing even more debug statements into dbus_address_unescape_value shows the problem is actually triggered by the call to 'append_unscaped_value()' around line 631.

This in turn appears to enter, successfully call _dbus_string_get_const_data(), sets 'p' and enters the while loop (with the value of 'p' being two less than 'end'), finds that _DBUS_ADDRESS_OPTIONALLY_ESCAPED_BYTE(*p) is false && p == '%', and then segfaults when calling dbus_set_error().

This is:

dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                "In D-Bus address, percent character was not followed by two hex digits");

... at around line 300.

Hope this helps!
Comment 4 John (J5) Palmieri 2010-02-03 08:57:44 UTC
I'm stumped here.  It looks like it is dieing in the malloc and the in the first traceback it looks like malloc is calling free.  Has any version of D-Bus worked for you?  Are you sure it isn't a bug in libc?  If it is D-Bus it looks like a we are corrupting memory somewhere else and then triggering the segfault during the malloc.  Can you reproduce the issue by writing a simpler test case?  e.g. strip out the unescape illegal address test and put it into its own executable?  If that crashes we can start to narrow down from there. 
Comment 5 Simon McVittie 2011-01-06 09:37:22 UTC
This looks a lot like Bug #16662, but is somewhat more informative.

*** This bug has been marked as a duplicate of bug 16662 ***

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.