Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

inet: annotate devconf data-races

Add READ_ONCE() in ipv4_devconf_get() and corresponding
WRITE_ONCE() in ipv4_devconf_set()

Add IPV4_DEVCONF_RO() and IPV4_DEVCONF_ALL_RO() macros,
and use them when reading devconf fields.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20240227092411.2315725-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
0598f8f3 e83ddcea

+24 -21
+8 -6
include/linux/inetdevice.h
··· 53 53 }; 54 54 55 55 #define IPV4_DEVCONF(cnf, attr) ((cnf).data[IPV4_DEVCONF_ ## attr - 1]) 56 + #define IPV4_DEVCONF_RO(cnf, attr) READ_ONCE(IPV4_DEVCONF(cnf, attr)) 56 57 #define IPV4_DEVCONF_ALL(net, attr) \ 57 58 IPV4_DEVCONF((*(net)->ipv4.devconf_all), attr) 59 + #define IPV4_DEVCONF_ALL_RO(net, attr) READ_ONCE(IPV4_DEVCONF_ALL(net, attr)) 58 60 59 - static inline int ipv4_devconf_get(struct in_device *in_dev, int index) 61 + static inline int ipv4_devconf_get(const struct in_device *in_dev, int index) 60 62 { 61 63 index--; 62 - return in_dev->cnf.data[index]; 64 + return READ_ONCE(in_dev->cnf.data[index]); 63 65 } 64 66 65 67 static inline void ipv4_devconf_set(struct in_device *in_dev, int index, ··· 69 67 { 70 68 index--; 71 69 set_bit(index, in_dev->cnf.state); 72 - in_dev->cnf.data[index] = val; 70 + WRITE_ONCE(in_dev->cnf.data[index], val); 73 71 } 74 72 75 73 static inline void ipv4_devconf_setall(struct in_device *in_dev) ··· 83 81 ipv4_devconf_set((in_dev), IPV4_DEVCONF_ ## attr, (val)) 84 82 85 83 #define IN_DEV_ANDCONF(in_dev, attr) \ 86 - (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) && \ 84 + (IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), attr) && \ 87 85 IN_DEV_CONF_GET((in_dev), attr)) 88 86 89 87 #define IN_DEV_NET_ORCONF(in_dev, net, attr) \ 90 - (IPV4_DEVCONF_ALL(net, attr) || \ 88 + (IPV4_DEVCONF_ALL_RO(net, attr) || \ 91 89 IN_DEV_CONF_GET((in_dev), attr)) 92 90 93 91 #define IN_DEV_ORCONF(in_dev, attr) \ 94 92 IN_DEV_NET_ORCONF(in_dev, dev_net(in_dev->dev), attr) 95 93 96 94 #define IN_DEV_MAXCONF(in_dev, attr) \ 97 - (max(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr), \ 95 + (max(IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), attr), \ 98 96 IN_DEV_CONF_GET((in_dev), attr))) 99 97 100 98 #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
+11 -10
net/ipv4/devinet.c
··· 1982 1982 return -EMSGSIZE; 1983 1983 1984 1984 for (i = 0; i < IPV4_DEVCONF_MAX; i++) 1985 - ((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i]; 1985 + ((u32 *) nla_data(nla))[i] = READ_ONCE(in_dev->cnf.data[i]); 1986 1986 1987 1987 return 0; 1988 1988 } ··· 2068 2068 } 2069 2069 2070 2070 static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex, 2071 - struct ipv4_devconf *devconf, u32 portid, 2072 - u32 seq, int event, unsigned int flags, 2073 - int type) 2071 + const struct ipv4_devconf *devconf, 2072 + u32 portid, u32 seq, int event, 2073 + unsigned int flags, int type) 2074 2074 { 2075 2075 struct nlmsghdr *nlh; 2076 2076 struct netconfmsg *ncm; ··· 2095 2095 2096 2096 if ((all || type == NETCONFA_FORWARDING) && 2097 2097 nla_put_s32(skb, NETCONFA_FORWARDING, 2098 - IPV4_DEVCONF(*devconf, FORWARDING)) < 0) 2098 + IPV4_DEVCONF_RO(*devconf, FORWARDING)) < 0) 2099 2099 goto nla_put_failure; 2100 2100 if ((all || type == NETCONFA_RP_FILTER) && 2101 2101 nla_put_s32(skb, NETCONFA_RP_FILTER, 2102 - IPV4_DEVCONF(*devconf, RP_FILTER)) < 0) 2102 + IPV4_DEVCONF_RO(*devconf, RP_FILTER)) < 0) 2103 2103 goto nla_put_failure; 2104 2104 if ((all || type == NETCONFA_MC_FORWARDING) && 2105 2105 nla_put_s32(skb, NETCONFA_MC_FORWARDING, 2106 - IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0) 2106 + IPV4_DEVCONF_RO(*devconf, MC_FORWARDING)) < 0) 2107 2107 goto nla_put_failure; 2108 2108 if ((all || type == NETCONFA_BC_FORWARDING) && 2109 2109 nla_put_s32(skb, NETCONFA_BC_FORWARDING, 2110 - IPV4_DEVCONF(*devconf, BC_FORWARDING)) < 0) 2110 + IPV4_DEVCONF_RO(*devconf, BC_FORWARDING)) < 0) 2111 2111 goto nla_put_failure; 2112 2112 if ((all || type == NETCONFA_PROXY_NEIGH) && 2113 2113 nla_put_s32(skb, NETCONFA_PROXY_NEIGH, 2114 - IPV4_DEVCONF(*devconf, PROXY_ARP)) < 0) 2114 + IPV4_DEVCONF_RO(*devconf, PROXY_ARP)) < 0) 2115 2115 goto nla_put_failure; 2116 2116 if ((all || type == NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN) && 2117 2117 nla_put_s32(skb, NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN, 2118 - IPV4_DEVCONF(*devconf, IGNORE_ROUTES_WITH_LINKDOWN)) < 0) 2118 + IPV4_DEVCONF_RO(*devconf, 2119 + IGNORE_ROUTES_WITH_LINKDOWN)) < 0) 2119 2120 goto nla_put_failure; 2120 2121 2121 2122 out:
+2 -2
net/ipv4/igmp.c
··· 120 120 */ 121 121 122 122 #define IGMP_V1_SEEN(in_dev) \ 123 - (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 1 || \ 123 + (IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 1 || \ 124 124 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \ 125 125 ((in_dev)->mr_v1_seen && \ 126 126 time_before(jiffies, (in_dev)->mr_v1_seen))) 127 127 #define IGMP_V2_SEEN(in_dev) \ 128 - (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 2 || \ 128 + (IPV4_DEVCONF_ALL_RO(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 2 || \ 129 129 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \ 130 130 ((in_dev)->mr_v2_seen && \ 131 131 time_before(jiffies, (in_dev)->mr_v2_seen)))
+1 -1
net/ipv4/proc.c
··· 395 395 seq_printf(seq, " %s", snmp4_ipstats_list[i].name); 396 396 397 397 seq_printf(seq, "\nIp: %d %d", 398 - IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2, 398 + IPV4_DEVCONF_ALL_RO(net, FORWARDING) ? 1 : 2, 399 399 READ_ONCE(net->ipv4.sysctl_ip_default_ttl)); 400 400 401 401 BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0);
+2 -2
net/ipv4/route.c
··· 2313 2313 if (IN_DEV_BFORWARD(in_dev)) 2314 2314 goto make_route; 2315 2315 /* not do cache if bc_forwarding is enabled */ 2316 - if (IPV4_DEVCONF_ALL(net, BC_FORWARDING)) 2316 + if (IPV4_DEVCONF_ALL_RO(net, BC_FORWARDING)) 2317 2317 do_cache = false; 2318 2318 goto brd_input; 2319 2319 } ··· 2993 2993 #ifdef CONFIG_IP_MROUTE 2994 2994 if (ipv4_is_multicast(dst) && 2995 2995 !ipv4_is_local_multicast(dst) && 2996 - IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { 2996 + IPV4_DEVCONF_ALL_RO(net, MC_FORWARDING)) { 2997 2997 int err = ipmr_get_route(net, skb, 2998 2998 fl4->saddr, fl4->daddr, 2999 2999 r, portid);