Opened at 2012-04-06T12:16:04Z
Closed at 2012-04-10T09:18:05Z
#938 closed defect (fixed)
bitlbee segfaults with gnutls 3.0.18, infinite loop in http_incoming_data()
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | |
Component: | BitlBee | Version: | 3.0.5 |
Keywords: | Cc: | ||
IRC client+version: | Client-independent | Operating System: | Linux |
OS version/distro: |
Description
With gnutls 3.0.18, bitlbee segfaults when connecting to a MSN account, because of an infinite loop in http_incoming_data()
Backtrace is the following: #0 0x00000000004342e2 in http_incoming_data (data=Cannot access memory at address 0x7fffff7fef08 ) at http_client.c:196 #1 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #2 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 ... #3758 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3759 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3760 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3761 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3762 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3763 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3764 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3765 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3766 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3767 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3768 0x000000000043453f in http_incoming_data (data=0x70c510, source=17, cond=B_EV_IO_READ) at http_client.c:257 #3769 0x00000000004335f1 in gaim_io_invoke (source=0x703c20, condition=G_IO_IN, data=0x744910) at events_glib.c:88 #3770 0x00007ffff77269ba in g_main_context_dispatch () from /lib64/libglib-2.0.so.0 #3771 0x00007ffff7726d80 in ?? () from /lib64/libglib-2.0.so.0 #3772 0x00007ffff772717a in g_main_loop_run () from /lib64/libglib-2.0.so.0 #3773 0x0000000000433563 in b_main_run () at events_glib.c:64 #3774 0x0000000000430d1c in main (argc=7, argv=0x7fffffffd9d8) at unix.c:183
Attachments (3)
Change History (14)
comment:1 Changed at 2012-04-06T12:25:00Z by
Changed at 2012-04-06T12:25:52Z by
Attachment: | gnutls-segfault.patch added |
---|
patch appearing to fix the infinite loop
comment:2 Changed at 2012-04-06T12:27:08Z by
The attached patch fixes the infinite loop and thus the segfault. Though, I am not sure if it is the correct fix, and it is ok for earlier versions of gnutls.
comment:3 Changed at 2012-04-06T22:18:35Z by
Actually, that patch did not help, the gnutls version upgrade was probably a red herring.
I have modified http_incoming_data() to use internal goto instead of recursive calls. The MSN server replies after a huge number of SSL_AGAIN errors, in the case below, 29128 retries, but I have seen more than 31000 at least once (the "retries" variable contains the number of SSL_AGAIN errors before ssl_pending() returns false). No wonder it exploded the stack previously.
(gdb) p retries $1 = 29128 (gdb) p *req $2 = {request = 0x716370 "POST /RST.srf HTTP/1.0\r\nHost: login.live.com\r\nAccept: */*\r\nUser-Agent: BitlBee 3.0.5\r\nContent-Type: text/xml; charset=utf-8\r\nContent-Length: 2981\r\nCache-Control: no-cache\r\n\r\n<Envelope xmlns=\"http://sc"..., request_length = 3155, status_code = 0, status_string = 0x0, reply_headers = 0x719600 "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nContent-Length: 10709\r\nContent-Type: text/html; charset=utf-8\r\nExpires: Fri, 06 Apr 2012 22:05:09 GMT\r\nServer: Microsoft-IIS/7.5\r\nP3P: CP=\"D"..., reply_body = 0x0, body_size = 0, finished = 0, redir_ttl = 3, func = 0x449c78 <msn_soap_handle_response>, data = 0x704360, ssl = 0x704ae0, fd = 16, inpa = 29353, bytes_written = 3155, bytes_read = 11093} (gdb) p ssl_errno $3 = 0 (gdb) p st $4 = 469
Changed at 2012-04-06T22:30:08Z by
Attachment: | bitlbee-3.0.5-msn-recursive-loop.patch added |
---|
fix recursive call in http_incoming_data when logging into MSN
comment:4 Changed at 2012-04-06T22:31:48Z by
This patch fixes the recursive loop and thus the stack explosion, but there might be a cleaner fix.
comment:5 Changed at 2012-04-07T11:42:28Z by
Ah, it looks like ssl_pending is just not always returning the right stuff. ssl_pending should return true only if there's more data available in the SSL buffer *right now*. If your fix ends up repeating that stuff 30k times, clearly there is no pending data so the function is lying.
So you're saying that you see the same problem with old SSL libs now, or am I wrong there?
comment:6 Changed at 2012-04-07T11:57:42Z by
Great, I can reproduce this. gnutls_record_check_pending() seems to be returning 5792 (0x16A0), whatever that might mean.
comment:7 Changed at 2012-04-07T11:58:28Z by
Oh yes, a number of bytes. This is weird, if that's the case then by all means ssl_read() must give that data I'd say..
comment:8 Changed at 2012-04-07T12:31:48Z by
From the gnutls_record_check_pending man-page:
This function checks if there are unread data in the gnutls buffers. If the return value is non-zero the next call to gnutls_record_recv() is guarranteed not to block.
Looks to me like a GnuTLS bug. Time to write them, I guess..
comment:9 Changed at 2012-04-07T13:08:09Z by
I'm attaching a workaround that should be a bit easier on the CPU/stack, although I think there's a theoretical chance that this approach could result in BitlBee not noticing new data coming in.
I sent a bug to the help-gnutls mailing list (couldn't find a bug tracker), hopefully I'll get a response there.
Changed at 2012-04-07T13:08:25Z by
Attachment: | gnutls3-workaround.diff added |
---|
comment:10 Changed at 2012-04-09T09:06:44Z by
The upstream bug report is here BTW: http://lists.gnu.org/archive/html/help-gnutls/2012-04/msg00001.html
I'm still assuming that this is a bug in GnuTLS but let's keep this bug open until that's confirmed.
comment:11 Changed at 2012-04-10T09:18:05Z by
Resolution: | → fixed |
---|---|
Status: | new → closed |
Work-around for this bug is in changeset:devel,903 and I think the fix in GnuTLS will be in 3.0.19. Thank you for the report!
It seems to be because gnutls 3.0.18 has been modified so that gnutls_record_recv() can return GNUTLS_E_PREMATURE_TERMINATION in some cases. See http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=commitdiff;h=d096705e9e0dd896db917b610707b830534e003c;hp=05eee078353374ca917d0df6adeee3567aa16386