4

I've been trying to use gloox 1.0.14 for the first time and I think I'm using the most minimal example there is but poorly I get a SIGSEGV. Can anyone reproduce this problem or tell me why this happens and what I'm doing wrong? It's seems to be that the JID has an impact on this but I'd expect it to throw an error instead of segv crashing and the JID seems valid to me and even if the certificate is incorrect or whatever I'd still expect it to throw instead.

#include <cstdlib>

#include "gloox/client.h"

int main() {
  gloox::JID jid("segv@jabber.de");
  gloox::Client client(jid, "password");
  client.connect();
  return EXIT_SUCCESS;
}

Sanitizer told me:

ASAN:SIGSEGV
=================================================================
==27028==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f6357f79acd bp 0x7ffcca7c1a50 sp 0x7ffcca7c17d0 T0)
    #0 0x7f6357f79acc  (/lib64/libgnutls.so.30+0x99acc)
    #1 0x7f6357f7b49a  (/lib64/libgnutls.so.30+0x9b49a)
    #2 0x7f6357f7bb18 in gnutls_x509_crt_verify (/lib64/libgnutls.so.30+0x9bb18)
    #3 0x7f635a4ad54b in gloox::GnuTLSClient::verifyAgainstCAs(gnutls_x509_crt_int*, gnutls_x509_crt_int**, int) (/lib64/libgloox.so.13+0xbd54b)
    #4 0x7f635a4ad6bf in gloox::GnuTLSClient::getCertInfo() (/lib64/libgloox.so.13+0xbd6bf)
    #5 0x7f635a4afd6c in gloox::GnuTLSBase::handshake() (/lib64/libgloox.so.13+0xbfd6c)
    #6 0x7f635a4afbc0 in gloox::GnuTLSBase::decrypt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/lib64/libgloox.so.13+0xbfbc0)
    #7 0x7f635a4490bb in gloox::ConnectionTCPClient::recv(int) (/lib64/libgloox.so.13+0x590bb)
    #8 0x7f635a4c297d in gloox::ConnectionTCPBase::receive() (/lib64/libgloox.so.13+0xd297d)
    #9 0x7f635a4541d7 in gloox::ClientBase::connect(bool) (/lib64/libgloox.so.13+0x641d7)
    #10 0x4014d7 in main test.cc:8
    #11 0x7f6358aa357f in __libc_start_main (/lib64/libc.so.6+0x2057f)
    #12 0x401198 in _start (test+0x401198)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 ??
==27028==ABORTING

I compiled via:

c++ -fsanitize=address -fsanitize=undefined -ggdb -std=c++14 -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -lgloox main.cc
noob
  • 8,982
  • 4
  • 37
  • 65
  • 1
    Can you provide any additional info about your system, compiler etc. I've just tried running your minimal example and didn't get a `SEGV`. – Nicholas Smith Feb 08 '16 at 10:56
  • @NicholasSmith well I run Fedora 23: 4.3.3-303.fc23.x86_64 x86_64 (64 bit) – noob Feb 09 '16 at 23:02
  • Update your system fully. Compile with *all* warnings enabled, fix any problems that turn up. Try not-so-exotic compiler flags. Run under a debugger. Make *sure* your TLS infrastructure isn't borked. – vonbrand Feb 09 '16 at 23:06
  • @vonbrand well that's what I did. Except how do I make sure that this `/lib64/libgnutls.so` is not broken? – noob Feb 09 '16 at 23:28
  • Build a minimal wrapper around `libgnutls` to test it. – Nicholas Smith Feb 10 '16 at 09:06
  • @NicholasSmith well to be honest I've no clue what exactly libgnutls is for and I don't really care either. I'm compiling on an up-to-date fedora system and I didn't install any extra package for libgnutls so if this doesn't compile you may say that I should blame fedora but I don't. I can not start writing a program which just does not compile on some systems even though they're awesome. – noob Feb 10 '16 at 10:39
  • [The manual suggests](https://camaya.net/gloox/example/) adding `#include ` and `client->registerMessageHandler( this );` before invoking `connect()`. Did you try with these? – John_West Feb 13 '16 at 18:09
  • 1
    I just tested on recent Ubuntu and it does not error like this (note you should add link libraries after the source files in the command-line like this `... main.cc -lgloox`). Versions `libgnutls28-dev amd64 3.3.15-5ubuntu2` and `libgloox-dev:amd64 (1.0.13-3)`. It seems like issue in more recent versions. But on my Fedora 23 I see the same issue. @John_West Adding include seems correct, but does not fix the problem. – Jakuje Feb 13 '16 at 22:23
  • Seems to occur on ubuntu 16.04 – Begui Apr 22 '16 at 12:08

1 Answers1

3

This looks like a bug in recent version of gloox. Running the code under gdb or valgrind (without sanitizer) shows nice backtrace.

Full backtrace from valgrind points to the place of problem:

==29533==    at 0x62B558D: verify_crt (verify.c:602)
==29533==    by 0x62B6F57: _gnutls_verify_crt_status (verify.c:936)
==29533==    by 0x62B75CC: gnutls_x509_crt_verify (verify.c:1329)
==29533==    by 0x4EF254B: gloox::GnuTLSClient::verifyAgainstCAs(gnutls_x509_crt_int*, gnutls_x509_crt_int**, int) (tlsgnutlsclient.cpp:227)
==29533==    by 0x4EF26BF: gloox::GnuTLSClient::getCertInfo() (tlsgnutlsclient.cpp:157)
==29533==    by 0x4EF4D6C: gloox::GnuTLSBase::handshake() (tlsgnutlsbase.cpp:138)
==29533==    by 0x4EF4BC0: gloox::GnuTLSBase::decrypt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tlsgnutlsbase.cpp:70)
==29533==    by 0x4E8E0BB: gloox::ConnectionTCPClient::recv(int) (connectiontcpclient.cpp:169)
==29533==    by 0x4F0797D: gloox::ConnectionTCPBase::receive() (connectiontcpbase.cpp:115)
==29533==    by 0x4E991D7: gloox::ClientBase::connect(bool) (clientbase.cpp:212)
==29533==    by 0x400DAC: main (main.cc:9)

