Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Oct 2019 19:47:33 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354037 - head/sys/netinet6
Message-ID:  <201910241947.x9OJlX8M025665@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Thu Oct 24 19:47:32 2019
New Revision: 354037
URL: https://svnweb.freebsd.org/changeset/base/354037

Log:
  frag6.c: do not leak packet queue entry in error case
  
  When we are checking for the maximum reassembled packet size of the
  fragmentable part and run into the error case (packet too big),
  we are leaking the packet queue enntry if this was a first fragment
  to arrive.
  Properly cleanup, removing the queue entry from the bucket, decrementing
  counters, and freeing the memory.
  
  MFC after:	3 weeks
  Sponsored by:	Netflix

Modified:
  head/sys/netinet6/frag6.c

Modified: head/sys/netinet6/frag6.c
==============================================================================
--- head/sys/netinet6/frag6.c	Thu Oct 24 19:47:18 2019	(r354036)
+++ head/sys/netinet6/frag6.c	Thu Oct 24 19:47:32 2019	(r354037)
@@ -572,17 +572,35 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 	if (q6->ip6q_unfrglen >= 0) {
 		/* The 1st fragment has already arrived. */
 		if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
+			if (only_frag) {
+				TAILQ_REMOVE(head, q6, ip6q_tq);
+				V_ip6qb[bucket].count--;
+				atomic_subtract_int(&V_frag6_nfragpackets, 1);
+#ifdef MAC
+				mac_ip6q_destroy(q6);
+#endif
+				free(q6, M_FRAG6);
+			}
+			IP6QB_UNLOCK(bucket);
 			icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 			    offset - sizeof(struct ip6_frag) +
 			    offsetof(struct ip6_frag, ip6f_offlg));
-			IP6QB_UNLOCK(bucket);
 			return (IPPROTO_DONE);
 		}
 	} else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
+		if (only_frag) {
+			TAILQ_REMOVE(head, q6, ip6q_tq);
+			V_ip6qb[bucket].count--;
+			atomic_subtract_int(&V_frag6_nfragpackets, 1);
+#ifdef MAC
+			mac_ip6q_destroy(q6);
+#endif
+			free(q6, M_FRAG6);
+		}
+		IP6QB_UNLOCK(bucket);
 		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 		    offset - sizeof(struct ip6_frag) +
 		    offsetof(struct ip6_frag, ip6f_offlg));
-		IP6QB_UNLOCK(bucket);
 		return (IPPROTO_DONE);
 	}
 



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