Crash in pseudo_tcp_socket_close()
@xhaakon
Submitted by Jakub Adam Assigned to Jakub Adam @xhaakon
Description
libnice may crash with the following stack when a stream is being removed:
# 0 0x00007ffff0749044 in g_socket_send_message (socket=0x0, address=0x0, vectors=0x7ffffffeaaa0, num_vectors=1, messages=0x0, num_messages=0, flags=0, cancellable=0x0, error=0x7ffffffea980) at /build/glib2.0-wnDt2X/glib2.0-2.48.1/./gio/gsocket.c:4255
# 1 0x00007fffd5d99b9f in socket_send_message (sock=0x7fff50002120, message=0x7ffffffeaa90, reliable=0) at tcp-bsd.c:308
priv = 0x7fff50003400
ret = 54100183102001
gerr = 0x0
message_len = 24
# 2 0x00007fffd5d99d96 in socket_send_messages (sock=0x7fff50002120, to=0x555556a499e8, messages=0x7ffffffeaa90, n_messages=1) at tcp-bsd.c:363
message = 0x7ffffffeaa90
len = 140737345555503
i = 0
# 3 0x00007fffd5d97804 in nice_socket_send_messages (sock=0x7fff50002120, to=0x555556a499e8, messages=0x7ffffffeaa90, n_messages=1) at socket.c:153
__func__ = "nice_socket_send_messages"
# 4 0x00007fffd5d9a415 in socket_send_messages (sock=0x5555569cb0b0, to=0x555556a499e8, messages=0x7ffffffeaa90, n_messages=1) at tcp-passive.c:211
peer_socket = 0x7fff50002120
priv = 0x55555595d540
# 5 0x00007fffd5d97957 in nice_socket_send (sock=0x5555569cb0b0, to=0x555556a499e8, len=24, buf=0x7ffffffeab80 "") at socket.c:226
local_buf = {buffer = 0x7ffffffeab80, size = 24}
local_message = {buffers = 0x7ffffffeaaa0, n_buffers = 1}
ret = 32767
# 6 0x00007fffd5d75be7 in pseudo_tcp_socket_write_packet (psocket=0x555555963b00 [PseudoTcpSocket], buffer=0x7ffffffeab80 "", len=24, user_data=0x55555687dc00) at agent.c:1775
sock = 0x5555569cb0b0
addr = 0x555556a499e8
component = 0x55555687dc00 [NiceComponent]
__func__ = "pseudo_tcp_socket_write_packet"
# 7 0x00007fffd5d8f3ac in packet (self=0x555555963b00 [PseudoTcpSocket], seq=0, flags=FLAG_RST, offset=0, len=0, now=375458652) at pseudotcp.c:1415
priv = 0x55555687a310
buffer = {u8 = '\000' <repeats 13 times>, "\004\360\000\026a\v\\\000\000\000\000f\252G\033\320|\374Z", '\000' <repeats 160 times>, "\300Z\311\314\377\177\000\000"..., u16 = {0, 0, 0, 0, 0, 0, 1024, 240, 24854, 23563, 0, 0, 43622, 6983, 31952, 23292, 0 <repeats 80 times>, 23232, 52425, 32767, 0, 20416, 52425, 32767, 0, 10992, 22125, 21845, 0, 0, 0, 0, 0, 6416, 59872, 32767, 0, 10992, 22125, 21845, 0 <repeats 15 times>, 32797, 0, 74, 48, 0, 0, 0, 0, 0, 0, 25120, 22132, 21845, 0, 0, 0, 0, 0, 417, 0, 0, 0, 4448, 22125, 21845, 0, 0, 0, 0, 0, 1040, 0 <repeats 11 times>, 45408, 59871, 32767, 0, 45488, 59871, 32767, 0, 12288, 22132, 21845, 0, 64, 0, 0, 0, 46834, 24115, 0 <repeats 42 times>, 16, 0, 16, 0, 16, 0, 0, 0, 64, 0, 0, 0, 16, 0, 16, 0, 20036, 18757, 0, 0, 4511, 22125, 21845, 0, 4383, 22125, 21845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 24706, 44610, 0 <repeats 11 times>, 1536, 8, 1056, 2048, 8224, 0, 0, 0, 0, 2979, 63357, 32767, 0, 0, 0, 0, 0, 13024...}, u32 = {0, 0, 0, 15729664, 1544249622, 0, 457681510, 1526496464, 0 <repeats 40 times>, 3435748032, 32767, 3435745216, 32767, 1449994992, 21845, 0, 0, 3923777808, 32767, 1449994992, 21845, 0, 0, 0, 0, 0, 0, 0, 32797, 3145802, 0, 0, 0, 1450467872, 21845, 0, 0, 417, 0, 1449988448, 21845, 0, 0, 1040, 0, 0, 0, 0, 0, 3923751264, 32767, 3923751344, 32767, 1450455040, 21845, 64, 0, 1580447474, 0 <repeats 21 times>, 16, 16, 16, 0, 64, 0, 16, 16, 1229278788, 0, 1449988511, 21845, 1449988383, 21845, 0, 0, 0, 0, 64, 0, 0, 2923585666, 0, 0, 0, 0, 0, 100663296, 69206024, 538970112, 0, 0, 4152167331, 32767, 0, 0, 1436431072, 21845, 0, 0, 253, 0, 4294881184, 32767, 1450467328, 21845, 1443646928, 21845, 1450000528, 21845, 1441175104, 21845, 4025674725, 32767, 0, 0, 526344, 8, 0, 0, 0, 0, 0, 0, 0, 0, 4294881200, 32767, 0, 0, 1436431072, 21845, 3435749008, 32767, 0, 0, 0, 0, 0, 0, 1450467888, 21845, 1450467340, 21845, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 6, 0 <repeats 29 times>, 3435749904, 32767, 3435745248, 32767, 0, 0, 0, 0, 4116451840, 3929404425, 0, 0, 1436431072, 21845, 1450467328, 21845, 1443646928, 21845...}}
wres = WR_SUCCESS
__func__ = "packet"
# 8 0x00007fffd5d9112b in transmit (self=0x555555963b00 [PseudoTcpSocket], segment=0x555556a65e70, now=375458652) at pseudotcp.c:1967
seq = 0
flags = 4 '\004'
wres = WR_SUCCESS
priv = 0x55555687a310
nTransmit = 0
__func__ = "transmit"
# 9 0x00007fffd5d918e3 in attempt_send (self=0x555555963b00 [PseudoTcpSocket], sflags=sfRst) at pseudotcp.c:2131
cwnd = 180
nInFlight = 0
iter = 0x5555559724e0
sseg = 0x555556a65e70
nWindow = 1
nUseable = 1
nAvailable = 0
snd_buffered = 0
priv = 0x55555687a310
now = 375458652
bFirst = 0
# 10 0x00007fffd5d919ad in closedown (self=0x555555963b00 [PseudoTcpSocket], err=103, source=CLOSEDOWN_LOCAL) at pseudotcp.c:2152
priv = 0x55555687a310
# 11 0x00007fffd5d8ed41 in pseudo_tcp_socket_close (self=0x555555963b00 [PseudoTcpSocket], force=1) at pseudotcp.c:1239
priv = 0x55555687a310
# 12 0x00007fffd5d70a85 in nice_component_close (cmp=0x55555687dc00 [NiceComponent]) at component.c:283
data = 0x55555676a8a0
vec = 0x7fffd5d89d30 <discovery_free+38>
# 13 0x00007fffd5d8152e in nice_stream_close (stream=0x55555687a8c0 [NiceStream]) at stream.c:88
component = 0x55555687dc00 [NiceComponent]
i = 0x555555ef8950
# 14 0x00007fffd5d78ee9 in nice_agent_remove_stream (agent=0x555555cf8cb0 [NiceAgent], stream_id=1) at agent.c:3027
stream_ids = {1, 0}
stream = 0x55555687a8c0 [NiceStream]
__func__ = "nice_agent_remove_stream"
# 15 0x00007fff5a1232d8 in fs_nice_stream_transmitter_stop (streamtransmitter=0x55555676acb0 [FsNiceStreamTransmitter]) at fs-nice-stream-transmitter.c:517
self = 0x55555676acb0 [FsNiceStreamTransmitter]
gststream = 0x555555a1a1c0
stream_id = 1
...
It seems this happens when pseudo-TCP writes to a TCP-passive socket (which makes little sense to me - I don't care about pseudo-TCP socket when using actual TCP, but it gets created anyway).
I think the TCP passive socket crashes because its connections
(from TcpPassivePriv
) contains a reference to NiceSocket
that has been already destroyed, but gets selected and used as peer_socket
in socket_send_messages()
(# 4
on the stack). So, when cleaning up a socket in nice_component_remove_socket()
, we should probably check and remove it also from connections
lists of TCP-passives.