Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Sep 2017 10:10:42 +0000 (UTC)
From:      Mariusz Zaborski <oshogbo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r323854 - head/sys/contrib/libnv
Message-ID:  <201709211010.v8LAAgmw068623@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oshogbo
Date: Thu Sep 21 10:10:42 2017
New Revision: 323854
URL: https://svnweb.freebsd.org/changeset/base/323854

Log:
  Because nvp wasn't initialized on every loop iteration once we jumped
  to 'fail' on error it was treated as success, because nvp!=NULL. Fix this
  by not handling success under 'fail' label and by using separate variable
  for parent nvpair.
  
  If we succeeded to allocate nvlist, but failed to allocated nvpair we
  would leak nvls[ii] on return. Destroy it when we cannot allocate nvpair,
  before we goto fail.
  
  Submitted by:	pjd@ and oshogbo@ (minor changes)
  Found by:       scan-build
  MFC after:	1 month
  Sponsored by:	Wheel Systems

Modified:
  head/sys/contrib/libnv/nvpair.c

Modified: head/sys/contrib/libnv/nvpair.c
==============================================================================
--- head/sys/contrib/libnv/nvpair.c	Thu Sep 21 10:06:00 2017	(r323853)
+++ head/sys/contrib/libnv/nvpair.c	Thu Sep 21 10:10:42 2017	(r323854)
@@ -1407,10 +1407,9 @@ nvpair_create_nvlist_array(const char *name, const nvl
 {
 	unsigned int ii;
 	nvlist_t **nvls;
-	nvpair_t *nvp;
+	nvpair_t *parent;
 	int flags;
 
-	nvp = NULL;
 	nvls = NULL;
 
 	if (value == NULL || nitems == 0) {
@@ -1433,33 +1432,40 @@ nvpair_create_nvlist_array(const char *name, const nvl
 			goto fail;
 
 		if (ii > 0) {
+			nvpair_t *nvp;
+
 			nvp = nvpair_allocv(" ", NV_TYPE_NVLIST,
 			    (uint64_t)(uintptr_t)nvls[ii], 0, 0);
-			if (nvp == NULL)
+			if (nvp == NULL) {
+				ERRNO_SAVE();
+				nvlist_destroy(nvls[ii]);
+				ERRNO_RESTORE();
 				goto fail;
+			}
 			nvlist_set_array_next(nvls[ii - 1], nvp);
 		}
 	}
 	flags = nvlist_flags(nvls[nitems - 1]) | NV_FLAG_IN_ARRAY;
 	nvlist_set_flags(nvls[nitems - 1], flags);
 
-	nvp = nvpair_allocv(name, NV_TYPE_NVLIST_ARRAY,
+	parent = nvpair_allocv(name, NV_TYPE_NVLIST_ARRAY,
 	    (uint64_t)(uintptr_t)nvls, 0, nitems);
+	if (parent == NULL)
+		goto fail;
 
-fail:
-	if (nvp == NULL) {
-		ERRNO_SAVE();
-		for (; ii > 0; ii--)
-			nvlist_destroy(nvls[ii - 1]);
+	for (ii = 0; ii < nitems; ii++)
+		nvlist_set_parent(nvls[ii], parent);
 
-		nv_free(nvls);
-		ERRNO_RESTORE();
-	} else {
-		for (ii = 0; ii < nitems; ii++)
-			nvlist_set_parent(nvls[ii], nvp);
-	}
+	return (parent);
 
-	return (nvp);
+fail:
+	ERRNO_SAVE();
+	for (; ii > 0; ii--)
+		nvlist_destroy(nvls[ii - 1]);
+	nv_free(nvls);
+	ERRNO_RESTORE();
+
+	return (NULL);
 }
 
 #ifndef _KERNEL



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