ipv6: annotate data-races around cnf.mtu6
authorEric Dumazet <edumazet@google.com>
Wed, 28 Feb 2024 13:54:28 +0000 (13:54 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 1 Mar 2024 08:42:31 +0000 (08:42 +0000)
idev->cnf.mtu6 might be read locklessly, add appropriate READ_ONCE()
and WRITE_ONCE() annotations.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip6_route.h
net/ipv6/addrconf.c
net/ipv6/ndisc.c
net/ipv6/route.c

index 52a51c69aa9de2fe1e6d351997f5b3d94862521a..a30c6aa9e5cf3e442cd29e2d169ba0b0d46a1f46 100644 (file)
@@ -332,7 +332,7 @@ static inline unsigned int ip6_dst_mtu_maybe_forward(const struct dst_entry *dst
        rcu_read_lock();
        idev = __in6_dev_get(dst->dev);
        if (idev)
-               mtu = idev->cnf.mtu6;
+               mtu = READ_ONCE(idev->cnf.mtu6);
        rcu_read_unlock();
 
 out:
index 6975685f55ea91e55bd08d3f1ebf94ffd414f2b0..1b534edc7ca2c461da19f4dca2040b94eaa4581b 100644 (file)
@@ -3671,7 +3671,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 
                if (idev) {
                        rt6_mtu_change(dev, dev->mtu);
-                       idev->cnf.mtu6 = dev->mtu;
+                       WRITE_ONCE(idev->cnf.mtu6, dev->mtu);
                        break;
                }
 
@@ -3763,7 +3763,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                        if (idev->cnf.mtu6 != dev->mtu &&
                            dev->mtu >= IPV6_MIN_MTU) {
                                rt6_mtu_change(dev, dev->mtu);
-                               idev->cnf.mtu6 = dev->mtu;
+                               WRITE_ONCE(idev->cnf.mtu6, dev->mtu);
                        }
                        WRITE_ONCE(idev->tstamp, jiffies);
                        inet6_ifinfo_notify(RTM_NEWLINK, idev);
index 8523f0595b01899a9f6cf82809c1b4bcfc233202..e96d79cd34d27ca304c5f71b6db41b99d2dd8856 100644 (file)
@@ -1578,8 +1578,8 @@ skip_routeinfo:
 
                if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
                        ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
-               } else if (in6_dev->cnf.mtu6 != mtu) {
-                       in6_dev->cnf.mtu6 = mtu;
+               } else if (READ_ONCE(in6_dev->cnf.mtu6) != mtu) {
+                       WRITE_ONCE(in6_dev->cnf.mtu6, mtu);
                        fib6_metric_set(rt, RTAX_MTU, mtu);
                        rt6_mtu_change(skb->dev, mtu);
                }
index 707d65bc9c0e5e9b2900063f0ac86c3c5e299088..66c685b0b6199fee3bc39768eab5a6fb831bd2f5 100644 (file)
@@ -1596,7 +1596,7 @@ static unsigned int fib6_mtu(const struct fib6_result *res)
 
                rcu_read_lock();
                idev = __in6_dev_get(dev);
-               mtu = idev->cnf.mtu6;
+               mtu = READ_ONCE(idev->cnf.mtu6);
                rcu_read_unlock();
        }
 
@@ -3249,8 +3249,8 @@ u32 ip6_mtu_from_fib6(const struct fib6_result *res,
 
                mtu = IPV6_MIN_MTU;
                idev = __in6_dev_get(dev);
-               if (idev && idev->cnf.mtu6 > mtu)
-                       mtu = idev->cnf.mtu6;
+               if (idev)
+                       mtu = max_t(u32, mtu, READ_ONCE(idev->cnf.mtu6));
        }
 
        mtu = min_t(unsigned int, mtu, IP6_MAX_MTU);