Modify

#938 closed defect (fixed)

bitlbee segfaults with gnutls 3.0.18, infinite loop in http_incoming_data()

Reported by: dev@… 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)

gnutls-segfault.patch (2.1 KB) - added by dev@… at 2012-04-06T12:25:52Z.
patch appearing to fix the infinite loop
bitlbee-3.0.5-msn-recursive-loop.patch (548 bytes) - added by Olivier Blin <dev@…> at 2012-04-06T22:30:08Z.
fix recursive call in http_incoming_data when logging into MSN
gnutls3-workaround.diff (787 bytes) - added by wilmer at 2012-04-07T13:08:25Z.

Download all attachments as: .zip

Change History (14)

comment:1 Changed at 2012-04-06T12:25:00Z by anonymous

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

Changed at 2012-04-06T12:25:52Z by dev@…

Attachment: gnutls-segfault.patch added

patch appearing to fix the infinite loop

comment:2 Changed at 2012-04-06T12:27:08Z by dev@…

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 Olivier Blin <dev@…>

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 Olivier Blin <dev@…>

fix recursive call in http_incoming_data when logging into MSN

comment:4 Changed at 2012-04-06T22:31:48Z by Olivier Blin <dev@…>

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 wilmer

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 wilmer

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 wilmer

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 wilmer

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 wilmer

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 wilmer

Attachment: gnutls3-workaround.diff added

comment:10 Changed at 2012-04-09T09:06:44Z by wilmer

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 wilmer

Resolution: fixed
Status: newclosed

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!

Modify Ticket

Action
as closed The ticket will remain with no owner.
The resolution will be deleted.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.