sctp: ensure ep is not destroyed before doing the dump
authorXin Long <lucien.xin@gmail.com>
Sat, 17 Jun 2017 08:10:27 +0000 (16:10 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 19 Jun 2017 19:13:43 +0000 (15:13 -0400)
Now before dumping a sock in sctp_diag, it only holds the sock while
the ep may be already destroyed. It can cause a use-after-free panic
when accessing ep->asocs.

This patch is to set sctp_sk(sk)->ep NULL in sctp_endpoint_destroy,
and check if this ep is already destroyed before dumping this ep.

Suggested-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdrver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sctp/endpointola.c
net/sctp/sctp_diag.c

index 8c589230794f9394406d2a0ad2157b7a47d75757..3dcd0ecf3d99f74ec8ed4aad149bd32950ab23ef 100644 (file)
@@ -275,6 +275,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
                if (sctp_sk(sk)->bind_hash)
                        sctp_put_port(sk);
 
+               sctp_sk(sk)->ep = NULL;
                sock_put(sk);
        }
 
index 048954eee984f28e599084b32fad87b2bd6989d0..9a647214a91ebc583660db320307e0df1e13e5be 100644 (file)
@@ -278,7 +278,6 @@ out:
 
 static int sctp_sock_dump(struct sock *sk, void *p)
 {
-       struct sctp_endpoint *ep = sctp_sk(sk)->ep;
        struct sctp_comm_param *commp = p;
        struct sk_buff *skb = commp->skb;
        struct netlink_callback *cb = commp->cb;
@@ -287,7 +286,9 @@ static int sctp_sock_dump(struct sock *sk, void *p)
        int err = 0;
 
        lock_sock(sk);
-       list_for_each_entry(assoc, &ep->asocs, asocs) {
+       if (!sctp_sk(sk)->ep)
+               goto release;
+       list_for_each_entry(assoc, &sctp_sk(sk)->ep->asocs, asocs) {
                if (cb->args[4] < cb->args[1])
                        goto next;