Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c78679e8 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parent 86ebb02d
Loading
Loading
Loading
Loading
+15 −17
Original line number Original line Diff line number Diff line
@@ -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:
+7 −8
Original line number Original line Diff line number Diff line
@@ -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:
+5 −4
Original line number Original line Diff line number Diff line
@@ -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;


+3 −2
Original line number Original line Diff line number Diff line
@@ -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);
+23 −15
Original line number Original line Diff line number Diff line
@@ -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)