netfilter: ebtables: abort if next_offset is too small
[safe/jmp/linux-2.6] / net / netfilter / nf_conntrack_proto.c
index 592d733..1a4568b 100644 (file)
@@ -74,27 +74,6 @@ EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find);
 
 /* this is guaranteed to always return a valid protocol helper, since
  * it falls back to generic_protocol */
-struct nf_conntrack_l4proto *
-nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto)
-{
-       struct nf_conntrack_l4proto *p;
-
-       rcu_read_lock();
-       p = __nf_ct_l4proto_find(l3proto, l4proto);
-       if (!try_module_get(p->me))
-               p = &nf_conntrack_l4proto_generic;
-       rcu_read_unlock();
-
-       return p;
-}
-EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get);
-
-void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p)
-{
-       module_put(p->me);
-}
-EXPORT_SYMBOL_GPL(nf_ct_l4proto_put);
-
 struct nf_conntrack_l3proto *
 nf_ct_l3proto_find_get(u_int16_t l3proto)
 {
@@ -188,6 +167,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
        if (proto->l3proto >= AF_MAX)
                return -EBUSY;
 
+       if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
+               return -EINVAL;
+
        mutex_lock(&nf_ct_proto_mutex);
        if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
                ret = -EBUSY;
@@ -198,6 +180,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
        if (ret < 0)
                goto out_unlock;
 
+       if (proto->nlattr_tuple_size)
+               proto->nla_size = 3 * proto->nlattr_tuple_size();
+
        rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
 
 out_unlock:
@@ -284,6 +269,10 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
        if (l4proto->l3proto >= PF_MAX)
                return -EBUSY;
 
+       if ((l4proto->to_nlattr && !l4proto->nlattr_size)
+               || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
+               return -EINVAL;
+
        mutex_lock(&nf_ct_proto_mutex);
        if (!nf_ct_protos[l4proto->l3proto]) {
                /* l3proto may be loaded latter. */
@@ -311,6 +300,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
        if (ret < 0)
                goto out_unlock;
 
+       l4proto->nla_size = 0;
+       if (l4proto->nlattr_size)
+               l4proto->nla_size += l4proto->nlattr_size();
+       if (l4proto->nlattr_tuple_size)
+               l4proto->nla_size += 3 * l4proto->nlattr_tuple_size();
+
        rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
                           l4proto);