[NETFILTER] ctnetlink: More thorough size checking of attributes
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 14 Nov 2005 23:22:11 +0000 (15:22 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Nov 2005 23:22:11 +0000 (15:22 -0800)
Add missing size checks. Thanks Patrick McHardy for the hint.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/netfilter/ip_conntrack_netlink.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c

index 853d0ac5534fb53bf3bd2b015c90edfcb6e7655c..f5e5e3158670f783ed46bc64688b60ce6aeb89e8 100644 (file)
@@ -614,6 +614,11 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
        return 0;
 }
 
+static const size_t cta_min_nat[CTA_NAT_MAX] = {
+       [CTA_NAT_MINIP-1]       = sizeof(u_int32_t),
+       [CTA_NAT_MAXIP-1]       = sizeof(u_int32_t),
+};
+
 static inline int
 ctnetlink_parse_nat(struct nfattr *cda[],
                    const struct ip_conntrack *ct, struct ip_nat_range *range)
@@ -627,6 +632,9 @@ ctnetlink_parse_nat(struct nfattr *cda[],
        
        nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
 
+       if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
+               return -EINVAL;
+
        if (tb[CTA_NAT_MINIP-1])
                range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
 
@@ -667,6 +675,14 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
        return 0;
 }
 
+static const size_t cta_min[CTA_MAX] = {
+       [CTA_STATUS-1]          = sizeof(u_int32_t),
+       [CTA_TIMEOUT-1]         = sizeof(u_int32_t),
+       [CTA_MARK-1]            = sizeof(u_int32_t),
+       [CTA_USE-1]             = sizeof(u_int32_t),
+       [CTA_ID-1]              = sizeof(u_int32_t)
+};
+
 static int
 ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 
                        struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
@@ -678,6 +694,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        DEBUGP("entered %s\n", __FUNCTION__);
 
+       if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+               return -EINVAL;
+
        if (cda[CTA_TUPLE_ORIG-1])
                err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
        else if (cda[CTA_TUPLE_REPLY-1])
@@ -760,6 +779,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return 0;
        }
 
+       if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+               return -EINVAL;
+
        if (cda[CTA_TUPLE_ORIG-1])
                err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
        else if (cda[CTA_TUPLE_REPLY-1])
@@ -1047,6 +1069,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        DEBUGP("entered %s\n", __FUNCTION__);
 
+       if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+               return -EINVAL;
+
        if (cda[CTA_TUPLE_ORIG-1]) {
                err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG);
                if (err < 0)
@@ -1252,6 +1277,11 @@ out:
        return skb->len;
 }
 
+static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
+       [CTA_EXPECT_TIMEOUT-1]          = sizeof(u_int32_t),
+       [CTA_EXPECT_ID-1]               = sizeof(u_int32_t)
+};
+
 static int
 ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 
                     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
@@ -1263,6 +1293,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
 
        DEBUGP("entered %s\n", __FUNCTION__);
 
+       if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+               return -EINVAL;
+
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
                struct nfgenmsg *msg = NLMSG_DATA(nlh);
                u32 rlen;
@@ -1333,6 +1366,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
        struct ip_conntrack_helper *h;
        int err;
 
+       if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+               return -EINVAL;
+
        if (cda[CTA_EXPECT_TUPLE-1]) {
                /* delete a single expect by tuple */
                err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
@@ -1462,6 +1498,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
 
        DEBUGP("entered %s\n", __FUNCTION__);   
 
+       if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+               return -EINVAL;
+
        if (!cda[CTA_EXPECT_TUPLE-1]
            || !cda[CTA_EXPECT_MASK-1]
            || !cda[CTA_EXPECT_MASTER-1])
index 5b3f5220f2896cc965d809f1678847b1471e79f8..ee3b7d6c4d2efbb5c76012b0ed1e6a7fda26ef92 100644 (file)
@@ -357,6 +357,10 @@ nfattr_failure:
        return -1;
 }
 
+static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
+       [CTA_PROTOINFO_TCP_STATE-1]     = sizeof(u_int8_t),
+};
+
 static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
 {
        struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
@@ -369,6 +373,9 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
 
         nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
 
+       if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
+               return -EINVAL;
+
        if (!tb[CTA_PROTOINFO_TCP_STATE-1])
                return -EINVAL;