Skip to content

Commit 0b68e3c

Browse files
committed
libnv: Fix handling of nvlist_dump() and nvlist_send() for child nvlists
Suppose an nvlist nvl belongs to a parent nvlist or nvlist array. In this case, nvl contains a pointer to its container. This trips up nvlist_send(nvl) and nvlist_dump(nvl), which intuitively should only operate on nvl and its nvpairs. In particular, both of these functions will traverse to nvl's parent and start sending/dumping the parent's nvpairs, which results in assertion failures or nonsensical output, respectively. Reviewed by: oshogbo MFC after: 2 weeks Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D52360
1 parent 187ee62 commit 0b68e3c

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

sys/contrib/libnv/nvlist.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ nvlist_dump_error_check(const nvlist_t *nvl, int fd, int level)
478478
void
479479
nvlist_dump(const nvlist_t *nvl, int fd)
480480
{
481-
const nvlist_t *tmpnvl;
481+
const nvlist_t *tmpnvl, *top;
482482
nvpair_t *nvp, *tmpnvp;
483483
void *cookie;
484484
int level;
@@ -487,6 +487,7 @@ nvlist_dump(const nvlist_t *nvl, int fd)
487487
if (nvlist_dump_error_check(nvl, fd, level))
488488
return;
489489

490+
top = nvl;
490491
nvp = nvlist_first_nvpair(nvl);
491492
while (nvp != NULL) {
492493
dprintf(fd, "%*s%s (%s):", level * 4, "", nvpair_name(nvp),
@@ -645,6 +646,8 @@ nvlist_dump(const nvlist_t *nvl, int fd)
645646

646647
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
647648
do {
649+
if (nvl == top)
650+
return;
648651
cookie = NULL;
649652
if (nvlist_in_array(nvl))
650653
dprintf(fd, "%*s,\n", level * 4, "");
@@ -847,7 +850,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
847850
{
848851
unsigned char *buf, *ptr;
849852
size_t left, size;
850-
const nvlist_t *tmpnvl;
853+
const nvlist_t *tmpnvl, *top;
851854
nvpair_t *nvp, *tmpnvp;
852855
void *cookie;
853856

@@ -868,6 +871,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
868871

869872
ptr = nvlist_pack_header(nvl, ptr, &left);
870873

874+
top = nvl;
871875
nvp = nvlist_first_nvpair(nvl);
872876
while (nvp != NULL) {
873877
NVPAIR_ASSERT(nvp);
@@ -958,6 +962,8 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
958962
goto fail;
959963
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
960964
do {
965+
if (nvl == top)
966+
goto out;
961967
cookie = NULL;
962968
if (nvlist_in_array(nvl)) {
963969
ptr = nvpair_pack_nvlist_array_next(ptr,

0 commit comments

Comments
 (0)