aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2005-01-04 04:14:47 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 04:14:47 -0800
commit734c53f3a0416017b8fa8e3f80ecda78195060cf (patch)
treea312225f65f83574bbc84719efd04ec80de81ec9 /net
parentcec8e41165b7016d80e031920159fbc5eb3f879f (diff)
downloadhistory-734c53f3a0416017b8fa8e3f80ecda78195060cf.tar.gz
[PATCH] Fix for UDP and TCP NAT on nonlinear skbs
UDP and TCP refer to potentially stale pointers after calling skb_ip_make_writable(), and UDP calls it with the wrong len argument. All found by nfsim. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_tcp.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_udp.c10
2 files changed, 9 insertions, 9 deletions
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index 281e19a520ebd8..fb21a0875fa447 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -91,8 +91,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct tcphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
- u_int32_t oldip;
- u_int16_t *portptr, oldport;
+ u32 oldip, oldsrc = iph->saddr, olddst = iph->daddr;
+ u16 *portptr, oldport;
int hdrsize = 8; /* TCP connection tracking guarantees this much */
/* this could be a inner header returned in icmp packet; in such
@@ -108,11 +108,11 @@ tcp_manip_pkt(struct sk_buff **pskb,
if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */
- oldip = iph->saddr;
+ oldip = oldsrc;
portptr = &hdr->source;
} else {
/* Get rid of dst ip and dst pt */
- oldip = iph->daddr;
+ oldip = olddst;
portptr = &hdr->dest;
}
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 12c19bfe5ad34e..3c492530863c1e 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -90,20 +90,20 @@ udp_manip_pkt(struct sk_buff **pskb,
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct udphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
- u_int32_t oldip;
- u_int16_t *portptr;
+ u32 oldip, oldsrc = iph->saddr, olddst = iph->daddr;
+ u16 *portptr;
- if (!skb_ip_make_writable(pskb, hdroff + sizeof(hdr)))
+ if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
return 0;
hdr = (void *)(*pskb)->data + hdroff;
if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */
- oldip = iph->saddr;
+ oldip = oldsrc;
portptr = &hdr->source;
} else {
/* Get rid of dst ip and dst pt */
- oldip = iph->daddr;
+ oldip = olddst;
portptr = &hdr->dest;
}
if (hdr->check) /* 0 is a special case meaning no checksum */