aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib
diff options
context:
space:
mode:
authorMariusz Zaborski <oshogbo@FreeBSD.org>2017-09-21 10:10:42 +0000
committerMariusz Zaborski <oshogbo@FreeBSD.org>2017-09-21 10:10:42 +0000
commitc696dd0687ebf475e76289c6d1500a936801d612 (patch)
treee40e887dd6f32c3a36a75ae1a0c8d7265e74250b /sys/contrib
parenta3c485d38d914f733c1b185b3f76bda7fde394f2 (diff)
downloadsrc-c696dd0687ebf475e76289c6d1500a936801d612.tar.gz
src-c696dd0687ebf475e76289c6d1500a936801d612.zip
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
Notes
Notes: svn path=/head/; revision=323854
Diffstat (limited to 'sys/contrib')
-rw-r--r--sys/contrib/libnv/nvpair.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/sys/contrib/libnv/nvpair.c b/sys/contrib/libnv/nvpair.c
index 42cfaf8816ec..7d4500fdf7a3 100644
--- a/sys/contrib/libnv/nvpair.c
+++ b/sys/contrib/libnv/nvpair.c
@@ -1407,10 +1407,9 @@ nvpair_create_nvlist_array(const char *name, const nvlist_t * const *value,
{
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 nvlist_t * const *value,
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