svn commit: r293092 - in user/ngie/stable-10-libnv: share/man/man9 sys/contrib/libnv
Garrett Cooper
ngie at FreeBSD.org
Sun Jan 3 09:08:36 UTC 2016
Author: ngie
Date: Sun Jan 3 09:08:34 2016
New Revision: 293092
URL: https://svnweb.freebsd.org/changeset/base/293092
Log:
MFC r286642,r286644,r286645,r286646:
r286642 (by oshogbo):
Make the nvlist_next(9) function handle NULL pointer variable.
This simplifies removing the first element from nvlist.
r286644 (by oshogbo):
Don't set parent if the unpack operation fail. In some
case this could crash the library, because of the NULL pointer references.
Discovered thanks to american fuzzy lop.
r286645 (by oshogbo):
The nvlist_move_nvpair() function can fail in two cases, if:
- the nvlist error is set, or
- the nvlist case ignore flag is not set and there is attend to
add element with duplicated name.
In both cases the nvlist_move_nvpair() function free nvpair structure.
If library will try to unpack a binary blob which contains duplicated
names it will end up with using memory after free.
To prevent that, the nvlist_move_nvpair() function interface is changed
to report about failure and checks are added to the nvpair_xunpack()
function.
Discovered thanks to the american fuzzy lop.
r286646 (by oshogbo):
If any function fail (the ptr variable will be equal to NULL), we shouldn't
return buffer. Instead we should free it and return NULL.
Modified:
user/ngie/stable-10-libnv/share/man/man9/nv.9
user/ngie/stable-10-libnv/sys/contrib/libnv/nv_impl.h
user/ngie/stable-10-libnv/sys/contrib/libnv/nvlist.c
Directory Properties:
user/ngie/stable-10-libnv/ (props changed)
Modified: user/ngie/stable-10-libnv/share/man/man9/nv.9
==============================================================================
--- user/ngie/stable-10-libnv/share/man/man9/nv.9 Sun Jan 3 08:48:23 2016 (r293091)
+++ user/ngie/stable-10-libnv/share/man/man9/nv.9 Sun Jan 3 09:08:34 2016 (r293092)
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 4, 2015
+.Dd Aug 11, 2015
.Dt NV 9
.Os
.Sh NAME
@@ -410,6 +410,16 @@ The
argument can be NULL.
Elements may not be removed from the nvlist while traversing it.
The nvlist must not be in error state.
+Note that
+.Fn nvlist_next
+will handle
+.Va cookiep
+being set to
+.Dv NULL .
+In this case first element is returned or
+.Dv NULL
+if nvlist is empty.
+This behavior simplifies removing the first element from the list.
.Pp
The
.Fn nvlist_exists
Modified: user/ngie/stable-10-libnv/sys/contrib/libnv/nv_impl.h
==============================================================================
--- user/ngie/stable-10-libnv/sys/contrib/libnv/nv_impl.h Sun Jan 3 08:48:23 2016 (r293091)
+++ user/ngie/stable-10-libnv/sys/contrib/libnv/nv_impl.h Sun Jan 3 09:08:34 2016 (r293092)
@@ -93,7 +93,7 @@ nvpair_t *nvlist_prev_nvpair(const nvlis
void nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp);
-void nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp);
+bool nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp);
void nvlist_set_parent(nvlist_t *nvl, nvpair_t *parent);
Modified: user/ngie/stable-10-libnv/sys/contrib/libnv/nvlist.c
==============================================================================
--- user/ngie/stable-10-libnv/sys/contrib/libnv/nvlist.c Sun Jan 3 08:48:23 2016 (r293091)
+++ user/ngie/stable-10-libnv/sys/contrib/libnv/nvlist.c Sun Jan 3 09:08:34 2016 (r293092)
@@ -330,7 +330,7 @@ nvlist_clone(const nvlist_t *nvl)
newnvp = nvpair_clone(nvp);
if (newnvp == NULL)
break;
- nvlist_move_nvpair(newnvl, newnvp);
+ (void)nvlist_move_nvpair(newnvl, newnvp);
}
if (nvp != NULL) {
nvlist_destroy(newnvl);
@@ -629,10 +629,8 @@ nvlist_xpack(const nvlist_t *nvl, int64_
nvpair_init_datasize(nvp);
ptr = nvpair_pack_header(nvp, ptr, &left);
- if (ptr == NULL) {
- nv_free(buf);
- return (NULL);
- }
+ if (ptr == NULL)
+ goto fail;
switch (nvpair_type(nvp)) {
case NV_TYPE_NULL:
ptr = nvpair_pack_null(nvp, ptr, &left);
@@ -650,7 +648,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_
tmpnvl = nvpair_get_nvlist(nvp);
ptr = nvlist_pack_header(tmpnvl, ptr, &left);
if (ptr == NULL)
- goto out;
+ goto fail;
tmpnvp = nvlist_first_nvpair(tmpnvl);
if (tmpnvp != NULL) {
nvl = tmpnvl;
@@ -670,10 +668,8 @@ nvlist_xpack(const nvlist_t *nvl, int64_
default:
PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp));
}
- if (ptr == NULL) {
- nv_free(buf);
- return (NULL);
- }
+ if (ptr == NULL)
+ goto fail;
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
cookie = NULL;
nvl = nvlist_get_parent(nvl, &cookie);
@@ -682,7 +678,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_
nvp = cookie;
ptr = nvpair_pack_nvlist_up(ptr, &left);
if (ptr == NULL)
- goto out;
+ goto fail;
}
}
@@ -690,6 +686,9 @@ out:
if (sizep != NULL)
*sizep = size;
return (buf);
+fail:
+ nv_free(buf);
+ return (NULL);
}
void *
@@ -824,6 +823,8 @@ nvlist_xunpack(const void *buf, size_t s
case NV_TYPE_NVLIST:
ptr = nvpair_unpack_nvlist(isbe, nvp, ptr, &left, nfds,
&tmpnvl);
+ if (tmpnvl == NULL || ptr == NULL)
+ goto failed;
nvlist_set_parent(tmpnvl, nvp);
break;
#ifndef _KERNEL
@@ -846,7 +847,8 @@ nvlist_xunpack(const void *buf, size_t s
}
if (ptr == NULL)
goto failed;
- nvlist_move_nvpair(nvl, nvp);
+ if (!nvlist_move_nvpair(nvl, nvp))
+ goto failed;
if (tmpnvl != NULL) {
nvl = tmpnvl;
tmpnvl = NULL;
@@ -1026,9 +1028,8 @@ nvlist_next(const nvlist_t *nvl, int *ty
nvpair_t *nvp;
NVLIST_ASSERT(nvl);
- PJDLOG_ASSERT(cookiep != NULL);
- if (*cookiep == NULL)
+ if (cookiep == NULL || *cookiep == NULL)
nvp = nvlist_first_nvpair(nvl);
else
nvp = nvlist_next_nvpair(nvl, *cookiep);
@@ -1036,7 +1037,8 @@ nvlist_next(const nvlist_t *nvl, int *ty
return (NULL);
if (typep != NULL)
*typep = nvpair_type(nvp);
- *cookiep = nvp;
+ if (cookiep != NULL)
+ *cookiep = nvp;
return (nvpair_name(nvp));
}
@@ -1122,7 +1124,7 @@ nvlist_add_stringv(nvlist_t *nvl, const
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
@@ -1141,7 +1143,7 @@ nvlist_add_null(nvlist_t *nvl, const cha
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
@@ -1161,7 +1163,7 @@ nvlist_add_binary(nvlist_t *nvl, const c
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
@@ -1182,7 +1184,7 @@ nvlist_add_##type(nvlist_t *nvl, const c
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); \
ERRNO_SET(nvl->nvl_error); \
} else { \
- nvlist_move_nvpair(nvl, nvp); \
+ (void)nvlist_move_nvpair(nvl, nvp); \
} \
}
@@ -1196,7 +1198,7 @@ NVLIST_ADD(int, descriptor);
#undef NVLIST_ADD
-void
+bool
nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
{
@@ -1206,18 +1208,19 @@ nvlist_move_nvpair(nvlist_t *nvl, nvpair
if (nvlist_error(nvl) != 0) {
nvpair_free(nvp);
ERRNO_SET(nvlist_error(nvl));
- return;
+ return (false);
}
if ((nvl->nvl_flags & NV_FLAG_NO_UNIQUE) == 0) {
if (nvlist_exists(nvl, nvpair_name(nvp))) {
nvpair_free(nvp);
nvl->nvl_error = EEXIST;
ERRNO_SET(nvl->nvl_error);
- return;
+ return (false);
}
}
nvpair_insert(&nvl->nvl_head, nvp, nvl);
+ return (true);
}
void
@@ -1236,7 +1239,7 @@ nvlist_move_string(nvlist_t *nvl, const
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
@@ -1257,7 +1260,7 @@ nvlist_move_nvlist(nvlist_t *nvl, const
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
@@ -1278,7 +1281,7 @@ nvlist_move_descriptor(nvlist_t *nvl, co
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
#endif
@@ -1299,7 +1302,7 @@ nvlist_move_binary(nvlist_t *nvl, const
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
} else {
- nvlist_move_nvpair(nvl, nvp);
+ (void)nvlist_move_nvpair(nvl, nvp);
}
}
More information about the svn-src-user
mailing list