[Pkg-xmpp-devel] Bug#747488: jabberd2-router segfaults on messages w/o "body" element

Jan Nordholz jnordholz at sec.t-labs.tu-berlin.de
Fri May 9 09:32:40 UTC 2014


Package: jabberd2
Version: 2.2.17-1
Severity: normal

Hi,

I'm getting frequent segfaults from jabberd2-router with the faulting
address lying a good deal beyond the end of heap.

Backtrace (strings redacted):
============================================================
#0  0x00007f8818a4a107 in message_log (nad=nad at entry=0x7f88197cc7f0, r=0x7f88197a4010, msg_from=0x7f88197c4c50 "...",
    msg_to=msg_to at entry=0x7f88197c4e30 "...") at router.c:1156
#1  0x00007f8818a4bb7a in _router_process_route (nad=0x7f88197cc7f0, comp=0x7f88197af9e0) at router.c:587
#2  _router_sx_callback (s=<optimized out>, e=<optimized out>, data=0x7f88197cc7f0, arg=0x7f88197af9e0) at router.c:948
#3  0x00007f8818a4f22a in __sx_event (file=file at entry=0x7f8818a5dae6 "io.c", line=line at entry=156, s=s at entry=0x7f88197afaa0, e=e at entry=event_PACKET, data=data at entry=0x7f88197cc7f0)
    at sx.c:345
#4  0x00007f8818a4d687 in _sx_process_read (s=s at entry=0x7f88197afaa0, buf=buf at entry=0x7f88197c4c80) at io.c:156
#5  0x00007f8818a4da9a in sx_can_read (s=0x7f88197afaa0) at io.c:243
#6  0x00007f8818a49ced in router_mio_callback (m=<optimized out>, a=<optimized out>, fd=0x7f88197af9b0, data=<optimized out>, arg=0x7f88197af9e0) at router.c:1047
#7  0x00007f8818a5343d in _mio_run (m=0x7f88197af7e0, timeout=<optimized out>) at mio_impl.h:268
#8  0x00007f8818a488c8 in main (argc=<optimized out>, argv=<optimized out>) at main.c:446
============================================================

Turns out the problematic code block is this:
============================================================
1155        // Find the message body
1156        for (i = 0; NAD_ENAME_L(nad, i) > 0; i++)
1157        {
1158            if((NAD_ENAME_L(nad, i) == 4) && (strncmp("body", NAD_ENAME(nad, i), 4) == 0))
1159            {
1160                nad_body_len = NAD_CDATA_L(nad, i);
1161                if (nad_body_len > 0) {
1162                    nad_body = NAD_CDATA(nad, i);
1163                } else {
1164                    log_write(r->log, LOG_NOTICE, "message_log received a message with empty body");
1165                    return 0;
1166                }
1167                break;
1168            }
1169        }
============================================================
As long as every message has a body, this works like a charm. However, the
message I received contains only {"route", "message", "event", "items",
"item", "activities", "delay"}, so we loop on...

However, nad->elems[] looks like this:
============================================================
(gdb) set $i=0
(gdb) p nad->elems[$i++]
$38 = {parent = -1, iname = 48, lname = 5, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = 1, ns = 0, my_ns = 0, depth = 0}
(gdb) 
$39 = {parent = 0, iname = 89, lname = 7, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = 3, ns = 1, my_ns = 1, depth = 1}
(gdb) 
$40 = {parent = 1, iname = 192, lname = 5, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = -1, ns = 2, my_ns = 2, depth = 2}
(gdb) 
$41 = {parent = 2, iname = 197, lname = 5, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = 4, ns = -1, my_ns = 2, depth = 3}
(gdb) 
$42 = {parent = 3, iname = 248, lname = 4, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = 5, ns = -1, my_ns = 2, depth = 4}
(gdb) 
$43 = {parent = 4, iname = 309, lname = 10, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = -1, ns = 3, my_ns = 3, depth = 5}
(gdb) 
$44 = {parent = 1, iname = 333, lname = 5, icdata = 0, lcdata = 0, itail = 0, ltail = 0, attr = 7, ns = 4, my_ns = 4, depth = 2}
(gdb) 
$45 = {parent = 779248994, iname = 778265443, lname = 1042769252, icdata = 1702257980, lcdata = 2015392878, itail = 1936616557, ltail = 1952982845, attr = 792359028, ns = 1650551343, 
  my_ns = 779248994, depth = 795308655}
============================================================

I.e. the loop looks for a terminating element with zero ->lname which
doesn't exist. The last is obviously already bogus, as nad->ecur proves:
============================================================
(gdb) p *nad
$46 = {elems = 0x7f88197ce3e0, attrs = 0x7f88197cdbc0, nss = 0x7f88197c4e60, 
  cdata = 0x7f88197cbab0 "..."..., depths = 0x7f88197c48f0, elen = 384,
  alen = 256, nlen = 128, clen = 512, dlen = 128, ecur = 7, acur = 8,
  ncur = 5, ccur = 400, scope = -1, next = 0x0}
============================================================

Suggested fix: loop until nad->ecur is reached instead.


Jan

PS: This loop is still present even in upstream 2.3.2.



More information about the Pkg-xmpp-devel mailing list