Package: libetpan17 Version: 1.5-1 Severity: important Tags: upstream patch
Hi there, Claws Mail (all versions since 3.9.3-2+b3, inclusive) reliably segfaults seconds after startup on my system. I have attached a full backtrace taken after such an event. I have tracked the problem down to a corner case in the interaction between claws-mail and libetpan17, which seems simplest to fix in libetpan. The trigger for the bug is that claws-mail links directly against libgnutls26, but also against libetpan17, which links against libgnutls-deb0-28. This problem does not occur with versions of claws-mail prior to 3.9.3-2+b3, which all link against libetpan16 (which links against libgnutls26). claws-mail first calls gnutls_global_init, which initialises libgnutls26, and then calls mailstream_gnutls_init_not_required in libetpan17, which causes libetpan not to initialise libgnutls-deb0-28. The result of this is that libetpan calls gnutls with an uninitialised session handle, resulting in a segfault. However, since gnutls_global_init is reentrant, it is perfectly safe to ignore any calls to mailstream_gnutls_init_not_required and initialise gnutls anyway. In the case where gnutls has already been initialised, doing so will simply increment a counter; and in the case where this bug is triggered, gnutls will be properly initialised before use. OpenSSL's SSL_library_init is not reentrant, and therefore this change can only apply to gnutls. I am attaching a patch which implements this change, and I have confirmed that it fixes the segfaulting behaviour described above. Please let me know if you think it needs to be revised, or if you need any further information. Thanks, Steven. -- System Information: Debian Release: jessie/sid APT prefers unstable APT policy: (800, 'unstable'), (700, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.14-1-amd64 (SMP w/4 CPU cores) Locale: LANG=en_AU.utf8, LC_CTYPE=en_AU.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libetpan17 depends on: ii libc6 2.19-1 ii libdb5.3 5.3.28-3 ii libgcc1 1:4.9.0-6 ii libgnutls-deb0-28 3.2.15-2 ii liblockfile1 1.09-6 ii libsasl2-2 2.1.26.dfsg1-9 ii libstdc++6 4.9.0-6 ii multiarch-support 2.19-1 ii zlib1g 1:1.2.8.dfsg-1 libetpan17 recommends no packages. libetpan17 suggests no packages. -- no debconf information
#0 __GI___pthread_mutex_lock (mutex=0x3) at ../nptl/pthread_mutex_lock.c:66 __PRETTY_FUNCTION__ = "__pthread_mutex_lock" type = 3968189784 #1 0x00007fffec59068c in gnutls_system_mutex_lock (priv=<optimized out>) at system.c:228 No locals. #2 0x00007fffec6214c7 in wrap_nettle_rnd (_ctx=<optimized out>, level=0, data=0x7fffd0002b9b, datasize=29) at rnd.c:441 ret = <optimized out> reseed = 0 event = {now = {tv_sec = 4, tv_nsec = 140733193388127}, count = 0, err = 0, pid = 3071, rusage = {ru_utime = {tv_sec = 472446402560, tv_usec = 119}, ru_stime = {tv_sec = 532575944704, tv_usec = -1403518415238332416}, {ru_maxrss = 32767, __ru_maxrss_word = 32767}, { ru_ixrss = -1403546487144579072, __ru_ixrss_word = -1403546487144579072}, {ru_idrss = 32767, __ru_idrss_word = 32767}, { ru_isrss = 58552705030815744, __ru_isrss_word = 58552705030815744}, {ru_minflt = -3089299401110192128, __ru_minflt_word = -3089299401110192128}, {ru_majflt = -585856942451163137, __ru_majflt_word = -585856942451163137}, { ru_nswap = 21474869247, __ru_nswap_word = 21474869247}, {ru_inblock = 0, __ru_inblock_word = 0}, {ru_oublock = -3089299469829668864, __ru_oublock_word = -3089299469829668864}, {ru_msgsnd = -1417224274355126273, __ru_msgsnd_word = -1417224274355126273}, { ru_msgrcv = -3458716891223130113, __ru_msgrcv_word = -3458716891223130113}, {ru_nsignals = -3089299401110159361, __ru_nsignals_word = -3089299401110159361}, {ru_nvcsw = 8589967359, __ru_nvcsw_word = 8589967359}, {ru_nivcsw = -585745419330387968, __ru_nivcsw_word = -585745419330387968}}} #3 0x00007fffec578252 in _gnutls_rnd (len=29, data=0x7fffd0002b9b, level=GNUTLS_RND_NONCE) at ./random.h:37 data = 0x7fffd0002b9b #4 _gnutls_tls_create_random (dst=0x7fffd0002b98 "S\231\212\206") at gnutls_handshake.c:207 tim = <optimized out> #5 0x00007fffec578573 in _gnutls_set_client_random (session=0x0, rnd=0x0) at gnutls_handshake.c:232 ret = -805295280 #6 0x00007fffec579dfd in _gnutls_send_client_hello (again=<optimized out>, session=0x7fffd0002b50) at gnutls_handshake.c:1994 ret = 2 extdata = {allocd = 0x7fffd00046b0 "\003\003", data = 0x7fffd00046b0 "\003\003", max_length = 2048, length = 2} session_id_len = 0 '\000' bufel = 0x0 hver = 0x7fffec8599e8 <sup_versions+72> tver = "\003\003" rehandshake = <optimized out> #7 _gnutls_send_hello (session=session@entry=0x7fffd0002b50, again=<optimized out>) at gnutls_handshake.c:2207 ret = <optimized out> #8 0x00007fffec57c308 in _gnutls_handshake_client (session=0x7fffd0002b50) at gnutls_handshake.c:2664 ret = 0 #9 gnutls_handshake (session=0x7fffd0002b50) at gnutls_handshake.c:2535 ret = <optimized out> params = 0x7fffec58cba5 <gnutls_dh_set_prime_bits+37> #10 0x00007ffff2d27629 in ssl_data_new (fd=fd@entry=16, timeout=timeout@entry=0, callback=0x5c3390 <etpan_connect_ssl_context_cb>, cb_data=0xd00560, cb_data@entry=0x5c3390 <etpan_connect_ssl_context_cb>) at mailstream_ssl.c:597 ssl_data = <optimized out> session = 0x7fffd0002b50 cancel = <optimized out> xcred = 0x7fffd0001270 r = <optimized out> ssl_context = 0x7fffd0004270 timeout_value = <optimized out> #11 0x00007ffff2d27755 in tls_data_new (cb_data=0x5c3390 <etpan_connect_ssl_context_cb>, callback=<optimized out>, timeout=0, fd=fd@entry=16) at mailstream_ssl.c:638 No locals. #12 mailstream_low_ssl_open_full (fd=fd@entry=16, starttls=starttls@entry=0, timeout=0, callback=callback@entry=0x5c3390 <etpan_connect_ssl_context_cb>, cb_data=cb_data@entry=0xd00560) at mailstream_ssl.c:693 s = <optimized out> ssl_data = <optimized out> #13 0x00007ffff2d279a0 in mailstream_low_ssl_open_with_callback_timeout (fd=fd@entry=16, timeout=<optimized out>, callback=callback@entry=0x5c3390 <etpan_connect_ssl_context_cb>, data=data@entry=0xd00560) at mailstream_ssl.c:1181 No locals. #14 0x00007ffff2d279a6 in mailstream_ssl_open_with_callback_timeout (fd=fd@entry=16, timeout=<optimized out>, callback=callback@entry=0x5c3390 <etpan_connect_ssl_context_cb>, data=data@entry=0xd00560) at mailstream_ssl.c:1071 low = <optimized out> s = <optimized out> #15 0x00007ffff2d3c645 in mailimap_ssl_connect_voip_with_callback (f=0x2e43ed70, server=<optimized out>, port=<optimized out>, voip_enabled=<optimized out>, callback=0x5c3390 <etpan_connect_ssl_context_cb>, data=0xd00560) at mailimap_ssl.c:94 s = 16 stream = <optimized out> #16 0x00007ffff2d3c6c7 in mailimap_ssl_connect_with_callback (f=<optimized out>, server=<optimized out>, port=<optimized out>, callback=<optimized out>, data=<optimized out>) at mailimap_ssl.c:65 No locals. #17 0x00000000005bd159 in connect_ssl_run (op=<optimized out>) at imap-thread.c:538 r = <optimized out> param = <optimized out> result = 0x7fffffffb260 #18 0x00000000005e0139 in thread_run (data=0x2e43a100) at etpan-thread-manager.c:351 do_quit = 0 op = 0x2e43efd0 thread = 0x2e43a100 r = <optimized out> #19 0x00007ffff43540ca in start_thread (arg=0x7fffd520a700) at pthread_create.c:312 __res = <optimized out> pd = 0x7fffd520a700 now = <optimized out> unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140736769074944, 1956691914992824913, 1, 140737354125408, 993, 140736769074944, -1956749513846246831, -1956681527595322799}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}} not_first_call = <optimized out> pagesize_m1 = <optimized out> sp = <optimized out> freesize = <optimized out> __PRETTY_FUNCTION__ = "start_thread" #20 0x00007ffff1d85ffd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 No locals.
Always initialise gnutls, regardless of being told not to gnutls_global_init is reentrant, unlike SSL_library_init, so we can safely ignore any calls to mailstream_gnutls_init_not_required. This fixes broken behaviour in cases where our caller links against a different version of gnutls and we end up using an uninitialised library. --- a/src/data-types/mailstream_ssl.c +++ b/src/data-types/mailstream_ssl.c @@ -152,7 +152,6 @@ # define MUTEX_LOCK(x) # define MUTEX_UNLOCK(x) #endif -static int gnutls_init_not_required = 0; static int openssl_init_done = 0; #endif @@ -242,11 +241,7 @@ void mailstream_gnutls_init_not_required(void) { -#ifdef USE_SSL - MUTEX_LOCK(&ssl_lock); - gnutls_init_not_required = 1; - MUTEX_UNLOCK(&ssl_lock); -#endif + return; } void mailstream_openssl_init_not_required(void) @@ -282,8 +277,7 @@ openssl_init_done = 1; } #else - if (!gnutls_init_not_required) - gnutls_global_init(); + gnutls_global_init(); #endif MUTEX_UNLOCK(&ssl_lock); #endif @@ -666,8 +660,7 @@ gnutls_deinit(ssl_data->session); MUTEX_LOCK(&ssl_lock); - if(!gnutls_init_not_required) - gnutls_global_deinit(); + gnutls_global_deinit(); MUTEX_UNLOCK(&ssl_lock); ssl_data->session = NULL;