[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