patch-2.4.17 linux/net/ipv4/netfilter/ip_nat_helper.c

Next file: linux/net/ipv4/netfilter/ip_nat_irc.c
Previous file: linux/net/ipv4/netfilter/ip_nat_core.c
Back to the patch index
Back to the overall index

diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.16/net/ipv4/netfilter/ip_nat_helper.c linux/net/ipv4/netfilter/ip_nat_helper.c
@@ -143,6 +143,23 @@
 		}
 	}
 
+	/* Alexey says: if a hook changes _data_ ... it can break
+	   original packet sitting in tcp queue and this is fatal */
+	if (skb_cloned(*skb)) {
+		struct sk_buff *nskb = skb_copy(*skb, GFP_ATOMIC);
+		if (!nskb) {
+			if (net_ratelimit())
+				printk("Out of memory cloning TCP packet\n");
+			return 0;
+		}
+		/* Rest of kernel will get very unhappy if we pass it
+		   a suddenly-orphaned skbuff */
+		if ((*skb)->sk)
+			skb_set_owner_w(nskb, (*skb)->sk);
+		kfree_skb(*skb);
+		*skb = nskb;
+	}
+
 	/* skb may be copied !! */
 	iph = (*skb)->nh.iph;
 	tcph = (void *)iph + iph->ihl*4;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)