summaryrefslogtreecommitdiff
path: root/net/sctp/sctp_diag.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-16 11:28:59 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-16 11:28:59 -0700
commit48bddb143befb1dd93c0e5a66af62cfd60c86b04 (patch)
tree8d71225922209f780d0e0a1f27beaac3e836972b /net/sctp/sctp_diag.c
parentc8503720fd0b952ff25bcc49b6eb9c492e22f3c6 (diff)
parent8e29f97979c300406c21994986bdfcdb67fe4ff7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix hotplug deadlock in hv_netvsc, from Stephen Hemminger. 2) Fix double-free in rmnet driver, from Dan Carpenter. 3) INET connection socket layer can double put request sockets, fix from Eric Dumazet. 4) Don't match collect metadata-mode tunnels if the device is down, from Haishuang Yan. 5) Do not perform TSO6/GSO on ipv6 packets with extensions headers in be2net driver, from Suresh Reddy. 6) Fix scaling error in gen_estimator, from Eric Dumazet. 7) Fix 64-bit statistics deadlock in systemport driver, from Florian Fainelli. 8) Fix use-after-free in sctp_sock_dump, from Xin Long. 9) Reject invalid BPF_END instructions in verifier, from Edward Cree. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (43 commits) mlxsw: spectrum_router: Only handle IPv4 and IPv6 events Documentation: link in networking docs tcp: fix data delivery rate bpf/verifier: reject BPF_ALU64|BPF_END sctp: do not mark sk dumped when inet_sctp_diag_fill returns err sctp: fix an use-after-free issue in sctp_sock_dump netvsc: increase default receive buffer size tcp: update skb->skb_mstamp more carefully net: ipv4: fix l3slave check for index returned in IP_PKTINFO net: smsc911x: Quieten netif during suspend net: systemport: Fix 64-bit stats deadlock net: vrf: avoid gcc-4.6 warning qed: remove unnecessary call to memset tg3: clean up redundant initialization of tnapi tls: make tls_sw_free_resources static sctp: potential read out of bounds in sctp_ulpevent_type_enabled() MAINTAINERS: review Renesas DT bindings as well net_sched: gen_estimator: fix scaling error in bytes/packets samples nfp: wait for the NSP resource to appear on boot nfp: wait for board state before talking to the NSP ...
Diffstat (limited to 'net/sctp/sctp_diag.c')
-rw-r--r--net/sctp/sctp_diag.c33
1 files changed, 9 insertions, 24 deletions
diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c
index e99518e79b52..22ed01a76b19 100644
--- a/net/sctp/sctp_diag.c
+++ b/net/sctp/sctp_diag.c
@@ -279,9 +279,11 @@ out:
return err;
}
-static int sctp_sock_dump(struct sock *sk, void *p)
+static int sctp_sock_dump(struct sctp_transport *tsp, void *p)
{
+ struct sctp_endpoint *ep = tsp->asoc->ep;
struct sctp_comm_param *commp = p;
+ struct sock *sk = ep->base.sk;
struct sk_buff *skb = commp->skb;
struct netlink_callback *cb = commp->cb;
const struct inet_diag_req_v2 *r = commp->r;
@@ -289,9 +291,7 @@ static int sctp_sock_dump(struct sock *sk, void *p)
int err = 0;
lock_sock(sk);
- if (!sctp_sk(sk)->ep)
- goto release;
- list_for_each_entry(assoc, &sctp_sk(sk)->ep->asocs, asocs) {
+ list_for_each_entry(assoc, &ep->asocs, asocs) {
if (cb->args[4] < cb->args[1])
goto next;
@@ -309,7 +309,6 @@ static int sctp_sock_dump(struct sock *sk, void *p)
cb->nlh->nlmsg_seq,
NLM_F_MULTI, cb->nlh,
commp->net_admin) < 0) {
- cb->args[3] = 1;
err = 1;
goto release;
}
@@ -327,40 +326,30 @@ next:
cb->args[4]++;
}
cb->args[1] = 0;
- cb->args[2]++;
cb->args[3] = 0;
cb->args[4] = 0;
release:
release_sock(sk);
- sock_put(sk);
return err;
}
-static int sctp_get_sock(struct sctp_transport *tsp, void *p)
+static int sctp_sock_filter(struct sctp_transport *tsp, void *p)
{
struct sctp_endpoint *ep = tsp->asoc->ep;
struct sctp_comm_param *commp = p;
struct sock *sk = ep->base.sk;
- struct netlink_callback *cb = commp->cb;
const struct inet_diag_req_v2 *r = commp->r;
struct sctp_association *assoc =
list_entry(ep->asocs.next, struct sctp_association, asocs);
/* find the ep only once through the transports by this condition */
if (tsp->asoc != assoc)
- goto out;
+ return 0;
if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family)
- goto out;
-
- sock_hold(sk);
- cb->args[5] = (long)sk;
+ return 0;
return 1;
-
-out:
- cb->args[2]++;
- return 0;
}
static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
@@ -503,12 +492,8 @@ skip:
if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
goto done;
-next:
- cb->args[5] = 0;
- sctp_for_each_transport(sctp_get_sock, net, cb->args[2], &commp);
-
- if (cb->args[5] && !sctp_sock_dump((struct sock *)cb->args[5], &commp))
- goto next;
+ sctp_for_each_transport(sctp_sock_filter, sctp_sock_dump,
+ net, (int *)&cb->args[2], &commp);
done:
cb->args[1] = cb->args[4];