diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2011-01-20 17:54:26 +0100 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2011-01-20 17:54:26 +0100 |
commit | 13f42a71e49164769a98fc51033c65a211861404 (patch) | |
tree | 966741c7765a2cf866f3a67ca4a432178eadfabe /kernel/ip_set_core.c | |
parent | c8396bdc040f4b16e6f6e3f8b81b9fb67a499d9c (diff) |
Enforce network-order data in the netlink protocol
Allow only network-order data, with NLA_F_NET_BYTEORDER flag.
Sanity checks also added to prevent processing broken messages
where mandatory attributes are missing. (Patrick McHardy's review)
Diffstat (limited to 'kernel/ip_set_core.c')
-rw-r--r-- | kernel/ip_set_core.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/kernel/ip_set_core.c b/kernel/ip_set_core.c index e449740..ba2f890 100644 --- a/kernel/ip_set_core.c +++ b/kernel/ip_set_core.c @@ -209,6 +209,12 @@ ip_set_free(void *members) } EXPORT_SYMBOL_GPL(ip_set_free); +static inline bool +flag_nested(const struct nlattr *nla) +{ + return nla->nla_type & NLA_F_NESTED; +} + static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] = { [IPSET_ATTR_IPADDR_IPV4] = { .type = NLA_U32 }, [IPSET_ATTR_IPADDR_IPV6] = { .type = NLA_BINARY, @@ -216,19 +222,17 @@ static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] = { }; int -ip_set_get_ipaddr4(struct nlattr *attr[], int type, __be32 *ipaddr) +ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr) { struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1]; - if (!attr[type]) + if (unlikely(!flag_nested(nla))) return -IPSET_ERR_PROTOCOL; - - if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX, - nla_data(attr[type]), nla_len(attr[type]), + if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX, nla_data(nla), nla_len(nla), ipaddr_policy)) return -IPSET_ERR_PROTOCOL; - if (!tb[IPSET_ATTR_IPADDR_IPV4]) - return -IPSET_ERR_IPADDR_IPV4; + if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV4))) + return -IPSET_ERR_PROTOCOL; *ipaddr = nla_get_be32(tb[IPSET_ATTR_IPADDR_IPV4]); return 0; @@ -236,19 +240,18 @@ ip_set_get_ipaddr4(struct nlattr *attr[], int type, __be32 *ipaddr) EXPORT_SYMBOL_GPL(ip_set_get_ipaddr4); int -ip_set_get_ipaddr6(struct nlattr *attr[], int type, union nf_inet_addr *ipaddr) +ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr) { struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1]; - if (!attr[type]) + if (unlikely(!flag_nested(nla))) return -IPSET_ERR_PROTOCOL; - if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX, - nla_data(attr[type]), nla_len(attr[type]), + if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX, nla_data(nla), nla_len(nla), ipaddr_policy)) return -IPSET_ERR_PROTOCOL; - if (!tb[IPSET_ATTR_IPADDR_IPV6]) - return -IPSET_ERR_IPADDR_IPV6; + if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV6))) + return -IPSET_ERR_PROTOCOL; memcpy(ipaddr, nla_data(tb[IPSET_ATTR_IPADDR_IPV6]), sizeof(struct in6_addr)); @@ -511,12 +514,6 @@ flag_exist(const struct nlmsghdr *nlh) return nlh->nlmsg_flags & NLM_F_EXCL ? 0 : IPSET_FLAG_EXIST; } -static inline bool -flag_nested(const struct nlattr *nla) -{ - return nla->nla_type & NLA_F_NESTED; -} - static struct nlmsghdr * start_msg(struct sk_buff *skb, u32 pid, u32 seq, unsigned int flags, enum ipset_cmd cmd) |