Module Name:    src
Committed By:   rmind
Date:           Tue Feb 12 12:49:23 UTC 2019

Modified Files:
        src/sys/external/bsd/libnv/dist: nv_impl.h nvlist.c nvpair.c

Log Message:
libnv: fix multiple memory leaks.

- nvpair_create_stringv: free the temporary string; this fix affects
  nvlist_add_stringf() and nvlist_add_stringv().

- nvpair_remove_nvlist_array (NV_TYPE_NVLIST_ARRAY case): free the chain
  of nvpairs (as resetting it prevents nvlist_destroy() from freeing it).
  Note: freeing the chain in nvlist_destroy() is not sufficient, because
  it would still leak through nvlist_take_nvlist_array().  This affects
  all nvlist_*_nvlist_array() users.

Found by clang/gcc ASAN.  These fixes have been contributed to the
upstream (FreeBSD) repository.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/external/bsd/libnv/dist/nv_impl.h
cvs rdiff -u -r1.6 -r1.7 src/sys/external/bsd/libnv/dist/nvlist.c
cvs rdiff -u -r1.3 -r1.4 src/sys/external/bsd/libnv/dist/nvpair.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/libnv/dist/nv_impl.h
diff -u src/sys/external/bsd/libnv/dist/nv_impl.h:1.5 src/sys/external/bsd/libnv/dist/nv_impl.h:1.6
--- src/sys/external/bsd/libnv/dist/nv_impl.h:1.5	Sun Sep 23 19:07:10 2018
+++ src/sys/external/bsd/libnv/dist/nv_impl.h	Tue Feb 12 12:49:23 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nv_impl.h,v 1.5 2018/09/23 19:07:10 rmind Exp $	*/
+/*	$NetBSD: nv_impl.h,v 1.6 2019/02/12 12:49:23 rmind Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -125,6 +125,7 @@ bool nvlist_move_nvpair(nvlist_t *nvl, n
 
 void nvlist_set_parent(nvlist_t *nvl, nvpair_t *parent);
 void nvlist_set_array_next(nvlist_t *nvl, nvpair_t *ele);
+nvpair_t *nvlist_get_array_next_nvpair(nvlist_t *nvl);
 
 const nvpair_t *nvlist_get_nvpair(const nvlist_t *nvl, const char *name);
 

Index: src/sys/external/bsd/libnv/dist/nvlist.c
diff -u src/sys/external/bsd/libnv/dist/nvlist.c:1.6 src/sys/external/bsd/libnv/dist/nvlist.c:1.7
--- src/sys/external/bsd/libnv/dist/nvlist.c:1.6	Sat Sep 22 17:13:30 2018
+++ src/sys/external/bsd/libnv/dist/nvlist.c	Tue Feb 12 12:49:23 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvlist.c,v 1.6 2018/09/22 17:13:30 rmind Exp $	*/
+/*	$NetBSD: nvlist.c,v 1.7 2019/02/12 12:49:23 rmind Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -36,7 +36,7 @@
 #ifdef __FreeBSD__
 __FBSDID("$FreeBSD: head/sys/contrib/libnv/nvlist.c 335347 2018-06-18 22:57:32Z oshogbo $");
 #else
-__RCSID("$NetBSD: nvlist.c,v 1.6 2018/09/22 17:13:30 rmind Exp $");
+__RCSID("$NetBSD: nvlist.c,v 1.7 2019/02/12 12:49:23 rmind Exp $");
 #endif
 
 #include <sys/param.h>
@@ -269,6 +269,15 @@ nvlist_set_array_next(nvlist_t *nvl, nvp
 	nvl->nvl_array_next = ele;
 }
 
+nvpair_t *
+nvlist_get_array_next_nvpair(nvlist_t *nvl)
+{
+
+	NVLIST_ASSERT(nvl);
+
+	return (nvl->nvl_array_next);
+}
+
 bool
 nvlist_in_array(const nvlist_t *nvl)
 {

Index: src/sys/external/bsd/libnv/dist/nvpair.c
diff -u src/sys/external/bsd/libnv/dist/nvpair.c:1.3 src/sys/external/bsd/libnv/dist/nvpair.c:1.4
--- src/sys/external/bsd/libnv/dist/nvpair.c:1.3	Sat Sep  8 14:32:25 2018
+++ src/sys/external/bsd/libnv/dist/nvpair.c	Tue Feb 12 12:49:23 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvpair.c,v 1.3 2018/09/08 14:32:25 christos Exp $	*/
+/*	$NetBSD: nvpair.c,v 1.4 2019/02/12 12:49:23 rmind Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -36,7 +36,7 @@
 #ifdef __FreeBSD__
 __FBSDID("$FreeBSD: head/sys/contrib/libnv/nvpair.c 335382 2018-06-19 18:43:02Z lwhsu $");
 #else
-__RCSID("$NetBSD: nvpair.c,v 1.3 2018/09/08 14:32:25 christos Exp $");
+__RCSID("$NetBSD: nvpair.c,v 1.4 2019/02/12 12:49:23 rmind Exp $");
 #endif
 
 #include <sys/param.h>
@@ -251,8 +251,16 @@ nvpair_remove_nvlist_array(nvpair_t *nvp
 	nvlarray = __DECONST(nvlist_t **,
 	    nvpair_get_nvlist_array(nvp, &count));
 	for (i = 0; i < count; i++) {
-		nvlist_set_array_next(nvlarray[i], NULL);
-		nvlist_set_parent(nvlarray[i], NULL);
+		nvlist_t *nvl;
+		nvpair_t *nnvp;
+
+		nvl = nvlarray[i];
+		nnvp = nvlist_get_array_next_nvpair(nvl);
+		if (nnvp != NULL) {
+			nvpair_free_structure(nnvp);
+		}
+		nvlist_set_array_next(nvl, NULL);
+		nvlist_set_parent(nvl, NULL);
 	}
 }
 
@@ -1216,8 +1224,7 @@ nvpair_create_stringv(const char *name, 
 	if (len < 0)
 		return (NULL);
 	nvp = nvpair_create_string(name, str);
-	if (nvp == NULL)
-		nv_free(str);
+	nv_free(str);
 	return (nvp);
 }
 #endif

Reply via email to