Backtrace from gdb shows:

#0  verify_crt (cert=0xbebebebebebebebe, trusted_cas=trusted_cas@entry=0x0, tcas_size=tcas_size@entry=0, flags=flags@entry=0, output=output@entry=0x7fffffffce90, _issuer=_issuer@entry=0x7fffffffce98, 
    now=1455405710, max_path=0x7fffffffce94, end_cert=true, nc=0x602000007a50, func=0x0) at verify.c:602
#1  0x00007ffff46bcf58 in _gnutls_verify_crt_status (certificate_list=certificate_list@entry=0x7fffffffcf08, clist_size=clist_size@entry=1, trusted_cas=trusted_cas@entry=0x0, tcas_size=tcas_size@entry=0, 
    flags=flags@entry=0, purpose=purpose@entry=0x0, func=0x0) at verify.c:936
#2  0x00007ffff46bd5cd in gnutls_x509_crt_verify (cert=cert@entry=0xbebebebebebebebe, CA_list=CA_list@entry=0x0, CA_list_length=CA_list_length@entry=0, flags=flags@entry=0, verify=verify@entry=0x7fffffffcf24)
    at verify.c:1329
#3  0x00007ffff6bee54c in gloox::GnuTLSClient::verifyAgainstCAs (this=this@entry=0x61400000fc40, cert=0xbebebebebebebebe, CAList=CAList@entry=0x0, CAListSize=CAListSize@entry=0) at tlsgnutlsclient.cpp:227
#4  0x00007ffff6bee6c0 in gloox::GnuTLSClient::getCertInfo (this=0x61400000fc40) at tlsgnutlsclient.cpp:157
#5  0x00007ffff6bf0d6d in gloox::GnuTLSBase::handshake (this=0x61400000fc40) at tlsgnutlsbase.cpp:138
#6  0x00007ffff6bf0bc1 in gloox::GnuTLSBase::decrypt (this=0x61400000fc40, 
    data="\024\003\003\000\001\001\026\003\003\000(\373\336\267\221q\256\266\344\363\022\367 C\022\233\351\251\065\036\355\070\362\217\264\370\003\206+\"\201r^\355\067I\203Y\213\350\301")
    at tlsgnutlsbase.cpp:70
#7  0x00007ffff6b8a0bc in gloox::ConnectionTCPClient::recv (this=<optimized out>, timeout=<optimized out>) at connectiontcpclient.cpp:169
#8  0x00007ffff6c0397e in gloox::ConnectionTCPBase::receive (this=0x60c00000bec0) at connectiontcpbase.cpp:115
#9  0x00007ffff6b951d8 in gloox::ClientBase::connect (this=0x7fffffffd410, block=<optimized out>) at clientbase.cpp:212
#10 0x00000000004013a8 in main () at main.cc:9

cert=0xbebebebebebebebe pointer is the point of failure. It is brought to that place from frame 4 in tlsgnutlsclient.cpp:157, where is such fanny construct:

157     m_certInfo.chain = verifyAgainstCAs( cert[certListSize], 0 /*CAList*/, 0 /*CAListSize*/ );

cert[certListSize] is clearly pointing away from the existing array. I tried to trace the bug in sources, but I am not so skilled with the svn commandline tools so I am leaving this on the reported to fill upstream bug (ok, I can do that, but let me know if there is anything I can do for you).

Jakuje
  • 24,773
  • 12
  • 69
  • 75
  • 2
    The main developer released a [patch file](http://sprunge.us/KdiH?cpp) unofficially. – noob Feb 16 '16 at 01:00