[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20181129140100.901583118@linuxfoundation.org>
Date: Thu, 29 Nov 2018 15:11:55 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
syzbot+56a40ceee5fb35932f4d@...kaller.appspotmail.com,
Xin Long <lucien.xin@...il.com>,
"David S. Miller" <davem@...emloft.net>
Subject: [PATCH 4.14 025/100] sctp: clear the transport of some out_chunk_list chunks in sctp_assoc_rm_peer
4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <lucien.xin@...il.com>
commit df132eff463873e14e019a07f387b4d577d6d1f9 upstream.
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@...kaller.appspotmail.com
Signed-off-by: Xin Long <lucien.xin@...il.com>
Signed-off-by: David S. Miller <davem@...emloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
net/sctp/associola.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -497,8 +497,9 @@ void sctp_assoc_set_primary(struct sctp_
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);
@@ -562,7 +563,6 @@ void sctp_assoc_rm_peer(struct sctp_asso
*/
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,
@@ -584,6 +584,10 @@ void sctp_assoc_rm_peer(struct sctp_asso
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);
Powered by blists - more mailing lists