[NETFILTER]: ip_tables: account for struct ipt_entry/struct compat_ipt_entry size...
authorPatrick McHardy <kaber@trash.net>
Tue, 18 Dec 2007 05:47:14 +0000 (21:47 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 22:58:30 +0000 (14:58 -0800)
Account for size differences when dumping entries or calculating the
entry positions. This doesn't actually make any difference for IPv4
since the structures have the same size, but its logically correct
and needed for IPv6.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/netfilter/ip_tables.c

index 4586af397ef4382ca99b9feea203f746ac411df0..cc896fe2fd92e03632686b9e7b11e23f41f4ea57 100644 (file)
@@ -1098,7 +1098,7 @@ static int compat_calc_entry(struct ipt_entry *e,
        unsigned int entry_offset;
        int off, i, ret;
 
-       off = 0;
+       off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
        entry_offset = (void *)e - base;
        IPT_MATCH_ITERATE(e, compat_calc_match, &off);
        t = ipt_get_target(e);
@@ -1501,6 +1501,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
                goto out;
 
        *dstptr += sizeof(struct compat_ipt_entry);
+       *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
+
        ret = IPT_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size);
        target_offset = e->target_offset - (origsize - *size);
        if (ret)
@@ -1605,7 +1607,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
        if (ret)
                return ret;
 
-       off = 0;
+       off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
        entry_offset = (void *)e - (void *)base;
        j = 0;
        ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
@@ -1671,6 +1673,8 @@ compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
        memcpy(de, e, sizeof(struct ipt_entry));
 
        *dstptr += sizeof(struct compat_ipt_entry);
+       *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
+
        ret = IPT_MATCH_ITERATE(e, xt_compat_match_from_user, dstptr, size);
        if (ret)
                return ret;