netfilter: xtables: fix conntrack match v1 ipt-save output
authorFlorian Westphal <fw@strlen.de>
Mon, 23 Nov 2009 09:43:57 +0000 (10:43 +0100)
committerPatrick McHardy <kaber@trash.net>
Mon, 23 Nov 2009 09:43:57 +0000 (10:43 +0100)
commit3a0429292daa0e1ec848bd26479f5e48b0d54a42
treeef63c29a31efc7942e2d364a11edfab627e6bc33
parentc4832c7bbc3f7a4813347e871d7238651bf437d3
netfilter: xtables: fix conntrack match v1 ipt-save output

commit d6d3f08b0fd998b647a05540cedd11a067b72867
(netfilter: xtables: conntrack match revision 2) does break the
v1 conntrack match iptables-save output in a subtle way.

Problem is as follows:

    up = kmalloc(sizeof(*up), GFP_KERNEL);
[..]
   /*
    * The strategy here is to minimize the overhead of v1 matching,
    * by prebuilding a v2 struct and putting the pointer into the
    * v1 dataspace.
    */
    memcpy(up, info, offsetof(typeof(*info), state_mask));
[..]
    *(void **)info  = up;

As the v2 struct pointer is saved in the match data space,
it clobbers the first structure member (->origsrc_addr).

Because the _v1 match function grabs this pointer and does not actually
look at the v1 origsrc, run time functionality does not break.
But iptables -nvL (or iptables-save) cannot know that v1 origsrc_addr
has been overloaded in this way:

$ iptables -p tcp -A OUTPUT -m conntrack --ctorigsrc 10.0.0.1 -j ACCEPT
$ iptables-save
-A OUTPUT -p tcp -m conntrack --ctorigsrc 128.173.134.206 -j ACCEPT

(128.173... is the address to the v2 match structure).

To fix this, we take advantage of the fact that the v1 and v2 structures
are identical with exception of the last two structure members (u8 in v1,
u16 in v2).

We extract them as early as possible and prevent the v2 matching function
from looking at those two members directly.

Previously reported by Michel Messerschmidt via Ben Hutchings, also
see Debian Bug tracker #556587.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
net/netfilter/xt_conntrack.c