diff options
author | Xin Long <lucien.xin@gmail.com> | 2022-01-01 02:37:37 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-01-11 17:35:14 +0300 |
commit | 9f00a2a0c139588b7298e58c8c667f6d7ff37a5b (patch) | |
tree | 4232c7a17acd2dc631e350436f88cb58bf041940 /net/sctp/socket.c | |
parent | 3c5c81d1e3504e756dc1d8610c3bbdbc947fa5d5 (diff) | |
download | linux-9f00a2a0c139588b7298e58c8c667f6d7ff37a5b.tar.xz |
sctp: hold endpoint before calling cb in sctp_transport_lookup_process
commit f9d31c4cf4c11ff10317f038b9c6f7c3bda6cdd4 upstream.
The same fix in commit 5ec7d18d1813 ("sctp: use call_rcu to free endpoint")
is also needed for dumping one asoc and sock after the lookup.
Fixes: 86fdb3448cc1 ("sctp: ensure ep is not destroyed before doing the dump")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d2215d24634e..6b3c32264cbc 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -5317,23 +5317,31 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), } EXPORT_SYMBOL_GPL(sctp_for_each_endpoint); -int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *), - struct net *net, +int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net, const union sctp_addr *laddr, const union sctp_addr *paddr, void *p) { struct sctp_transport *transport; - int err; + struct sctp_endpoint *ep; + int err = -ENOENT; rcu_read_lock(); transport = sctp_addrs_lookup_transport(net, laddr, paddr); + if (!transport) { + rcu_read_unlock(); + return err; + } + ep = transport->asoc->ep; + if (!sctp_endpoint_hold(ep)) { /* asoc can be peeled off */ + sctp_transport_put(transport); + rcu_read_unlock(); + return err; + } rcu_read_unlock(); - if (!transport) - return -ENOENT; - err = cb(transport, p); + err = cb(ep, transport, p); + sctp_endpoint_put(ep); sctp_transport_put(transport); - return err; } EXPORT_SYMBOL_GPL(sctp_transport_lookup_process); |