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>
This commit is contained in:
David S. Miller 2012-04-01 20:39:02 -04:00
parent e549a6b3a5
commit f3756b79e8
6 changed files with 87 additions and 73 deletions

View file

@ -1267,17 +1267,15 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
ifm->ifa_scope = ifa->ifa_scope; ifm->ifa_scope = ifa->ifa_scope;
ifm->ifa_index = ifa->ifa_dev->dev->ifindex; ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
if (ifa->ifa_address) if ((ifa->ifa_address &&
NLA_PUT_BE32(skb, IFA_ADDRESS, ifa->ifa_address); nla_put_be32(skb, IFA_ADDRESS, ifa->ifa_address)) ||
(ifa->ifa_local &&
if (ifa->ifa_local) nla_put_be32(skb, IFA_LOCAL, ifa->ifa_local)) ||
NLA_PUT_BE32(skb, IFA_LOCAL, ifa->ifa_local); (ifa->ifa_broadcast &&
nla_put_be32(skb, IFA_BROADCAST, ifa->ifa_broadcast)) ||
if (ifa->ifa_broadcast) (ifa->ifa_label[0] &&
NLA_PUT_BE32(skb, IFA_BROADCAST, ifa->ifa_broadcast); nla_put_string(skb, IFA_LABEL, ifa->ifa_label)))
goto nla_put_failure;
if (ifa->ifa_label[0])
NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
return nlmsg_end(skb, nlh); return nlmsg_end(skb, nlh);

View file

@ -221,15 +221,15 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
frh->src_len = rule4->src_len; frh->src_len = rule4->src_len;
frh->tos = rule4->tos; frh->tos = rule4->tos;
if (rule4->dst_len) if ((rule4->dst_len &&
NLA_PUT_BE32(skb, FRA_DST, rule4->dst); nla_put_be32(skb, FRA_DST, rule4->dst)) ||
(rule4->src_len &&
if (rule4->src_len) nla_put_be32(skb, FRA_SRC, rule4->src)))
NLA_PUT_BE32(skb, FRA_SRC, rule4->src); goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID #ifdef CONFIG_IP_ROUTE_CLASSID
if (rule4->tclassid) if (rule4->tclassid &&
NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid); nla_put_u32(skb, FRA_FLOW, rule4->tclassid))
goto nla_put_failure;
#endif #endif
return 0; return 0;

View file

@ -932,33 +932,36 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
rtm->rtm_table = tb_id; rtm->rtm_table = tb_id;
else else
rtm->rtm_table = RT_TABLE_COMPAT; rtm->rtm_table = RT_TABLE_COMPAT;
NLA_PUT_U32(skb, RTA_TABLE, tb_id); if (nla_put_u32(skb, RTA_TABLE, tb_id))
goto nla_put_failure;
rtm->rtm_type = type; rtm->rtm_type = type;
rtm->rtm_flags = fi->fib_flags; rtm->rtm_flags = fi->fib_flags;
rtm->rtm_scope = fi->fib_scope; rtm->rtm_scope = fi->fib_scope;
rtm->rtm_protocol = fi->fib_protocol; rtm->rtm_protocol = fi->fib_protocol;
if (rtm->rtm_dst_len) if (rtm->rtm_dst_len &&
NLA_PUT_BE32(skb, RTA_DST, dst); nla_put_be32(skb, RTA_DST, dst))
goto nla_put_failure;
if (fi->fib_priority) if (fi->fib_priority &&
NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority); nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority))
goto nla_put_failure;
if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
goto nla_put_failure; goto nla_put_failure;
if (fi->fib_prefsrc) if (fi->fib_prefsrc &&
NLA_PUT_BE32(skb, RTA_PREFSRC, fi->fib_prefsrc); nla_put_be32(skb, RTA_PREFSRC, fi->fib_prefsrc))
goto nla_put_failure;
if (fi->fib_nhs == 1) { if (fi->fib_nhs == 1) {
if (fi->fib_nh->nh_gw) if (fi->fib_nh->nh_gw &&
NLA_PUT_BE32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw); nla_put_be32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw))
goto nla_put_failure;
if (fi->fib_nh->nh_oif) if (fi->fib_nh->nh_oif &&
NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif); nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))
goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID #ifdef CONFIG_IP_ROUTE_CLASSID
if (fi->fib_nh[0].nh_tclassid) if (fi->fib_nh[0].nh_tclassid &&
NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid); nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid))
goto nla_put_failure;
#endif #endif
} }
#ifdef CONFIG_IP_ROUTE_MULTIPATH #ifdef CONFIG_IP_ROUTE_MULTIPATH
@ -979,11 +982,13 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
rtnh->rtnh_hops = nh->nh_weight - 1; rtnh->rtnh_hops = nh->nh_weight - 1;
rtnh->rtnh_ifindex = nh->nh_oif; rtnh->rtnh_ifindex = nh->nh_oif;
if (nh->nh_gw) if (nh->nh_gw &&
NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw); nla_put_be32(skb, RTA_GATEWAY, nh->nh_gw))
goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID #ifdef CONFIG_IP_ROUTE_CLASSID
if (nh->nh_tclassid) if (nh->nh_tclassid &&
NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid); nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
goto nla_put_failure;
#endif #endif
/* length of rtnetlink header + attributes */ /* length of rtnetlink header + attributes */
rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh; rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;

View file

