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

ipv4: Stop using NLA_PUT*().

These macros contain a hidden goto, and are thus extremely error
prone and make code hard to audit.

Signed-off-by: David S. Miller <davem@davemloft.net>

+87 -73
+9 -11
net/ipv4/devinet.c
··· 1267 1267 ifm->ifa_scope = ifa->ifa_scope; 1268 1268 ifm->ifa_index = ifa->ifa_dev->dev->ifindex; 1269 1269 1270 - if (ifa->ifa_address) 1271 - NLA_PUT_BE32(skb, IFA_ADDRESS, ifa->ifa_address); 1272 - 1273 - if (ifa->ifa_local) 1274 - NLA_PUT_BE32(skb, IFA_LOCAL, ifa->ifa_local); 1275 - 1276 - if (ifa->ifa_broadcast) 1277 - NLA_PUT_BE32(skb, IFA_BROADCAST, ifa->ifa_broadcast); 1278 - 1279 - if (ifa->ifa_label[0]) 1280 - NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label); 1270 + if ((ifa->ifa_address && 1271 + nla_put_be32(skb, IFA_ADDRESS, ifa->ifa_address)) || 1272 + (ifa->ifa_local && 1273 + nla_put_be32(skb, IFA_LOCAL, ifa->ifa_local)) || 1274 + (ifa->ifa_broadcast && 1275 + nla_put_be32(skb, IFA_BROADCAST, ifa->ifa_broadcast)) || 1276 + (ifa->ifa_label[0] && 1277 + nla_put_string(skb, IFA_LABEL, ifa->ifa_label))) 1278 + goto nla_put_failure; 1281 1279 1282 1280 return nlmsg_end(skb, nlh); 1283 1281
+8 -8
net/ipv4/fib_rules.c
··· 221 221 frh->src_len = rule4->src_len; 222 222 frh->tos = rule4->tos; 223 223 224 - if (rule4->dst_len) 225 - NLA_PUT_BE32(skb, FRA_DST, rule4->dst); 226 - 227 - if (rule4->src_len) 228 - NLA_PUT_BE32(skb, FRA_SRC, rule4->src); 229 - 224 + if ((rule4->dst_len && 225 + nla_put_be32(skb, FRA_DST, rule4->dst)) || 226 + (rule4->src_len && 227 + nla_put_be32(skb, FRA_SRC, rule4->src))) 228 + goto nla_put_failure; 230 229 #ifdef CONFIG_IP_ROUTE_CLASSID 231 - if (rule4->tclassid) 232 - NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid); 230 + if (rule4->tclassid && 231 + nla_put_u32(skb, FRA_FLOW, rule4->tclassid)) 232 + goto nla_put_failure; 233 233 #endif 234 234 return 0; 235 235
+26 -21
net/ipv4/fib_semantics.c
··· 932 932 rtm->rtm_table = tb_id; 933 933 else 934 934 rtm->rtm_table = RT_TABLE_COMPAT; 935 - NLA_PUT_U32(skb, RTA_TABLE, tb_id); 935 + if (nla_put_u32(skb, RTA_TABLE, tb_id)) 936 + goto nla_put_failure; 936 937 rtm->rtm_type = type; 937 938 rtm->rtm_flags = fi->fib_flags; 938 939 rtm->rtm_scope = fi->fib_scope; 939 940 rtm->rtm_protocol = fi->fib_protocol; 940 941 941 - if (rtm->rtm_dst_len) 942 - NLA_PUT_BE32(skb, RTA_DST, dst); 943 - 944 - if (fi->fib_priority) 945 - NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority); 946 - 942 + if (rtm->rtm_dst_len && 943 + nla_put_be32(skb, RTA_DST, dst)) 944 + goto nla_put_failure; 945 + if (fi->fib_priority && 946 + nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority)) 947 + goto nla_put_failure; 947 948 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) 948 949 goto nla_put_failure; 949 950 950 - if (fi->fib_prefsrc) 951 - NLA_PUT_BE32(skb, RTA_PREFSRC, fi->fib_prefsrc); 952 - 951 + if (fi->fib_prefsrc && 952 + nla_put_be32(skb, RTA_PREFSRC, fi->fib_prefsrc)) 953 + goto nla_put_failure; 953 954 if (fi->fib_nhs == 1) { 954 - if (fi->fib_nh->nh_gw) 955 - NLA_PUT_BE32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw); 956 - 957 - if (fi->fib_nh->nh_oif) 958 - NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif); 955 + if (fi->fib_nh->nh_gw && 956 + nla_put_be32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw)) 957 + goto nla_put_failure; 958 + if (fi->fib_nh->nh_oif && 959 + nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif)) 960 + goto nla_put_failure; 959 961 #ifdef CONFIG_IP_ROUTE_CLASSID 960 - if (fi->fib_nh[0].nh_tclassid) 961 - NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid); 962 + if (fi->fib_nh[0].nh_tclassid && 963 + nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid)) 964 + goto nla_put_failure; 962 965 #endif 963 966 } 964 967 #ifdef CONFIG_IP_ROUTE_MULTIPATH ··· 982 979 rtnh->rtnh_hops = nh->nh_weight - 1; 983 980 rtnh->rtnh_ifindex = nh->nh_oif; 984 981 985 - if (nh->nh_gw) 986 - NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw); 982 + if (nh->nh_gw && 983 + nla_put_be32(skb, RTA_GATEWAY, nh->nh_gw)) 984 + goto nla_put_failure; 987 985 #ifdef CONFIG_IP_ROUTE_CLASSID 988 - if (nh->nh_tclassid) 989 - NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid); 986 + if (nh->nh_tclassid && 987 + nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid)) 988 + goto nla_put_failure; 990 989 #endif 991 990 /* length of rtnetlink header + attributes */ 992 991 rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
+12 -11
net/ipv4/ip_gre.c
··· 1654 1654 struct ip_tunnel *t = netdev_priv(dev); 1655 1655 struct ip_tunnel_parm *p = &t->parms; 1656 1656 1657 - NLA_PUT_U32(skb, IFLA_GRE_LINK, p->link); 1658 - NLA_PUT_BE16(skb, IFLA_GRE_IFLAGS, p->i_flags); 1659 - NLA_PUT_BE16(skb, IFLA_GRE_OFLAGS, p->o_flags); 1660 - NLA_PUT_BE32(skb, IFLA_GRE_IKEY, p->i_key); 1661 - NLA_PUT_BE32(skb, IFLA_GRE_OKEY, p->o_key); 1662 - NLA_PUT_BE32(skb, IFLA_GRE_LOCAL, p->iph.saddr); 1663 - NLA_PUT_BE32(skb, IFLA_GRE_REMOTE, p->iph.daddr); 1664 - NLA_PUT_U8(skb, IFLA_GRE_TTL, p->iph.ttl); 1665 - NLA_PUT_U8(skb, IFLA_GRE_TOS, p->iph.tos); 1666 - NLA_PUT_U8(skb, IFLA_GRE_PMTUDISC, !!(p->iph.frag_off & htons(IP_DF))); 1667 - 1657 + if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) || 1658 + nla_put_be16(skb, IFLA_GRE_IFLAGS, p->i_flags) || 1659 + nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || 1660 + nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || 1661 + nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || 1662 + nla_put_be32(skb, IFLA_GRE_LOCAL, p->iph.saddr) || 1663 + nla_put_be32(skb, IFLA_GRE_REMOTE, p->iph.daddr) || 1664 + nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) || 1665 + nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) || 1666 + nla_put_u8(skb, IFLA_GRE_PMTUDISC, 1667 + !!(p->iph.frag_off & htons(IP_DF)))) 1668 + goto nla_put_failure; 1668 1669 return 0; 1669 1670 1670 1671 nla_put_failure:
+5 -4
net/ipv4/ipmr.c
··· 2120 2120 rtm->rtm_src_len = 32; 2121 2121 rtm->rtm_tos = 0; 2122 2122 rtm->rtm_table = mrt->id; 2123 - NLA_PUT_U32(skb, RTA_TABLE, mrt->id); 2123 + if (nla_put_u32(skb, RTA_TABLE, mrt->id)) 2124 + goto nla_put_failure; 2124 2125 rtm->rtm_type = RTN_MULTICAST; 2125 2126 rtm->rtm_scope = RT_SCOPE_UNIVERSE; 2126 2127 rtm->rtm_protocol = RTPROT_UNSPEC; 2127 2128 rtm->rtm_flags = 0; 2128 2129 2129 - NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin); 2130 - NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp); 2131 - 2130 + if (nla_put_be32(skb, RTA_SRC, c->mfc_origin) || 2131 + nla_put_be32(skb, RTA_DST, c->mfc_mcastgrp)) 2132 + goto nla_put_failure; 2132 2133 if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0) 2133 2134 goto nla_put_failure; 2134 2135
+27 -18
net/ipv4/route.c
··· 2973 2973 r->rtm_src_len = 0; 2974 2974 r->rtm_tos = rt->rt_key_tos; 2975 2975 r->rtm_table = RT_TABLE_MAIN; 2976 - NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); 2976 + if (nla_put_u32(skb, RTA_TABLE, RT_TABLE_MAIN)) 2977 + goto nla_put_failure; 2977 2978 r->rtm_type = rt->rt_type; 2978 2979 r->rtm_scope = RT_SCOPE_UNIVERSE; 2979 2980 r->rtm_protocol = RTPROT_UNSPEC; ··· 2982 2981 if (rt->rt_flags & RTCF_NOTIFY) 2983 2982 r->rtm_flags |= RTM_F_NOTIFY; 2984 2983 2985 - NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst); 2986 - 2984 + if (nla_put_be32(skb, RTA_DST, rt->rt_dst)) 2985 + goto nla_put_failure; 2987 2986 if (rt->rt_key_src) { 2988 2987 r->rtm_src_len = 32; 2989 - NLA_PUT_BE32(skb, RTA_SRC, rt->rt_key_src); 2988 + if (nla_put_be32(skb, RTA_SRC, rt->rt_key_src)) 2989 + goto nla_put_failure; 2990 2990 } 2991 - if (rt->dst.dev) 2992 - NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex); 2991 + if (rt->dst.dev && 2992 + nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) 2993 + goto nla_put_failure; 2993 2994 #ifdef CONFIG_IP_ROUTE_CLASSID 2994 - if (rt->dst.tclassid) 2995 - NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); 2995 + if (rt->dst.tclassid && 2996 + nla_put_u32(skb, RTA_FLOW, rt->dst.tclassid)) 2997 + goto nla_put_failure; 2996 2998 #endif 2997 - if (rt_is_input_route(rt)) 2998 - NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst); 2999 - else if (rt->rt_src != rt->rt_key_src) 3000 - NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src); 3001 - 3002 - if (rt->rt_dst != rt->rt_gateway) 3003 - NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway); 2999 + if (rt_is_input_route(rt)) { 3000 + if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_spec_dst)) 3001 + goto nla_put_failure; 3002 + } else if (rt->rt_src != rt->rt_key_src) { 3003 + if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_src)) 3004 + goto nla_put_failure; 3005 + } 3006 + if (rt->rt_dst != rt->rt_gateway && 3007 + nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway)) 3008 + goto nla_put_failure; 3004 3009 3005 3010 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 3006 3011 goto nla_put_failure; 3007 3012 3008 - if (rt->rt_mark) 3009 - NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark); 3013 + if (rt->rt_mark && 3014 + nla_put_be32(skb, RTA_MARK, rt->rt_mark)) 3015 + goto nla_put_failure; 3010 3016 3011 3017 error = rt->dst.error; 3012 3018 if (peer) { ··· 3054 3046 } 3055 3047 } else 3056 3048 #endif 3057 - NLA_PUT_U32(skb, RTA_IIF, rt->rt_iif); 3049 + if (nla_put_u32(skb, RTA_IIF, rt->rt_iif)) 3050 + goto nla_put_failure; 3058 3051 } 3059 3052 3060 3053 if (rtnl_put_cacheinfo(skb, &rt->dst, id, ts, tsage,