patch-2.1.86 linux/net/ipv4/ip_fragment.c

Next file: linux/net/ipv4/ip_fw.c
Previous file: linux/net/ipv4/ip_forward.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.85/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c
@@ -15,6 +15,7 @@
  *		David S. Miller :	Begin massive cleanup...
  *		Andi Kleen	:	Add sysctls.
  *		xxxx		:	Overlapfrag bug.
+ *		Ultima          :       ip_expire() kernel panic.
  */
 
 #include <linux/types.h>
@@ -78,10 +79,10 @@
 char *in_ntoa(__u32 in);
 
 /* Memory Tracking Functions. */
-extern __inline__ void frag_kfree_skb(struct sk_buff *skb, int type)
+extern __inline__ void frag_kfree_skb(struct sk_buff *skb)
 {
 	atomic_sub(skb->truesize, &ip_frag_mem);
-	kfree_skb(skb,type);
+	kfree_skb(skb);
 }
 
 extern __inline__ void frag_kfree_s(void *ptr, int len)
@@ -175,7 +176,7 @@
 	while (fp) {
 		struct ipfrag *xp = fp->next;
 
-		frag_kfree_skb(fp->skb,FREE_READ);
+		frag_kfree_skb(fp->skb);
 		frag_kfree_s(fp, sizeof(struct ipfrag));
 		fp = xp;
 	}
@@ -192,6 +193,15 @@
 {
 	struct ipq *qp = (struct ipq *) arg;
 
+  	if(!qp->fragments)
+        {	
+#ifdef IP_EXPIRE_DEBUG
+	  	printk("warning: possible ip-expire attack\n");
+#endif
+		ip_free(qp);
+		return;
+  	}
+  
 	/* Send an ICMP "Fragment Reassembly Timeout" message. */
 	ip_statistics.IpReasmTimeout++;
 	ip_statistics.IpReasmFails++;   
@@ -344,7 +354,7 @@
 			NETDEBUG(printk(KERN_ERR "Invalid fragment list: "
 					"Fragment over size.\n"));
 			ip_free(qp);
-			kfree_skb(skb,FREE_WRITE);
+			kfree_skb(skb);
 			ip_statistics.IpReasmFails++;
 			return NULL;
 		}
@@ -427,7 +437,7 @@
 	} else {
 		/* If we failed to create it, then discard the frame. */
 		if ((qp = ip_create(skb, iph)) == NULL) {
-			kfree_skb(skb, FREE_READ);
+			kfree_skb(skb);
 			ip_statistics.IpReasmFails++;
 			return NULL;
 		}
@@ -437,7 +447,7 @@
 	if(ntohs(iph->tot_len)+(int)offset>65535) {
 		if (net_ratelimit())
 			printk(KERN_INFO "Oversized packet received from %d.%d.%d.%d\n", NIPQUAD(iph->saddr));
-		frag_kfree_skb(skb, FREE_READ);
+		frag_kfree_skb(skb);
 		ip_statistics.IpReasmFails++;
 		return NULL;
 	}	
@@ -501,7 +511,7 @@
 			/* We have killed the original next frame. */
 			next = tfp;
 
-			frag_kfree_skb(tmp->skb,FREE_READ);
+			frag_kfree_skb(tmp->skb);
 			frag_kfree_s(tmp, sizeof(struct ipfrag));
 		}
 	}
@@ -512,7 +522,7 @@
 
 	/* No memory to save the fragment - so throw the lot. */
 	if (!tfp) {
-		frag_kfree_skb(skb, FREE_READ);
+		frag_kfree_skb(skb);
 		return NULL;
 	}
 	tfp->prev = prev;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov