diff options
author | Xin Long <lucien.xin@gmail.com> | 2022-01-01 00:37:37 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-01-02 13:46:41 +0100 |
commit | f9d31c4cf4c11ff10317f038b9c6f7c3bda6cdd4 (patch) | |
tree | b9773cb8cf506bcab4f94014afbb12becbe18e76 /net/sctp/socket.c | |
parent | Merge branch 'ena-fixes' (diff) | |
download | linux-f9d31c4cf4c11ff10317f038b9c6f7c3bda6cdd4.tar.xz linux-f9d31c4cf4c11ff10317f038b9c6f7c3bda6cdd4.zip |
sctp: hold endpoint before calling cb in sctp_transport_lookup_process
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>
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 ad5028a07b18..da08671a3f80 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); |