Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 May 2018 16:19:00 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r333986 - head/sys/netpfil/ipfw
Message-ID:  <201805211619.w4LGJ0D7059884@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Mon May 21 16:19:00 2018
New Revision: 333986
URL: https://svnweb.freebsd.org/changeset/base/333986

Log:
  Remove check for matching the rulenum, ruleid and rule pointer from
  dyn_lookup_ipv[46]_state_locked(). These checks are remnants of not
  ready to be committed code, and they are there by accident.
  Due to the race these checks can lead to creating of duplicate states
  when concurrent threads in the same time will try to add state for two
  packets of the same flow, but in reverse directions and matched by
  different parent rules.
  
  Reported by:	lev
  MFC after:	3 days

Modified:
  head/sys/netpfil/ipfw/ip_fw_dynamic.c

Modified: head/sys/netpfil/ipfw/ip_fw_dynamic.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_dynamic.c	Mon May 21 16:14:53 2018	(r333985)
+++ head/sys/netpfil/ipfw/ip_fw_dynamic.c	Mon May 21 16:19:00 2018	(r333986)
@@ -490,8 +490,7 @@ static struct dyn_ipv6_state *dyn_lookup_ipv6_state(
     const struct ipfw_flow_id *, uint32_t, const void *,
     struct ipfw_dyn_info *, int);
 static int dyn_lookup_ipv6_state_locked(const struct ipfw_flow_id *,
-    uint32_t, const void *, int, const void *, uint32_t, uint16_t, uint32_t,
-    uint16_t);
+    uint32_t, const void *, int, uint32_t, uint16_t);
 static struct dyn_ipv6_state *dyn_alloc_ipv6_state(
     const struct ipfw_flow_id *, uint32_t, uint16_t, uint8_t);
 static int dyn_add_ipv6_state(void *, uint32_t, uint16_t, uint8_t,
@@ -547,7 +546,7 @@ static void dyn_update_proto_state(struct dyn_data *,
 struct dyn_ipv4_state *dyn_lookup_ipv4_state(const struct ipfw_flow_id *,
     const void *, struct ipfw_dyn_info *, int);
 static int dyn_lookup_ipv4_state_locked(const struct ipfw_flow_id *,
-    const void *, int, const void *, uint32_t, uint16_t, uint32_t, uint16_t);
+    const void *, int, uint32_t, uint16_t);
 static struct dyn_ipv4_state *dyn_alloc_ipv4_state(
     const struct ipfw_flow_id *, uint16_t, uint8_t);
 static int dyn_add_ipv4_state(void *, uint32_t, uint16_t, uint8_t,
@@ -1066,8 +1065,7 @@ restart:
  */
 static int
 dyn_lookup_ipv4_state_locked(const struct ipfw_flow_id *pkt,
-    const void *ulp, int pktlen, const void *parent, uint32_t ruleid,
-    uint16_t rulenum, uint32_t bucket, uint16_t kidx)
+    const void *ulp, int pktlen, uint32_t bucket, uint16_t kidx)
 {
 	struct dyn_ipv4_state *s;
 	int dir;
@@ -1078,15 +1076,6 @@ dyn_lookup_ipv4_state_locked(const struct ipfw_flow_id
 		if (s->proto != pkt->proto ||
 		    s->kidx != kidx)
 			continue;
-		/*
-		 * XXXAE: Install synchronized state only when there are
-		 *	  no matching states.
-		 */
-		if (pktlen != 0 && (
-		    s->data->parent != parent ||
-		    s->data->ruleid != ruleid ||
-		    s->data->rulenum != rulenum))
-			continue;
 		if (s->sport == pkt->src_port &&
 		    s->dport == pkt->dst_port &&
 		    s->src == pkt->src_ip && s->dst == pkt->dst_ip) {
@@ -1228,8 +1217,7 @@ restart:
  */
 static int
 dyn_lookup_ipv6_state_locked(const struct ipfw_flow_id *pkt, uint32_t zoneid,
-    const void *ulp, int pktlen, const void *parent, uint32_t ruleid,
-    uint16_t rulenum, uint32_t bucket, uint16_t kidx)
+    const void *ulp, int pktlen, uint32_t bucket, uint16_t kidx)
 {
 	struct dyn_ipv6_state *s;
 	int dir;
@@ -1240,15 +1228,6 @@ dyn_lookup_ipv6_state_locked(const struct ipfw_flow_id
 		if (s->proto != pkt->proto || s->kidx != kidx ||
 		    s->zoneid != zoneid)
 			continue;
-		/*
-		 * XXXAE: Install synchronized state only when there are
-		 *	  no matching states.
-		 */
-		if (pktlen != 0 && (
-		    s->data->parent != parent ||
-		    s->data->ruleid != ruleid ||
-		    s->data->rulenum != rulenum))
-			continue;
 		if (s->sport == pkt->src_port && s->dport == pkt->dst_port &&
 		    IN6_ARE_ADDR_EQUAL(&s->src, &pkt->src_ip6) &&
 		    IN6_ARE_ADDR_EQUAL(&s->dst, &pkt->dst_ip6)) {
@@ -1595,8 +1574,8 @@ dyn_add_ipv4_state(void *parent, uint32_t ruleid, uint
 		 * Bucket version has been changed since last lookup,
 		 * do lookup again to be sure that state does not exist.
 		 */
-		if (dyn_lookup_ipv4_state_locked(pkt, ulp, pktlen, parent,
-		    ruleid, rulenum, bucket, kidx) != 0) {
+		if (dyn_lookup_ipv4_state_locked(pkt, ulp, pktlen,
+		    bucket, kidx) != 0) {
 			DYN_BUCKET_UNLOCK(bucket);
 			return (EEXIST);
 		}
@@ -1727,7 +1706,7 @@ dyn_add_ipv6_state(void *parent, uint32_t ruleid, uint
 		 * do lookup again to be sure that state does not exist.
 		 */
 		if (dyn_lookup_ipv6_state_locked(pkt, zoneid, ulp, pktlen,
-		    parent, ruleid, rulenum, bucket, kidx) != 0) {
+		    bucket, kidx) != 0) {
 			DYN_BUCKET_UNLOCK(bucket);
 			return (EEXIST);
 		}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805211619.w4LGJ0D7059884>