Skip to content

Commit a527750

Browse files
edumazetkuba-moo
authored andcommitted
ipv6: mcast: add RCU protection to mld_newpack()
mld_newpack() can be called without RTNL or RCU being held. Note that we no longer can use sock_alloc_send_skb() because ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep. Instead use alloc_skb() and charge the net->ipv6.igmp_sk socket under RCU protection. Fixes: b8ad0cb ("[NETNS][IPV6] mcast - handle several network namespace") Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: David Ahern <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5bef3ac commit a527750

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

net/ipv6/mcast.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,28 +1773,32 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
17731773
struct net_device *dev = idev->dev;
17741774
int hlen = LL_RESERVED_SPACE(dev);
17751775
int tlen = dev->needed_tailroom;
1776-
struct net *net = dev_net(dev);
17771776
const struct in6_addr *saddr;
17781777
struct in6_addr addr_buf;
17791778
struct mld2_report *pmr;
17801779
struct sk_buff *skb;
17811780
unsigned int size;
17821781
struct sock *sk;
1783-
int err;
1782+
struct net *net;
17841783

1785-
sk = net->ipv6.igmp_sk;
17861784
/* we assume size > sizeof(ra) here
17871785
* Also try to not allocate high-order pages for big MTU
17881786
*/
17891787
size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen;
1790-
skb = sock_alloc_send_skb(sk, size, 1, &err);
1788+
skb = alloc_skb(size, GFP_KERNEL);
17911789
if (!skb)
17921790
return NULL;
17931791

17941792
skb->priority = TC_PRIO_CONTROL;
17951793
skb_reserve(skb, hlen);
17961794
skb_tailroom_reserve(skb, mtu, tlen);
17971795

1796+
rcu_read_lock();
1797+
1798+
net = dev_net_rcu(dev);
1799+
sk = net->ipv6.igmp_sk;
1800+
skb_set_owner_w(skb, sk);
1801+
17981802
if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
17991803
/* <draft-ietf-magma-mld-source-05.txt>:
18001804
* use unspecified address as the source address
@@ -1806,6 +1810,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
18061810

18071811
ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0);
18081812

1813+
rcu_read_unlock();
1814+
18091815
skb_put_data(skb, ra, sizeof(ra));
18101816

18111817
skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data);

0 commit comments

Comments
 (0)