sctp: clear the transport of some out_chunk_list chunks in sctp_assoc_rm_peer
If a transport is removed by asconf but there still are some chunks with this transport queuing on out_chunk_list, later an use-after-free issue will be caused when accessing this transport from these chunks in sctp_outq_flush(). This is an old bug, we fix it by clearing the transport of these chunks in out_chunk_list when removing a transport in sctp_assoc_rm_peer(). Reported-by: syzbot+56a40ceee5fb35932f4d@syzkaller.appspotmail.com Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2b0ab72799
commit
df132eff46
|
@ -499,8 +499,9 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
|
|||
void sctp_assoc_rm_peer(struct sctp_association *asoc,
|
||||
struct sctp_transport *peer)
|
||||
{
|
||||
struct list_head *pos;
|
||||
struct sctp_transport *transport;
|
||||
struct sctp_transport *transport;
|
||||
struct list_head *pos;
|
||||
struct sctp_chunk *ch;
|
||||
|
||||
pr_debug("%s: association:%p addr:%pISpc\n",
|
||||
__func__, asoc, &peer->ipaddr.sa);
|
||||
|
@ -564,7 +565,6 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
|
|||
*/
|
||||
if (!list_empty(&peer->transmitted)) {
|
||||
struct sctp_transport *active = asoc->peer.active_path;
|
||||
struct sctp_chunk *ch;
|
||||
|
||||
/* Reset the transport of each chunk on this list */
|
||||
list_for_each_entry(ch, &peer->transmitted,
|
||||
|
@ -586,6 +586,10 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
|
|||
sctp_transport_hold(active);
|
||||
}
|
||||
|
||||
list_for_each_entry(ch, &asoc->outqueue.out_chunk_list, list)
|
||||
if (ch->transport == peer)
|
||||
ch->transport = NULL;
|
||||
|
||||
asoc->peer.transport_count--;
|
||||
|
||||
sctp_transport_free(peer);
|
||||
|
|
Loading…
Reference in New Issue