Ignore:
Timestamp:
2015-02-22T18:53:21Z (10 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
5ff4618
Parents:
da6f167
git-author:
dequis <dx@…> (22-02-15 06:50:48)
git-committer:
dequis <dx@…> (22-02-15 18:53:21)
Message:

s5bytestream: fix segfault (cleanup before trying next streamhost)

This segfault happened when none of the available streamhosts can be
connected to - or if at least one of them fails to connect.

Before this commit, it can be reproduced reliably by setting the "proxy"
setting of the account to nonsense, for example, this is what i used:

proxy.example.org,1.2.3.4,7777;proxy.example.com,173.194.42.65,80

jabber_bs_recv_handshake_abort() calls jabber_bs_recv_handshake(), which
is supposed to restart the handshake with the next streamhost. And it
replaced bt->tf->watch_out, which held an event ID, with a newer event
ID. So the replaced event ID doesn't get removed, and it gets called
again when its socket is closed by the timeout - and by the time that
happens, the memory is free()'d already. Boom.

The patch is simple - created jabber_bs_remove_events() to cleanup those
events, and use it before any code that expects to restart the cycle.

So basically the same as doing b_event_remove(bt->tf->watch_out).

I hope there aren't more bugs like this in this code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/s5bytestream.c

    rda6f167 r9216eff  
    253253}
    254254
     255void jabber_bs_remove_events(struct bs_transfer *bt)
     256{
     257        struct jabber_transfer *tf = bt->tf;
     258
     259        if (tf->watch_out) {
     260                b_event_remove(tf->watch_out);
     261                tf->watch_out = 0;
     262        }
     263
     264        if (tf->watch_in) {
     265                b_event_remove(tf->watch_in);
     266                tf->watch_in = 0;
     267        }
     268
     269        if (tf->fd != -1) {
     270                closesocket(tf->fd);
     271                tf->fd = -1;
     272        }
     273
     274        if (bt->connect_timeout) {
     275                b_event_remove(bt->connect_timeout);
     276                bt->connect_timeout = 0;
     277        }
     278}
     279
    255280/* Bad luck */
    256281void jabber_bs_canceled(file_transfer_t *ft, char *reason)
     
    555580        if (shlist && shlist->next) {
    556581                bt->sh = shlist->next->data;
     582                jabber_bs_remove_events(bt);
    557583                return jabber_bs_recv_handshake(bt, -1, 0);
    558584        }
     
    764790                /* using a proxy, abort listen */
    765791
    766                 if (tf->watch_in) {
    767                         b_event_remove(tf->watch_in);
    768                         tf->watch_in = 0;
    769                 }
    770 
    771                 if (tf->fd != -1) {
    772                         closesocket(tf->fd);
    773                         tf->fd = -1;
    774                 }
    775 
    776                 if (bt->connect_timeout) {
    777                         b_event_remove(bt->connect_timeout);
    778                         bt->connect_timeout = 0;
    779                 }
     792                jabber_bs_remove_events(bt);
    780793
    781794                GSList *shlist;
Note: See TracChangeset for help on using the changeset viewer.