]> granicus.if.org Git - ipset/commitdiff
Enforce network-order data in the netlink protocol
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 20 Jan 2011 16:54:26 +0000 (17:54 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 20 Jan 2011 16:54:26 +0000 (17:54 +0100)
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)

12 files changed:
kernel/include/linux/netfilter/ipset/ip_set.h
kernel/ip_set_bitmap_ip.c
kernel/ip_set_bitmap_ipmac.c
kernel/ip_set_bitmap_port.c
kernel/ip_set_core.c
kernel/ip_set_hash_ip.c
kernel/ip_set_hash_ipport.c
kernel/ip_set_hash_ipportip.c
kernel/ip_set_hash_ipportnet.c
kernel/ip_set_hash_net.c
kernel/ip_set_hash_netport.c
kernel/ip_set_list_set.c

index 7679b33cba9994f3e6f8bab276f949cc58f45556..61b08f17f8c41e8d711511d61185a5411627f6b8 100644 (file)
@@ -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)
index 7806ecc34e88be1feaf1fe2fa0de85f6f016d8c6..30db991144c1a22b299efbeb1c2585300a0a2220 100644 (file)
@@ -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) {
index 49e7ed1069b246e1c1031737f2f3627d2bb13876..87870a30ac71e00e12bb238cd497dec4836fca5f 100644 (file)
@@ -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) {
index dfece553699d2067f4af2597d369154457376cd3..17303c6c963e0fb5bf233057fca52f0e20723f89 100644 (file)
@@ -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;
index e449740ff30ea35e6e790b135080a3a1ff825f96..ba2f890227ec6a6accc17c923ecbf4fee69b3ad4 100644 (file)
@@ -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)
index e8ae8a5ac3d20c1b508be5f3210df4884faad5b8..21ace91f6e8423455cd1a27ebcfd19861ae80bed 100644 (file)
@@ -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)
index 4bc1f42e110ff772905f5dacca20b769ac8a4caa..dd925630390f3591f8625eac567980c6ff4baef8 100644 (file)
@@ -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)
index 734529cf3e03c26c88910ef0b1912dd02d0d2982..04cd079d4ed0f0231f7f772c5cfddfcfe1c70980 100644 (file)
@@ -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)
index b6bc5c9f84dfa9f915339bb4c0d021a922351a1c..2b06d510dc7b6b6ea913cad3e11ef180f2eacc39 100644 (file)
@@ -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)
index 61c4b4fa1477904184693015af0475256f93f933..175c621164c35ecd582f21d0b422bf0e00bfbb52 100644 (file)
@@ -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)
index ca17f1c9fc958c17829b518eb947b2bb39ff9055..72ca57ee877c8ab9783a9786d52c6f7b4d70af87 100644 (file)
@@ -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)
index 3525e3bd34000a1cfbaf815f1ff25aa453537eb5..9cae5d7b5c1d55ffb062de8b5e2f39d959d52e16 100644 (file)
@@ -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)