linux-stable/net/sctp
Xin Long d99f144acc sctp: leave the err path free in sctp_stream_init to sctp_stream_free
[ Upstream commit 181d8d2066 ]

A NULL pointer dereference was reported by Wei Chen:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  RIP: 0010:__list_del_entry_valid+0x26/0x80
  Call Trace:
   <TASK>
   sctp_sched_dequeue_common+0x1c/0x90
   sctp_sched_prio_dequeue+0x67/0x80
   __sctp_outq_teardown+0x299/0x380
   sctp_outq_free+0x15/0x20
   sctp_association_free+0xc3/0x440
   sctp_do_sm+0x1ca7/0x2210
   sctp_assoc_bh_rcv+0x1f6/0x340

This happens when calling sctp_sendmsg without connecting to server first.
In this case, a data chunk already queues up in send queue of client side
when processing the INIT_ACK from server in sctp_process_init() where it
calls sctp_stream_init() to alloc stream_in. If it fails to alloc stream_in
all stream_out will be freed in sctp_stream_init's err path. Then in the
asoc freeing it will crash when dequeuing this data chunk as stream_out
is missing.

As we can't free stream out before dequeuing all data from send queue, and
this patch is to fix it by moving the err path stream_out/in freeing in
sctp_stream_init() to sctp_stream_free() which is eventually called when
freeing the asoc in sctp_association_free(). This fix also makes the code
in sctp_process_init() more clear.

Note that in sctp_association_init() when it fails in sctp_stream_init(),
sctp_association_free() will not be called, and in that case it should
go to 'stream_free' err path to free stream instead of 'fail_init'.

Fixes: 5bbbbe32a4 ("sctp: introduce stream scheduler foundations")
Reported-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://lore.kernel.org/r/831a3dc100c4908ff76e5bcc363be97f2778bc0b.1658787066.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-08-03 12:05:28 +02:00
..
Kconfig
Makefile
associola.c sctp: leave the err path free in sctp_stream_init to sctp_stream_free 2022-08-03 12:05:28 +02:00
auth.c sctp: move the active_key update after sh_keys is added 2021-08-03 11:43:43 +01:00
bind_addr.c
chunk.c
debug.c
diag.c sctp: fix kernel-infoleak for SCTP sockets 2022-03-10 14:46:42 -08:00
endpointola.c sctp: use call_rcu to free endpoint 2021-12-25 17:13:37 +00:00
input.c sctp: read sk->sk_bound_dev_if once in sctp_rcv() 2022-06-09 10:30:14 +02:00
inqueue.c
ipv6.c sctp: delete addr based on sin6_scope_id 2021-07-26 12:34:03 +01:00
objcnt.c
offload.c
output.c net: annotate accesses to dev->gso_max_size 2021-11-22 12:49:42 +00:00
outqueue.c sctp: count singleton chunks in assoc user stats 2022-04-05 09:51:12 +02:00
primitive.c
proc.c sctp: move hlist_node and hashent out of sctp_ep_common 2021-12-23 11:15:30 +00:00
protocol.c ip: Fix data-races around sysctl_ip_nonlocal_bind. 2022-07-29 17:28:00 +02:00
sm_make_chunk.c sctp: account stream padding length for reconf chunk 2021-10-14 07:15:22 -07:00
sm_sideeffect.c sctp: check asoc strreset_chunk in sctp_generate_reconf_event 2022-04-23 22:34:17 +01:00
sm_statefuns.c sctp: use the correct skb for security_sctp_assoc_request 2022-04-08 14:38:58 -07:00
sm_statetable.c
socket.c sctp: Initialize daddr on peeled off socket 2022-04-11 20:33:10 -07:00
stream.c sctp: leave the err path free in sctp_stream_init to sctp_stream_free 2022-08-03 12:05:28 +02:00
stream_interleave.c
stream_sched.c sctp: fix sleep in atomic context bug in timer handlers 2022-08-03 12:05:27 +02:00
stream_sched_prio.c
stream_sched_rr.c
sysctl.c
transport.c sctp: make the raise timer more simple and accurate 2021-11-25 21:00:45 -08:00
tsnmap.c
ulpevent.c
ulpqueue.c