libnv: fix 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() use Submitted by: Mindaugas Rasiukevicius <rmind@netbsd.org> Reported by: clang/gcc ASAN MFC after: 2 weeks
This commit is contained in:
parent
e0d164c7a6
commit
b5d787d93b
@ -304,6 +304,8 @@ parent(int sock)
|
|||||||
|
|
||||||
name = nvlist_next(nvl, &type, &cookie);
|
name = nvlist_next(nvl, &type, &cookie);
|
||||||
CHECK(name == NULL);
|
CHECK(name == NULL);
|
||||||
|
|
||||||
|
nvlist_destroy(nvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -103,6 +103,7 @@ bool nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp);
|
|||||||
|
|
||||||
void nvlist_set_parent(nvlist_t *nvl, nvpair_t *parent);
|
void nvlist_set_parent(nvlist_t *nvl, nvpair_t *parent);
|
||||||
void nvlist_set_array_next(nvlist_t *nvl, nvpair_t *ele);
|
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);
|
const nvpair_t *nvlist_get_nvpair(const nvlist_t *nvl, const char *name);
|
||||||
|
|
||||||
|
@ -247,6 +247,15 @@ nvlist_set_array_next(nvlist_t *nvl, nvpair_t *ele)
|
|||||||
nvl->nvl_array_next = ele;
|
nvl->nvl_array_next = ele;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvpair_t *
|
||||||
|
nvlist_get_array_next_nvpair(nvlist_t *nvl)
|
||||||
|
{
|
||||||
|
|
||||||
|
NVLIST_ASSERT(nvl);
|
||||||
|
|
||||||
|
return (nvl->nvl_array_next);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nvlist_in_array(const nvlist_t *nvl)
|
nvlist_in_array(const nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
|
@ -229,8 +229,16 @@ nvpair_remove_nvlist_array(nvpair_t *nvp)
|
|||||||
nvlarray = __DECONST(nvlist_t **,
|
nvlarray = __DECONST(nvlist_t **,
|
||||||
nvpair_get_nvlist_array(nvp, &count));
|
nvpair_get_nvlist_array(nvp, &count));
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
nvlist_set_array_next(nvlarray[i], NULL);
|
nvlist_t *nvl;
|
||||||
nvlist_set_parent(nvlarray[i], NULL);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1193,8 +1201,7 @@ nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap)
|
|||||||
if (len < 0)
|
if (len < 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
nvp = nvpair_create_string(name, str);
|
nvp = nvpair_create_string(name, str);
|
||||||
if (nvp == NULL)
|
nv_free(str);
|
||||||
nv_free(str);
|
|
||||||
return (nvp);
|
return (nvp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user