svn commit: r298675 - in head/sys: netinet netinet6

Conrad E. Meyer cem at FreeBSD.org
Tue Apr 26 23:13:50 UTC 2016


Author: cem
Date: Tue Apr 26 23:13:48 2016
New Revision: 298675
URL: https://svnweb.freebsd.org/changeset/base/298675

Log:
  in_lltable_alloc and in6 copy: Don't leak LLE in error path
  
  Fix a memory leak in error conditions introduced in r292978.
  
  Reported by:	Coverity
  CIDs:		1347009, 1347010
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/netinet/in.c
  head/sys/netinet6/in6.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Tue Apr 26 23:09:47 2016	(r298674)
+++ head/sys/netinet/in.c	Tue Apr 26 23:13:48 2016	(r298675)
@@ -1004,6 +1004,17 @@ struct in_llentry {
 
 /*
  * Do actual deallocation of @lle.
+ */
+static void
+in_lltable_destroy_lle_unlocked(struct llentry *lle)
+{
+
+	LLE_LOCK_DESTROY(lle);
+	LLE_REQ_DESTROY(lle);
+	free(lle, M_LLTABLE);
+}
+
+/*
  * Called by LLE_FREE_LOCKED when number of references
  * drops to zero.
  */
@@ -1012,9 +1023,7 @@ in_lltable_destroy_lle(struct llentry *l
 {
 
 	LLE_WUNLOCK(lle);
-	LLE_LOCK_DESTROY(lle);
-	LLE_REQ_DESTROY(lle);
-	free(lle, M_LLTABLE);
+	in_lltable_destroy_lle_unlocked(lle);
 }
 
 static struct llentry *
@@ -1277,8 +1286,10 @@ in_lltable_alloc(struct lltable *llt, u_
 	if ((flags & LLE_IFADDR) == LLE_IFADDR) {
 		linkhdrsize = LLE_MAX_LINKHDR;
 		if (lltable_calc_llheader(ifp, AF_INET, IF_LLADDR(ifp),
-		    linkhdr, &linkhdrsize, &lladdr_off) != 0)
+		    linkhdr, &linkhdrsize, &lladdr_off) != 0) {
+			in_lltable_destroy_lle_unlocked(lle);
 			return (NULL);
+		}
 		lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
 		    lladdr_off);
 		lle->la_flags |= LLE_STATIC;

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Tue Apr 26 23:09:47 2016	(r298674)
+++ head/sys/netinet6/in6.c	Tue Apr 26 23:13:48 2016	(r298675)
@@ -2056,6 +2056,17 @@ struct in6_llentry {
 
 /*
  * Do actual deallocation of @lle.
+ */
+static void
+in6_lltable_destroy_lle_unlocked(struct llentry *lle)
+{
+
+	LLE_LOCK_DESTROY(lle);
+	LLE_REQ_DESTROY(lle);
+	free(lle, M_LLTABLE);
+}
+
+/*
  * Called by LLE_FREE_LOCKED when number of references
  * drops to zero.
  */
@@ -2064,9 +2075,7 @@ in6_lltable_destroy_lle(struct llentry *
 {
 
 	LLE_WUNLOCK(lle);
-	LLE_LOCK_DESTROY(lle);
-	LLE_REQ_DESTROY(lle);
-	free(lle, M_LLTABLE);
+	in6_lltable_destroy_lle_unlocked(lle);
 }
 
 static struct llentry *
@@ -2270,8 +2279,10 @@ in6_lltable_alloc(struct lltable *llt, u
 	if ((flags & LLE_IFADDR) == LLE_IFADDR) {
 		linkhdrsize = LLE_MAX_LINKHDR;
 		if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp),
-		    linkhdr, &linkhdrsize, &lladdr_off) != 0)
+		    linkhdr, &linkhdrsize, &lladdr_off) != 0) {
+			in6_lltable_destroy_lle_unlocked(lle);
 			return (NULL);
+		}
 		lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
 		    lladdr_off);
 		lle->la_flags |= LLE_STATIC;


More information about the svn-src-head mailing list