[<prev] [next>] [day] [month] [year] [list]
Message-ID: <649F6CF5-85D9-40EE-85D1-F698CE1757A2@purdue.edu>
Date: Mon, 30 Nov 2020 17:35:52 +0000
From: "Gong, Sishuai" <sishuai@...due.edu>
To: "davem@...emloft.net" <davem@...emloft.net>,
"kuznet@....inr.ac.ru" <kuznet@....inr.ac.ru>,
"yoshfuji@...ux-ipv6.org" <yoshfuji@...ux-ipv6.org>
CC: "netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: Race: data race between rawv6_send_hdrinc() and __dev_set_mtu()
Hi,
We found a data race in linux kernel 5.3.11 that we are able to reproduce in x86 under specific interleavings. Currently, we are not sure about the consequence of this race so we would like to confirm with the community if this can be a harmful bug.
------------------------------------------
Writer site
/tmp/tmp.B7zb7od2zE-5.3.11/extract/linux-5.3.11/net/core/dev.c:7665
7658 int __dev_set_mtu(struct net_device *dev, int new_mtu)
7659 {
7660 const struct net_device_ops *ops = dev->netdev_ops;
7661
7662 if (ops->ndo_change_mtu)
7663 return ops->ndo_change_mtu(dev, new_mtu);
7664
==> 7665 dev->mtu = new_mtu;
7666 return 0;
------------------------------------------
Reader site
/tmp/tmp.B7zb7od2zE-5.3.11/extract/linux-5.3.11/net/ipv6/raw.c:632
618 static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
619 struct flowi6 *fl6, struct dst_entry **dstp,
620 unsigned int flags, const struct sockcm_cookie *sockc)
621 {
622 struct ipv6_pinfo *np = inet6_sk(sk);
623 struct net *net = sock_net(sk);
624 struct ipv6hdr *iph;
625 struct sk_buff *skb;
626 int err;
627 struct rt6_info *rt = (struct rt6_info *)*dstp;
628 int hlen = LL_RESERVED_SPACE(rt->dst.dev);
629 int tlen = rt->dst.dev->needed_tailroom;
630
631 if (length > rt->dst.dev->mtu) {
==> 632 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
633 return -EMSGSIZE;
634 }
635 if (length < sizeof(struct ipv6hdr))
636 return -EINVAL;
637 if (flags&MSG_PROBE)
638 goto out;
639
640 skb = sock_alloc_send_skb(sk,
641 length + hlen + tlen + 15,
642 flags & MSG_DONTWAIT, &err);
643 if (!skb)
644 goto error;
645 skb_reserve(skb, hlen);
646
647 skb->protocol = htons(ETH_P_IPV6);
648 skb->priority = sk->sk_priority;
649 skb->mark = sk->sk_mark;
650 skb->tstamp = sockc->transmit_time;
651
652 skb_put(skb, length);
------------------------------------------
Writer calling trace
- ksys_ioctl
-- do_vfs_ioctl
--- vfs_ioctl
---- dev_ioctl
----- dev_ifsioc
------ dev_set_mtu
------- dev_set_mtu_ext
-------- __dev_set_mtu
------------------------------------------
Reader calling trace
- __sys_sendto
-- sock_sendmsg
--- inet_sendmsg
---- rawv6_sendmsg
Thanks,
Sishuai
Powered by blists - more mailing lists