tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Panic in nat_inlookup (trough ip6_input)



In article <20180430091453.GE62237%trav.math.uni-bonn.de@localhost>,
Edgar Fuß  <ef%math.uni-bonn.de@localhost> wrote:
>> Yes, there are fragment bugs fixed in later versions that have not been
>> pulled up to -6 :-(
>Any hint what these fixes are so I could pull-up them privately?
>

I would probably do these first :-)

christos

Index: fil.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/ipf/netinet/fil.c,v
retrieving revision 1.15.2.3
retrieving revision 1.22
diff -u -r1.15.2.3 -r1.22
--- fil.c	29 Jun 2017 12:24:10 -0000	1.15.2.3
+++ fil.c	4 Feb 2018 08:19:42 -0000	1.22
@@ -2916,9 +2950,7 @@
 		LBUMPD(ipf_stats[out], fr_short);
 	}
 
-#if 0
 	READ_ENTER(&softc->ipf_mutex);
-#endif
 
 	if (!out) {
 		switch (fin->fin_v)
@@ -3050,10 +3082,9 @@
 		fr->fr_ref++;
 		MUTEX_EXIT(&fr->fr_lock);
 	}
-#if 0
+
 	RWLOCK_EXIT(&softc->ipf_mutex);
 #endif
-#endif
 
 	if ((pass & FR_RETMASK) != 0) {
 		/*
@@ -3149,10 +3180,8 @@
 #endif
 	}
 #if !defined(FASTROUTE_RECURSION)
-#if 0
 	RWLOCK_EXIT(&softc->ipf_mutex);
 #endif
-#endif
 
 finished:
 	if (!FR_ISPASS(pass)) {
@@ -4307,6 +4336,38 @@
 	return 0;
 }
 
+/* ------------------------------------------------------------------------ */
+/* Function:    ipf_rule_compare                                            */
+/* Parameters:  fr1(I) - first rule structure to compare                    */
+/*              fr2(I) - second rule structure to compare                   */
+/* Returns:     int    - 0 == rules are the same, else mismatch             */
+/*                                                                          */
+/* Compare two rules and return 0 if they match or a number indicating      */
+/* which of the individual checks failed.                                   */
+/* ------------------------------------------------------------------------ */
+static int
+ipf_rule_compare(frentry_t *fr1, frentry_t *fr2)
+{
+	if (fr1->fr_cksum != fr2->fr_cksum)
+		return 1;
+	if (fr1->fr_size != fr2->fr_size)
+		return 2;
+	if (fr1->fr_dsize != fr2->fr_dsize)
+		return 3;
+	if (memcmp(&fr1->fr_func, &fr2->fr_func,
+		 fr1->fr_size - offsetof(struct frentry, fr_func)) != 0)
+		return 4;
+	if (fr1->fr_data && !fr2->fr_data)
+		return 5;
+	if (!fr1->fr_data && fr2->fr_data)
+		return 6;
+	if (fr1->fr_data) {
+		if (memcmp(fr1->fr_caddr, fr2->fr_caddr, fr1->fr_dsize))
+			return 7;
+	}
+	return 0;
+}
+
 
 /* ------------------------------------------------------------------------ */
 /* Function:    frrequest                                                   */
@@ -4801,16 +4862,7 @@
 
 	for (; (f = *ftail) != NULL; ftail = &f->fr_next) {
 		DT2(rule_cmp, frentry_t *, fp, frentry_t *, f);
-		if ((fp->fr_cksum != f->fr_cksum) ||
-		    (fp->fr_size != f->fr_size) ||
-		    (f->fr_dsize != fp->fr_dsize))
-			continue;
-		if (bcmp((char *)&f->fr_func, (char *)&fp->fr_func,
-			 fp->fr_size - offsetof(struct frentry, fr_func)) != 0)
-			continue;
-		if ((!ptr && !f->fr_data) ||
-		    (ptr && f->fr_data &&
-		     !bcmp((char *)ptr, (char *)f->fr_data, f->fr_dsize)))
+		if (ipf_rule_compare(fp, f) == 0)
 			break;
 	}
 
@@ -4841,13 +4893,14 @@
 			error = ipf_outobj(softc, data, fp, IPFOBJ_FRENTRY);
 
 			if (error == 0) {
-				if ((f->fr_dsize != 0) && (uptr != NULL))
+				if ((f->fr_dsize != 0) && (uptr != NULL)) {
 					error = COPYOUT(f->fr_data, uptr,
 							f->fr_dsize);
 					if (error != 0) {
 						IPFERROR(28);
 						error = EFAULT;
 					}
+				}
 				if (error == 0) {
 					f->fr_hits = 0;
 					f->fr_bytes = 0;
Index: ip_fil_compat.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/ipf/netinet/ip_fil_compat.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ip_fil_compat.c	20 Mar 2014 20:43:12 -0000	1.4
+++ ip_fil_compat.c	8 Feb 2018 08:04:45 -0000	1.5
@@ -2274,7 +2274,6 @@
 
 			if ((offset & 7) != 0)
 				offset += 8 - (offset & 7);
-				offset += 8 - (offset & 7);
 			error = ipf_in_compat(softc, &obj,
 					      fr->fr_names + offset, 0);
 			if (error == 0) {
Index: ip_frag.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/ipf/netinet/ip_frag.c,v
retrieving revision 1.3.14.1
retrieving revision 1.5
diff -u -r1.3.14.1 -r1.5
--- ip_frag.c	29 Jun 2017 12:24:10 -0000	1.3.14.1
+++ ip_frag.c	23 Apr 2017 19:09:29 -0000	1.5
@@ -726,6 +726,8 @@
 			} else if (off == 0)
 				f->ipfr_seen0 = 1;
 
+#if 0
+			/* We can't do this, since we only have a read lock! */
 			if (f != table[idx]) {
 				ipfr_t **fp;
 
@@ -745,9 +747,10 @@
 				f->ipfr_hprev = table + idx;
 				table[idx] = f;
 			}
+#endif
 
 			/*
-			 * If we've follwed the fragments, and this is the
+			 * If we've followed the fragments, and this is the
 			 * last (in order), shrink expiration time.
 			 */
 			if (off == f->ipfr_off) {
Index: radix_ipf.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/ipf/netinet/radix_ipf.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- radix_ipf.c	20 Mar 2014 20:43:12 -0000	1.5
+++ radix_ipf.c	15 Dec 2015 12:30:34 -0000	1.6
@@ -1,4 +1,4 @@
-/*	$NetBSD: radix_ipf.c,v 1.5 2014/03/20 20:43:12 christos Exp $	*/
+/*	$NetBSD: radix_ipf.c,v 1.6 2015/12/15 12:30:34 christos Exp $	*/
 
 /*
  * Copyright (C) 2012 by Darren Reed.
@@ -1480,6 +1480,8 @@
 		add_addr(rnh, i, order[i]);
 		checktree(rnh);
 	}
+
+	free(order);
 }
 
 
@@ -1497,5 +1499,7 @@
 		delete_addr(rnh, i);
 		checktree(rnh);
 	}
+
+	free(order);
 }
 #endif /* RDX_DEBUG */



Home | Main Index | Thread Index | Old Index