[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bugfix T124 connector: Fallback on the socket output callback leads to SIGSEGV


Hi there,

The commit
https://git.libssh.org/projects/libssh.git/commit/?id=b73ffb3f91ea26412482d145512e4261df903df7
to fix ticket T124 introduces a new issue.

On certain constellations, calling ssh_event_dopoll() leads to a SIGSEGV:

#0  0x0000000000000090 in ?? ()
#1  0x00007ffff7b6c272 in ssh_packet_socket_controlflow_callback
(code=2, userdata=0x611e80) at /home/till/libssh-master/src/packet.c:1388
#2  0x00007ffff7b7a3c8 in ssh_socket_pollcallback (p=0x6125c0, fd=5,
revents=4, v_s=0x611a50) at /home/till/libssh-master/src/socket.c:355
#3  0x00007ffff7b75912 in ssh_poll_ctx_dopoll (ctx=0x7ffff0003180,
timeout=20) at /home/till/libssh-master/src/poll.c:702
#4  0x00007ffff7b75dd1 in ssh_event_dopoll (event=0x7ffff00027d0,
timeout=20) at /home/till/libssh-master/src/poll.c:963
#5  0x0000000000405387 in per_conn_thread (args=0x611e80) at
src/ssh-direct-tcp.c:1254

I could track this down to

#define ssh_callbacks_execute_list(list, cbtype, c, ...)      \
    do {                                                      \
        struct ssh_iterator *i = ssh_list_get_iterator(list); \
        cbtype cb;                                            \
        while (i != NULL){                                    \
            cb = ssh_iterator_value(cbtype, i);               \
            if (ssh_callbacks_exists(cb, c))                  \
                cb-> c (__VA_ARGS__, cb->userdata);           \
            i = i->next;                                      \
        }                                                     \
    } while(0)

Which expands into this in packet.c:1388

        /* the out pipe is empty so we can forward this to channels */
        it = ssh_list_get_iterator(session->channels);
        while (it != NULL) {
            channel = ssh_iterator_value(ssh_channel, it);
            /*ssh_callbacks_execute_list(channel->callbacks,
                                       ssh_channel_callbacks,
                                       channel_write_wontblock_function,
                                       session,
                                       channel,
                                       channel->remote_window);
            */

            i = ssh_list_get_iterator(channel->callbacks);
            while (i != NULL){
                cb = ssh_iterator_value(ssh_channel_callbacks, i);
                if (ssh_callbacks_exists(cb, channel_write_wontblock_function))
                    cb->channel_write_wontblock_function(session, channel, channel->remote_window, cb->userdata);
                i = i->next;
            }
            it = it->next;
        }

The violation happens on the line

   cb->c(...) := cb->channel_write_wontblock_function(..)

(gdb) p cb->channel_write_wontblock_function
$7 = (ssh_channel_write_wontblock_callback) 0x90

So ssh_iterator_value(ssh_channel_callbacks, i) seem to return a CB
struct with uninitialized .channel_write_wontblock_function.

So probably this fix is not the issue, but it discovers a problem in
some other part. I didn't track down yet where
.channel_write_wontblock_function should be either initialized or zeroed.

What you think?

Cheers,
Till


Archive administrator: postmaster@lists.cynapses.org