@ -1654,17 +1654,18 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
struct ip_tunnel *t = netdev_priv(dev); struct ip_tunnel *t = netdev_priv(dev);
struct ip_tunnel_parm *p = &t->parms; struct ip_tunnel_parm *p = &t->parms;
NLA_PUT_U32(skb, IFLA_GRE_LINK, p->link); if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
NLA_PUT_BE16(skb, IFLA_GRE_IFLAGS, p->i_flags); nla_put_be16(skb, IFLA_GRE_IFLAGS, p->i_flags) ||
NLA_PUT_BE16(skb, IFLA_GRE_OFLAGS, p->o_flags); nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) ||
NLA_PUT_BE32(skb, IFLA_GRE_IKEY, p->i_key); nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
NLA_PUT_BE32(skb, IFLA_GRE_OKEY, p->o_key); nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
NLA_PUT_BE32(skb, IFLA_GRE_LOCAL, p->iph.saddr); nla_put_be32(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
NLA_PUT_BE32(skb, IFLA_GRE_REMOTE, p->iph.daddr); nla_put_be32(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
NLA_PUT_U8(skb, IFLA_GRE_TTL, p->iph.ttl); nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
NLA_PUT_U8(skb, IFLA_GRE_TOS, p->iph.tos); nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
NLA_PUT_U8(skb, IFLA_GRE_PMTUDISC, !!(p->iph.frag_off & htons(IP_DF))); nla_put_u8(skb, IFLA_GRE_PMTUDISC,
!!(p->iph.frag_off & htons(IP_DF))))
goto nla_put_failure;
return 0; return 0;
nla_put_failure: nla_put_failure:

View file

@ -2120,15 +2120,16 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
rtm->rtm_src_len = 32; rtm->rtm_src_len = 32;
rtm->rtm_tos = 0; rtm->rtm_tos = 0;
rtm->rtm_table = mrt->id; rtm->rtm_table = mrt->id;
NLA_PUT_U32(skb, RTA_TABLE, mrt->id); if (nla_put_u32(skb, RTA_TABLE, mrt->id))
goto nla_put_failure;
rtm->rtm_type = RTN_MULTICAST; rtm->rtm_type = RTN_MULTICAST;
rtm->rtm_scope = RT_SCOPE_UNIVERSE; rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_protocol = RTPROT_UNSPEC; rtm->rtm_protocol = RTPROT_UNSPEC;
rtm->rtm_flags = 0; rtm->rtm_flags = 0;
NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin); if (nla_put_be32(skb, RTA_SRC, c->mfc_origin) ||
NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp); nla_put_be32(skb, RTA_DST, c->mfc_mcastgrp))
goto nla_put_failure;
if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0) if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0)
goto nla_put_failure; goto nla_put_failure;

View file

@ -2973,7 +2973,8 @@ static int rt_fill_info(struct net *net,
r->rtm_src_len = 0; r->rtm_src_len = 0;
r->rtm_tos = rt->rt_key_tos; r->rtm_tos = rt->rt_key_tos;
r->rtm_table = RT_TABLE_MAIN; r->rtm_table = RT_TABLE_MAIN;
NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); if (nla_put_u32(skb, RTA_TABLE, RT_TABLE_MAIN))
goto nla_put_failure;
r->rtm_type = rt->rt_type; r->rtm_type = rt->rt_type;
r->rtm_scope = RT_SCOPE_UNIVERSE; r->rtm_scope = RT_SCOPE_UNIVERSE;
r->rtm_protocol = RTPROT_UNSPEC; r->rtm_protocol = RTPROT_UNSPEC;
@ -2981,31 +2982,38 @@ static int rt_fill_info(struct net *net,
if (rt->rt_flags & RTCF_NOTIFY) if (rt->rt_flags & RTCF_NOTIFY)
r->rtm_flags |= RTM_F_NOTIFY; r->rtm_flags |= RTM_F_NOTIFY;
NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst); if (nla_put_be32(skb, RTA_DST, rt->rt_dst))
goto nla_put_failure;
if (rt->rt_key_src) { if (rt->rt_key_src) {
r->rtm_src_len = 32; r->rtm_src_len = 32;
NLA_PUT_BE32(skb, RTA_SRC, rt->rt_key_src); if (nla_put_be32(skb, RTA_SRC, rt->rt_key_src))
goto nla_put_failure;
} }
if (rt->dst.dev) if (rt->dst.dev &&
NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex); nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID #ifdef CONFIG_IP_ROUTE_CLASSID
if (rt->dst.tclassid) if (rt->dst.tclassid &&
NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); nla_put_u32(skb, RTA_FLOW, rt->dst.tclassid))
goto nla_put_failure;
#endif #endif
if (rt_is_input_route(rt)) if (rt_is_input_route(rt)) {
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst); if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_spec_dst))
else if (rt->rt_src != rt->rt_key_src) goto nla_put_failure;
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src); } else if (rt->rt_src != rt->rt_key_src) {
if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_src))
if (rt->rt_dst != rt->rt_gateway) goto nla_put_failure;
NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway); }
if (rt->rt_dst != rt->rt_gateway &&
nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway))
goto nla_put_failure;
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure; goto nla_put_failure;
if (rt->rt_mark) if (rt->rt_mark &&
NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark); nla_put_be32(skb, RTA_MARK, rt->rt_mark))
goto nla_put_failure;
error = rt->dst.error; error = rt->dst.error;
if (peer) { if (peer) {
@ -3046,7 +3054,8 @@ static int rt_fill_info(struct net *net,
} }
} else } else
#endif #endif
NLA_PUT_U32(skb, RTA_IIF, rt->rt_iif); if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
goto nla_put_failure;
} }
if (rtnl_put_cacheinfo(skb, &rt->dst, id, ts, tsage, if (rtnl_put_cacheinfo(skb, &rt->dst, id, ts, tsage,