diff options
author | Jorge Boncompte <jorge@dti2.net> | 2007-05-03 06:34:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-03 06:34:42 -0400 |
commit | c2a1910b06fed96db77bb358c18c52a1fcf2b7fe (patch) | |
tree | a3e8fc944ea2a0bed4a6e02b6b0fb42e21444354 | |
parent | 327850070b019a96853c533c152688546201c286 (diff) |
[NETFILTER]: nf_nat_proto_gre: do not modify/corrupt GREv0 packets through NAT
While porting some changes of the 2.6.21-rc7 pptp/proto_gre conntrack
and nat modules to a 2.4.32 kernel I noticed that the gre_key function
returns a wrong pointer to the GRE key of a version 0 packet thus
corrupting the packet payload.
The intended behaviour for GREv0 packets is to act like
nf_conntrack_proto_generic/nf_nat_proto_unknown so I have ripped the
offending functions (not used anymore) and modified the
nf_nat_proto_gre modules to not touch version 0 (non PPTP) packets.
Signed-off-by: Jorge Boncompte <jorge@dti2.net>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter/nf_conntrack_proto_gre.h | 18 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_proto_gre.c | 20 |
2 files changed, 8 insertions, 30 deletions
diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h index 4e6bbce04ff8..535e4219d2bb 100644 --- a/include/linux/netfilter/nf_conntrack_proto_gre.h +++ b/include/linux/netfilter/nf_conntrack_proto_gre.h | |||
@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, | |||
87 | /* delete keymap entries */ | 87 | /* delete keymap entries */ |
88 | void nf_ct_gre_keymap_destroy(struct nf_conn *ct); | 88 | void nf_ct_gre_keymap_destroy(struct nf_conn *ct); |
89 | 89 | ||
90 | /* get pointer to gre key, if present */ | ||
91 | static inline __be32 *gre_key(struct gre_hdr *greh) | ||
92 | { | ||
93 | if (!greh->key) | ||
94 | return NULL; | ||
95 | if (greh->csum || greh->routing) | ||
96 | return (__be32 *)(greh+sizeof(*greh)+4); | ||
97 | return (__be32 *)(greh+sizeof(*greh)); | ||
98 | } | ||
99 | |||
100 | /* get pointer ot gre csum, if present */ | ||
101 | static inline __sum16 *gre_csum(struct gre_hdr *greh) | ||
102 | { | ||
103 | if (!greh->csum) | ||
104 | return NULL; | ||
105 | return (__sum16 *)(greh+sizeof(*greh)); | ||
106 | } | ||
107 | |||
108 | extern void nf_ct_gre_keymap_flush(void); | 90 | extern void nf_ct_gre_keymap_flush(void); |
109 | extern void nf_nat_need_gre(void); | 91 | extern void nf_nat_need_gre(void); |
110 | 92 | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c index e5a34c17d927..c3908bc5a709 100644 --- a/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/net/ipv4/netfilter/nf_nat_proto_gre.c | |||
@@ -72,6 +72,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
72 | __be16 *keyptr; | 72 | __be16 *keyptr; |
73 | unsigned int min, i, range_size; | 73 | unsigned int min, i, range_size; |
74 | 74 | ||
75 | /* If there is no master conntrack we are not PPTP, | ||
76 | do not change tuples */ | ||
77 | if (!conntrack->master) | ||
78 | return 0; | ||
79 | |||
75 | if (maniptype == IP_NAT_MANIP_SRC) | 80 | if (maniptype == IP_NAT_MANIP_SRC) |
76 | keyptr = &tuple->src.u.gre.key; | 81 | keyptr = &tuple->src.u.gre.key; |
77 | else | 82 | else |
@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff, | |||
122 | if (maniptype != IP_NAT_MANIP_DST) | 127 | if (maniptype != IP_NAT_MANIP_DST) |
123 | return 1; | 128 | return 1; |
124 | switch (greh->version) { | 129 | switch (greh->version) { |
125 | case 0: | 130 | case GRE_VERSION_1701: |
126 | if (!greh->key) { | 131 | /* We do not currently NAT any GREv0 packets. |
127 | DEBUGP("can't nat GRE w/o key\n"); | 132 | * Try to behave like "nf_nat_proto_unknown" */ |
128 | break; | ||
129 | } | ||
130 | if (greh->csum) { | ||
131 | /* FIXME: Never tested this code... */ | ||
132 | nf_proto_csum_replace4(gre_csum(greh), *pskb, | ||
133 | *(gre_key(greh)), | ||
134 | tuple->dst.u.gre.key, 0); | ||
135 | } | ||
136 | *(gre_key(greh)) = tuple->dst.u.gre.key; | ||
137 | break; | 133 | break; |
138 | case GRE_VERSION_PPTP: | 134 | case GRE_VERSION_PPTP: |
139 | DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); | 135 | DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); |