Date: Tue, 30 Sep 2025 21:14:44 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 72ac96ed8fa9 - stable/14 - libnv: Fix handling of nvlist_dump() and nvlist_send() for child nvlists Message-ID: <202509302114.58ULEiba010462@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=72ac96ed8fa9415c2be1a5ceb0289b45578ba7bd commit 72ac96ed8fa9415c2be1a5ceb0289b45578ba7bd Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2025-09-10 14:33:35 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2025-09-30 21:14:29 +0000 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 (cherry picked from commit 0b68e3ce6e0e437fa480b25a0ef706ee08562257) --- sys/contrib/libnv/nvlist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/contrib/libnv/nvlist.c b/sys/contrib/libnv/nvlist.c index 92d6e655876a..058ec032d3a3 100644 --- a/sys/contrib/libnv/nvlist.c +++ b/sys/contrib/libnv/nvlist.c @@ -486,7 +486,7 @@ nvlist_dump_error_check(const nvlist_t *nvl, int fd, int level) void nvlist_dump(const nvlist_t *nvl, int fd) { - const nvlist_t *tmpnvl; + const nvlist_t *tmpnvl, *top; nvpair_t *nvp, *tmpnvp; void *cookie; int level; @@ -495,6 +495,7 @@ nvlist_dump(const nvlist_t *nvl, int fd) if (nvlist_dump_error_check(nvl, fd, level)) return; + top = nvl; nvp = nvlist_first_nvpair(nvl); while (nvp != NULL) { dprintf(fd, "%*s%s (%s):", level * 4, "", nvpair_name(nvp), @@ -653,6 +654,8 @@ nvlist_dump(const nvlist_t *nvl, int fd) while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { do { + if (nvl == top) + return; cookie = NULL; if (nvlist_in_array(nvl)) dprintf(fd, "%*s,\n", level * 4, ""); @@ -855,7 +858,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) { unsigned char *buf, *ptr; size_t left, size; - const nvlist_t *tmpnvl; + const nvlist_t *tmpnvl, *top; nvpair_t *nvp, *tmpnvp; void *cookie; @@ -876,6 +879,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) ptr = nvlist_pack_header(nvl, ptr, &left); + top = nvl; nvp = nvlist_first_nvpair(nvl); while (nvp != NULL) { NVPAIR_ASSERT(nvp); @@ -966,6 +970,8 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) goto fail; while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { do { + if (nvl == top) + goto out; cookie = NULL; if (nvlist_in_array(nvl)) { ptr = nvpair_pack_nvlist_array_next(ptr,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202509302114.58ULEiba010462>