ipv6: 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:27:33 -04:00
parent 86ebb02dc7
commit c78679e8f3
5 changed files with 53 additions and 46 deletions

View File

@ -3989,14 +3989,14 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
struct nlattr *nla; struct nlattr *nla;
struct ifla_cacheinfo ci; struct ifla_cacheinfo ci;
NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); if (nla_put_u32(skb, IFLA_INET6_FLAGS, idev->if_flags))
goto nla_put_failure;
ci.max_reasm_len = IPV6_MAXPLEN; ci.max_reasm_len = IPV6_MAXPLEN;
ci.tstamp = cstamp_delta(idev->tstamp); ci.tstamp = cstamp_delta(idev->tstamp);
ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time); ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time); ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci))
goto nla_put_failure;
nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
if (nla == NULL) if (nla == NULL)
goto nla_put_failure; goto nla_put_failure;
@ -4061,15 +4061,13 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
hdr->ifi_flags = dev_get_flags(dev); hdr->ifi_flags = dev_get_flags(dev);
hdr->ifi_change = 0; hdr->ifi_change = 0;
NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name); if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
(dev->addr_len &&
if (dev->addr_len) nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
(dev->ifindex != dev->iflink &&
NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); nla_put_u32(skb, IFLA_LINK, dev->iflink)))
if (dev->ifindex != dev->iflink) goto nla_put_failure;
NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
protoinfo = nla_nest_start(skb, IFLA_PROTINFO); protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
if (protoinfo == NULL) if (protoinfo == NULL)
goto nla_put_failure; goto nla_put_failure;
@ -4182,12 +4180,12 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
if (pinfo->autoconf) if (pinfo->autoconf)
pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;
NLA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix); if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix))
goto nla_put_failure;
ci.preferred_time = ntohl(pinfo->prefered); ci.preferred_time = ntohl(pinfo->prefered);
ci.valid_time = ntohl(pinfo->valid); ci.valid_time = ntohl(pinfo->valid);
NLA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci); if (nla_put(skb, PREFIX_CACHEINFO, sizeof(ci), &ci))
goto nla_put_failure;
return nlmsg_end(skb, nlh); return nlmsg_end(skb, nlh);
nla_put_failure: nla_put_failure:

View File

@ -215,14 +215,13 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
frh->src_len = rule6->src.plen; frh->src_len = rule6->src.plen;
frh->tos = rule6->tclass; frh->tos = rule6->tclass;
if (rule6->dst.plen) if ((rule6->dst.plen &&
NLA_PUT(skb, FRA_DST, sizeof(struct in6_addr), nla_put(skb, FRA_DST, sizeof(struct in6_addr),
&rule6->dst.addr); &rule6->dst.addr)) ||
(rule6->src.plen &&
if (rule6->src.plen) nla_put(skb, FRA_SRC, sizeof(struct in6_addr),
NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr), &rule6->src.addr)))
&rule6->src.addr); goto nla_put_failure;
return 0; return 0;
nla_put_failure: nla_put_failure:

View File

@ -2216,14 +2216,15 @@ static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
rtm->rtm_src_len = 128; rtm->rtm_src_len = 128;
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_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(skb, RTA_SRC, 16, &c->mf6c_origin); if (nla_put(skb, RTA_SRC, 16, &c->mf6c_origin) ||
NLA_PUT(skb, RTA_DST, 16, &c->mf6c_mcastgrp); nla_put(skb, RTA_DST, 16, &c->mf6c_mcastgrp))
goto nla_put_failure;
if (__ip6mr_fill_mroute(mrt, skb, c, rtm) < 0) if (__ip6mr_fill_mroute(mrt, skb, c, rtm) < 0)
goto nla_put_failure; goto nla_put_failure;

View File

@ -1099,8 +1099,9 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3); memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
NLA_PUT(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr), if (nla_put(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr),
&ipv6_hdr(ra)->saddr); &ipv6_hdr(ra)->saddr))
goto nla_put_failure;
nlmsg_end(skb, nlh); nlmsg_end(skb, nlh);
rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC); rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);

View File

@ -2413,7 +2413,8 @@ static int rt6_fill_node(struct net *net,
else else
table = RT6_TABLE_UNSPEC; table = RT6_TABLE_UNSPEC;
rtm->rtm_table = table; rtm->rtm_table = table;
NLA_PUT_U32(skb, RTA_TABLE, table); if (nla_put_u32(skb, RTA_TABLE, table))
goto nla_put_failure;
if (rt->rt6i_flags & RTF_REJECT) if (rt->rt6i_flags & RTF_REJECT)
rtm->rtm_type = RTN_UNREACHABLE; rtm->rtm_type = RTN_UNREACHABLE;
else if (rt->rt6i_flags & RTF_LOCAL) else if (rt->rt6i_flags & RTF_LOCAL)
@ -2436,16 +2437,20 @@ static int rt6_fill_node(struct net *net,
rtm->rtm_flags |= RTM_F_CLONED; rtm->rtm_flags |= RTM_F_CLONED;
if (dst) { if (dst) {
NLA_PUT(skb, RTA_DST, 16, dst); if (nla_put(skb, RTA_DST, 16, dst))
goto nla_put_failure;
rtm->rtm_dst_len = 128; rtm->rtm_dst_len = 128;
} else if (rtm->rtm_dst_len) } else if (rtm->rtm_dst_len)
NLA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr); if (nla_put(skb, RTA_DST, 16, &rt->rt6i_dst.addr))
goto nla_put_failure;
#ifdef CONFIG_IPV6_SUBTREES #ifdef CONFIG_IPV6_SUBTREES
if (src) { if (src) {
NLA_PUT(skb, RTA_SRC, 16, src); if (nla_put(skb, RTA_SRC, 16, src))
goto nla_put_failure;
rtm->rtm_src_len = 128; rtm->rtm_src_len = 128;
} else if (rtm->rtm_src_len) } else if (rtm->rtm_src_len &&
NLA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr); nla_put(skb, RTA_SRC, 16, &rt->rt6i_src.addr))
goto nla_put_failure;
#endif #endif
if (iif) { if (iif) {
#ifdef CONFIG_IPV6_MROUTE #ifdef CONFIG_IPV6_MROUTE
@ -2463,17 +2468,20 @@ static int rt6_fill_node(struct net *net,
} }
} else } else
#endif #endif
NLA_PUT_U32(skb, RTA_IIF, iif); if (nla_put_u32(skb, RTA_IIF, iif))
goto nla_put_failure;
} else if (dst) { } else if (dst) {
struct in6_addr saddr_buf; struct in6_addr saddr_buf;
if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0) if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
goto nla_put_failure;
} }
if (rt->rt6i_prefsrc.plen) { if (rt->rt6i_prefsrc.plen) {
struct in6_addr saddr_buf; struct in6_addr saddr_buf;
saddr_buf = rt->rt6i_prefsrc.addr; saddr_buf = rt->rt6i_prefsrc.addr;
NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); if (nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
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)
@ -2489,11 +2497,11 @@ static int rt6_fill_node(struct net *net,
} }
rcu_read_unlock(); rcu_read_unlock();
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;
NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); if (nla_put_u32(skb, RTA_PRIORITY, rt->rt6i_metric))
goto nla_put_failure;
if (!(rt->rt6i_flags & RTF_EXPIRES)) if (!(rt->rt6i_flags & RTF_EXPIRES))
expires = 0; expires = 0;
else if (rt->dst.expires - jiffies < INT_MAX) else if (rt->dst.expires - jiffies < INT_MAX)