summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-01-20 17:54:26 +0100
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-01-20 17:54:26 +0100
commit13f42a71e49164769a98fc51033c65a211861404 (patch)
tree966741c7765a2cf866f3a67ca4a432178eadfabe
parentc8396bdc040f4b16e6f6e3f8b81b9fb67a499d9c (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)
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set.h22
-rw-r--r--kernel/ip_set_bitmap_ip.c23
-rw-r--r--kernel/ip_set_bitmap_ipmac.c15
-rw-r--r--kernel/ip_set_bitmap_port.c43
-rw-r--r--kernel/ip_set_core.c35
-rw-r--r--kernel/ip_set_hash_ip.c19
-rw-r--r--kernel/ip_set_hash_ipport.c23
-rw-r--r--kernel/ip_set_hash_ipportip.c27
-rw-r--r--kernel/ip_set_hash_ipportnet.c27
-rw-r--r--kernel/ip_set_hash_net.c17
-rw-r--r--kernel/ip_set_hash_netport.c21
-rw-r--r--kernel/ip_set_list_set.c28
12 files changed, 214 insertions, 86 deletions
diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h
index 7679b33..61b08f1 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set.h
+++ b/kernel/include/linux/netfilter/ipset/ip_set.h
@@ -320,15 +320,14 @@ extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb,
/* Utility functions */
extern void * ip_set_alloc(size_t size, gfp_t gfp_mask);
extern void ip_set_free(void *members);
-extern int ip_set_get_ipaddr4(struct nlattr *attr[], int type, __be32 *ipaddr);
-extern int ip_set_get_ipaddr6(struct nlattr *attr[], int type,
- union nf_inet_addr *ipaddr);
+extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr);
+extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
static inline int
-ip_set_get_hostipaddr4(struct nlattr *attr[], int type, u32 *ipaddr)
+ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
{
__be32 ip;
- int ret = ip_set_get_ipaddr4(attr, type, &ip);
+ int ret = ip_set_get_ipaddr4(nla, &ip);
if (ret)
return ret;
@@ -343,6 +342,19 @@ ip_set_eexist(int ret, u32 flags)
return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST);
}
+/* Check the NLA_F_NET_BYTEORDER flag */
+static inline bool
+ip_set_attr_netorder(struct nlattr *tb[], int type)
+{
+ return tb[type] && (tb[type]->nla_type & NLA_F_NET_BYTEORDER);
+}
+
+static inline bool
+ip_set_optattr_netorder(struct nlattr *tb[], int type)
+{
+ return !tb[type] || (tb[type]->nla_type & NLA_F_NET_BYTEORDER);
+}
+
/* Useful converters */
static inline u32
ip_set_get_h32(const struct nlattr *attr)
diff --git a/kernel/ip_set_bitmap_ip.c b/kernel/ip_set_bitmap_ip.c
index 7806ecc..30db991 100644
--- a/kernel/ip_set_bitmap_ip.c
+++ b/kernel/ip_set_bitmap_ip.c
@@ -121,10 +121,13 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
bitmap_ip_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP]))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP, &ip);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
if (ret)
return ret;
@@ -140,7 +143,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
return bitmap_ip_test(map, ip_to_id(map, ip));
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
return ret;
if (ip > ip_to) {
@@ -359,10 +362,14 @@ bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
bitmap_ip_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP, &ip);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
if (ret)
return ret;
@@ -374,7 +381,7 @@ bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
ip_to_id((const struct bitmap_ip *)map, ip));
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
return ret;
if (ip > ip_to) {
@@ -598,12 +605,16 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
bitmap_ip_create_policy))
return -IPSET_ERR_PROTOCOL;
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP, &first_ip);
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
if (ret)
return ret;
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &last_ip);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
if (ret)
return ret;
if (first_ip > last_ip) {
diff --git a/kernel/ip_set_bitmap_ipmac.c b/kernel/ip_set_bitmap_ipmac.c
index 49e7ed1..87870a3 100644
--- a/kernel/ip_set_bitmap_ipmac.c
+++ b/kernel/ip_set_bitmap_ipmac.c
@@ -380,10 +380,14 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *head, int len,
bitmap_ipmac_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP, &data.id);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &data.id);
if (ret)
return ret;
@@ -538,6 +542,7 @@ static const struct nla_policy
bitmap_ipmac_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED },
[IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
+ [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
};
@@ -572,12 +577,16 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *head, int len,
bitmap_ipmac_create_policy))
return -IPSET_ERR_PROTOCOL;
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP, &first_ip);
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
if (ret)
return ret;
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &last_ip);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
if (ret)
return ret;
if (first_ip > last_ip) {
diff --git a/kernel/ip_set_bitmap_port.c b/kernel/ip_set_bitmap_port.c
index dfece55..17303c6 100644
--- a/kernel/ip_set_bitmap_port.c
+++ b/kernel/ip_set_bitmap_port.c
@@ -116,14 +116,14 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *head, int len,
bitmap_port_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- if (tb[IPSET_ATTR_PORT])
- port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
- else
- return -IPSET_ERR_PROTOCOL;
-
+ port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
if (port < map->first_port || port > map->last_port)
return -IPSET_ERR_BITMAP_RANGE;
@@ -347,14 +347,15 @@ bitmap_port_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
bitmap_port_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- if (tb[IPSET_ATTR_PORT])
- port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
- else
- return -IPSET_ERR_PROTOCOL;
-
+ port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
if (port < map->first_port || port > map->last_port)
return -IPSET_ERR_BITMAP_RANGE;
@@ -568,21 +569,19 @@ bitmap_port_create(struct ip_set *set, struct nlattr *head, int len,
bitmap_port_create_policy))
return -IPSET_ERR_PROTOCOL;
- if (tb[IPSET_ATTR_PORT])
- first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
- else
+ if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
return -IPSET_ERR_PROTOCOL;
- if (tb[IPSET_ATTR_PORT_TO]) {
- last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
- if (first_port > last_port) {
- u16 tmp = first_port;
+ first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
+ last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
+ if (first_port > last_port) {
+ u16 tmp = first_port;
- first_port = last_port;
- last_port = tmp;
- }
- } else
- return -IPSET_ERR_PROTOCOL;
+ first_port = last_port;
+ last_port = tmp;
+ }
if (tb[IPSET_ATTR_TIMEOUT]) {
struct bitmap_port_timeout *map;
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)
diff --git a/kernel/ip_set_hash_ip.c b/kernel/ip_set_hash_ip.c
index e8ae8a5..21ace91 100644
--- a/kernel/ip_set_hash_ip.c
+++ b/kernel/ip_set_hash_ip.c
@@ -156,10 +156,14 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ip4_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP, &ip);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
if (ret)
return ret;
@@ -179,7 +183,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
}
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
return ret;
if (ip > ip_to)
@@ -346,10 +350,14 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ip6_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP, &ip);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &ip);
if (ret)
return ret;
@@ -398,6 +406,11 @@ hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
hash_ip_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_HASHSIZE]) {
hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
if (hashsize < IPSET_MIMINAL_HASHSIZE)
diff --git a/kernel/ip_set_hash_ipport.c b/kernel/ip_set_hash_ipport.c
index 4bc1f42..dd92563 100644
--- a/kernel/ip_set_hash_ipport.c
+++ b/kernel/ip_set_hash_ipport.c
@@ -181,10 +181,16 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ipport_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
@@ -227,7 +233,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
ip = ntohl(data.ip);
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
return ret;
if (ip > ip_to)
@@ -402,10 +408,16 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ipport_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
@@ -489,6 +501,11 @@ hash_ipport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
hash_ipport_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_HASHSIZE]) {
hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
if (hashsize < IPSET_MIMINAL_HASHSIZE)
diff --git a/kernel/ip_set_hash_ipportip.c b/kernel/ip_set_hash_ipportip.c
index 734529c..04cd079 100644
--- a/kernel/ip_set_hash_ipportip.c
+++ b/kernel/ip_set_hash_ipportip.c
@@ -188,14 +188,20 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ipportip_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP2, &data.ip2);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &data.ip2);
if (ret)
return ret;
@@ -238,7 +244,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
ip = ntohl(data.ip);
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
return ret;
if (ip > ip_to)
@@ -419,14 +425,20 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ipportip_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP2, &data.ip2);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2);
if (ret)
return ret;
@@ -510,6 +522,11 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *head,
hash_ipportip_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_HASHSIZE]) {
hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
if (hashsize < IPSET_MIMINAL_HASHSIZE)
diff --git a/kernel/ip_set_hash_ipportnet.c b/kernel/ip_set_hash_ipportnet.c
index b6bc5c9..2b06d51 100644
--- a/kernel/ip_set_hash_ipportnet.c
+++ b/kernel/ip_set_hash_ipportnet.c
@@ -209,14 +209,20 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ipportnet_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP2, &data.ip2);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &data.ip2);
if (ret)
return ret;
@@ -267,7 +273,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
ip = ntohl(data.ip);
if (tb[IPSET_ATTR_IP_TO]) {
- ret = ip_set_get_hostipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
return ret;
if (ip > ip_to)
@@ -474,14 +480,20 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_ipportnet_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP2, &data.ip2);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2);
if (ret)
return ret;
@@ -573,6 +585,11 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
hash_ipportnet_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_HASHSIZE]) {
hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
if (hashsize < IPSET_MIMINAL_HASHSIZE)
diff --git a/kernel/ip_set_hash_net.c b/kernel/ip_set_hash_net.c
index 61c4b4f..175c621 100644
--- a/kernel/ip_set_hash_net.c
+++ b/kernel/ip_set_hash_net.c
@@ -176,10 +176,14 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_net_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
@@ -352,10 +356,14 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_net_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
@@ -404,6 +412,11 @@ hash_net_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
hash_net_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_HASHSIZE]) {
hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
if (hashsize < IPSET_MIMINAL_HASHSIZE)
diff --git a/kernel/ip_set_hash_netport.c b/kernel/ip_set_hash_netport.c
index ca17f1c..72ca57e 100644
--- a/kernel/ip_set_hash_netport.c
+++ b/kernel/ip_set_hash_netport.c
@@ -201,10 +201,16 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_netport_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
@@ -431,10 +437,16 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *head, int len,
hash_netport_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP, &data.ip);
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
if (ret)
return ret;
@@ -524,6 +536,11 @@ hash_netport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
hash_netport_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_HASHSIZE]) {
hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
if (hashsize < IPSET_MIMINAL_HASHSIZE)
diff --git a/kernel/ip_set_list_set.c b/kernel/ip_set_list_set.c
index 3525e3b..9cae5d7 100644
--- a/kernel/ip_set_list_set.c
+++ b/kernel/ip_set_list_set.c
@@ -222,20 +222,22 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
list_set_adt_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!tb[IPSET_ATTR_NAME] ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_LINENO])
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
- if (tb[IPSET_ATTR_NAME]) {
- id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s);
- if (id == IPSET_INVALID_ID)
- return -IPSET_ERR_NAME;
- /* "Loop detection" */
- if (s->type->features & IPSET_TYPE_NAME) {
- ret = -IPSET_ERR_LOOP;
- goto finish;
- }
- } else
- return -IPSET_ERR_PROTOCOL;
+ id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s);
+ if (id == IPSET_INVALID_ID)
+ return -IPSET_ERR_NAME;
+ /* "Loop detection" */
+ if (s->type->features & IPSET_TYPE_NAME) {
+ ret = -IPSET_ERR_LOOP;
+ goto finish;
+ }
if (tb[IPSET_ATTR_CADT_FLAGS]) {
u32 f = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
@@ -541,6 +543,10 @@ list_set_create(struct ip_set *set, struct nlattr *head, int len,
list_set_create_policy))
return -IPSET_ERR_PROTOCOL;
+ if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+ return -IPSET_ERR_PROTOCOL;
+
if (tb[IPSET_ATTR_SIZE])
size = ip_set_get_h32(tb[IPSET_ATTR_SIZE]);
if (size < IP_SET_LIST_MIN_SIZE)