[PATCH 15/18] Netfilter: Fix for UDP and TCP NAT on nonlinear skbs
Rusty Russell
rusty at rustcorp.com.au
Wed Jan 5 04:37:00 CET 2005
Name: Fix for UDP and TCP NAT on nonlinear skbs
Status: Tested under nfsim
Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
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.
Index: linux-2.6.10-bk1-Netfilter/net/ipv4/netfilter/ip_nat_proto_udp.c
===================================================================
--- linux-2.6.10-bk1-Netfilter.orig/net/ipv4/netfilter/ip_nat_proto_udp.c 2004-12-29 23:07:37.000000000 +1100
+++ linux-2.6.10-bk1-Netfilter/net/ipv4/netfilter/ip_nat_proto_udp.c 2005-01-04 19:19:58.036153920 +1100
@@ -90,20 +90,20 @@
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 */
Index: linux-2.6.10-bk1-Netfilter/net/ipv4/netfilter/ip_nat_proto_tcp.c
===================================================================
--- linux-2.6.10-bk1-Netfilter.orig/net/ipv4/netfilter/ip_nat_proto_tcp.c 2004-12-29 23:07:37.000000000 +1100
+++ linux-2.6.10-bk1-Netfilter/net/ipv4/netfilter/ip_nat_proto_tcp.c 2005-01-04 19:23:51.765621640 +1100
@@ -91,8 +91,8 @@
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 @@
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;
}
More information about the netfilter-devel
mailing list