summaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-05-08 08:31:46 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-05-08 08:31:46 -0700
commitfc858a5231089b972076642a86cf62481d95d82e (patch)
tree5ff7b54cdb36bd25090c968783c553938883457f /net/sctp/socket.c
parentdd860052c99b1e088352bdd4fb7aef46f8d2ef47 (diff)
parent55bc1af3d9115d669570aa633e5428d6e2302e8f (diff)
downloadlinux-fc858a5231089b972076642a86cf62481d95d82e.tar.bz2
Merge tag 'net-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski: "Networking fixes for 5.13-rc1, including fixes from bpf, can and netfilter trees. Self-contained fixes, nothing risky. Current release - new code bugs: - dsa: ksz: fix a few bugs found by static-checker in the new driver - stmmac: fix frame preemption handshake not triggering after interface restart Previous releases - regressions: - make nla_strcmp handle more then one trailing null character - fix stack OOB reads while fragmenting IPv4 packets in openvswitch and net/sched - sctp: do asoc update earlier in sctp_sf_do_dupcook_a - sctp: delay auto_asconf init until binding the first addr - stmmac: clear receive all(RA) bit when promiscuous mode is off - can: mcp251x: fix resume from sleep before interface was brought up Previous releases - always broken: - bpf: fix leakage of uninitialized bpf stack under speculation - bpf: fix masking negation logic upon negative dst register - netfilter: don't assume that skb_header_pointer() will never fail - only allow init netns to set default tcp cong to a restricted algo - xsk: fix xp_aligned_validate_desc() when len == chunk_size to avoid false positive errors - ethtool: fix missing NLM_F_MULTI flag when dumping - can: m_can: m_can_tx_work_queue(): fix tx_skb race condition - sctp: fix a SCTP_MIB_CURRESTAB leak in sctp_sf_do_dupcook_b - bridge: fix NULL-deref caused by a races between assigning rx_handler_data and setting the IFF_BRIDGE_PORT bit Latecomer: - seg6: add counters support for SRv6 Behaviors" * tag 'net-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (73 commits) atm: firestream: Use fallthrough pseudo-keyword net: stmmac: Do not enable RX FIFO overflow interrupts mptcp: fix splat when closing unaccepted socket i40e: Remove LLDP frame filters i40e: Fix PHY type identifiers for 2.5G and 5G adapters i40e: fix the restart auto-negotiation after FEC modified i40e: Fix use-after-free in i40e_client_subtask() i40e: fix broken XDP support netfilter: nftables: avoid potential overflows on 32bit arches netfilter: nftables: avoid overflows in nft_hash_buckets() tcp: Specify cmsgbuf is user pointer for receive zerocopy. mlxsw: spectrum_mr: Update egress RIF list before route's action net: ipa: fix inter-EE IRQ register definitions can: m_can: m_can_tx_work_queue(): fix tx_skb race condition can: mcp251x: fix resume from sleep before interface was brought up can: mcp251xfd: mcp251xfd_probe(): add missing can_rx_offload_del() in error path can: mcp251xfd: mcp251xfd_probe(): fix an error pointer dereference in probe netfilter: nftables: Fix a memleak from userdata error path in new objects netfilter: remove BUG_ON() after skb_header_pointer() netfilter: nfnetlink_osf: Fix a missing skb_header_pointer() NULL check ...
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b7b90135c36a..40f9f6c4a0a1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -357,6 +357,18 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
return af;
}
+static void sctp_auto_asconf_init(struct sctp_sock *sp)
+{
+ struct net *net = sock_net(&sp->inet.sk);
+
+ if (net->sctp.default_auto_asconf) {
+ spin_lock(&net->sctp.addr_wq_lock);
+ list_add_tail(&sp->auto_asconf_list, &net->sctp.auto_asconf_splist);
+ spin_unlock(&net->sctp.addr_wq_lock);
+ sp->do_auto_asconf = 1;
+ }
+}
+
/* Bind a local address either to an endpoint or to an association. */
static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
{
@@ -418,8 +430,10 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
return -EADDRINUSE;
/* Refresh ephemeral port. */
- if (!bp->port)
+ if (!bp->port) {
bp->port = inet_sk(sk)->inet_num;
+ sctp_auto_asconf_init(sp);
+ }
/* Add the address to the bind address list.
* Use GFP_ATOMIC since BHs will be disabled.
@@ -1520,9 +1534,11 @@ static void sctp_close(struct sock *sk, long timeout)
/* Supposedly, no process has access to the socket, but
* the net layers still may.
+ * Also, sctp_destroy_sock() needs to be called with addr_wq_lock
+ * held and that should be grabbed before socket lock.
*/
- local_bh_disable();
- bh_lock_sock(sk);
+ spin_lock_bh(&net->sctp.addr_wq_lock);
+ bh_lock_sock_nested(sk);
/* Hold the sock, since sk_common_release() will put sock_put()
* and we have just a little more cleanup.
@@ -1531,7 +1547,7 @@ static void sctp_close(struct sock *sk, long timeout)
sk_common_release(sk);
bh_unlock_sock(sk);
- local_bh_enable();
+ spin_unlock_bh(&net->sctp.addr_wq_lock);
sock_put(sk);
@@ -4991,16 +5007,6 @@ static int sctp_init_sock(struct sock *sk)
sk_sockets_allocated_inc(sk);
sock_prot_inuse_add(net, sk->sk_prot, 1);
- if (net->sctp.default_auto_asconf) {
- spin_lock(&sock_net(sk)->sctp.addr_wq_lock);
- list_add_tail(&sp->auto_asconf_list,
- &net->sctp.auto_asconf_splist);
- sp->do_auto_asconf = 1;
- spin_unlock(&sock_net(sk)->sctp.addr_wq_lock);
- } else {
- sp->do_auto_asconf = 0;
- }
-
local_bh_enable();
return 0;
@@ -5025,9 +5031,7 @@ static void sctp_destroy_sock(struct sock *sk)
if (sp->do_auto_asconf) {
sp->do_auto_asconf = 0;
- spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock);
list_del(&sp->auto_asconf_list);
- spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock);
}
sctp_endpoint_free(sp->ep);
local_bh_disable();
@@ -9398,6 +9402,8 @@ static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
return err;
}
+ sctp_auto_asconf_init(newsp);
+
/* Move any messages in the old socket's receive queue that are for the
* peeled off association to the new socket's receive queue.
*/