From 1a3d302abd9ac4eae735a843eecb1e0fb028d722 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 10 May 2012 10:44:03 +0200 Subject: ipset: 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 --- kernel/include/linux/netfilter/ipset/ip_set.h | 46 ++++++++++++---------- .../include/linux/netfilter/ipset/ip_set_ahash.h | 21 +++++----- 2 files changed, 38 insertions(+), 29 deletions(-) (limited to 'kernel/include') diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h index 2f8e18a..d6d549c 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/linux/netfilter/ipset/ip_set.h @@ -411,26 +411,32 @@ ip_set_get_h16(const struct nlattr *attr) #define ipset_nest_start(skb, attr) nla_nest_start(skb, attr | NLA_F_NESTED) #define ipset_nest_end(skb, start) nla_nest_end(skb, start) -#define NLA_PUT_IPADDR4(skb, type, ipaddr) \ -do { \ - struct nlattr *__nested = ipset_nest_start(skb, type); \ - \ - if (!__nested) \ - goto nla_put_failure; \ - NLA_PUT_NET32(skb, IPSET_ATTR_IPADDR_IPV4, ipaddr); \ - ipset_nest_end(skb, __nested); \ -} while (0) - -#define NLA_PUT_IPADDR6(skb, type, ipaddrptr) \ -do { \ - struct nlattr *__nested = ipset_nest_start(skb, type); \ - \ - if (!__nested) \ - goto nla_put_failure; \ - NLA_PUT(skb, IPSET_ATTR_IPADDR_IPV6, \ - sizeof(struct in6_addr), ipaddrptr); \ - ipset_nest_end(skb, __nested); \ -} while (0) +static inline int nla_put_ipaddr4(struct sk_buff *skb, int type, __be32 ipaddr) +{ + struct nlattr *__nested = ipset_nest_start(skb, type); + int ret; + + if (!__nested) + return -EMSGSIZE; + ret = nla_put_net32(skb, IPSET_ATTR_IPADDR_IPV4, ipaddr); + if (!ret) + ipset_nest_end(skb, __nested); + return ret; +} + +static inline int nla_put_ipaddr6(struct sk_buff *skb, int type, const struct in6_addr *ipaddrptr) +{ + struct nlattr *__nested = ipset_nest_start(skb, type); + int ret; + + if (!__nested) + return -EMSGSIZE; + ret = nla_put(skb, IPSET_ATTR_IPADDR_IPV6, + sizeof(struct in6_addr), ipaddrptr); + if (!ret) + ipset_nest_end(skb, __nested); + return ret; +} /* Get address from skbuff */ static inline __be32 diff --git a/kernel/include/linux/netfilter/ipset/ip_set_ahash.h b/kernel/include/linux/netfilter/ipset/ip_set_ahash.h index 230a290..b114d35 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/kernel/include/linux/netfilter/ipset/ip_set_ahash.h @@ -610,17 +610,20 @@ type_pf_head(struct ip_set *set, struct sk_buff *skb) nested = ipset_nest_start(skb, IPSET_ATTR_DATA); if (!nested) goto nla_put_failure; - NLA_PUT_NET32(skb, IPSET_ATTR_HASHSIZE, - htonl(jhash_size(h->table->htable_bits))); - NLA_PUT_NET32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)); + if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE, + htonl(jhash_size(h->table->htable_bits))) || + nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem))) + goto nla_put_failure; #ifdef IP_SET_HASH_WITH_NETMASK - if (h->netmask != HOST_MASK) - NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask); + if (h->netmask != HOST_MASK && + nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask)) + goto nla_put_failure; #endif - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); - NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)); - if (with_timeout(h->timeout)) - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout)); + if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || + nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) || + (with_timeout(h->timeout) && + nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout)))) + goto nla_put_failure; ipset_nest_end(skb, nested); return 0; -- cgit v1.2.3