diff options
author | rstone <rstone@FreeBSD.org> | 2015-03-01 00:22:38 +0000 |
---|---|---|
committer | rstone <rstone@FreeBSD.org> | 2015-03-01 00:22:38 +0000 |
commit | 87cea7c74794d913e54f5fe0793ced6c67b288ff (patch) | |
tree | 883d08fdd05c26d1b9d4a601c8316d40dd2e875c | |
parent | 82f396d1056e72b527e0fb7a04bafb6c8cb1f490 (diff) | |
download | FreeBSD-src-87cea7c74794d913e54f5fe0793ced6c67b288ff.zip FreeBSD-src-87cea7c74794d913e54f5fe0793ced6c67b288ff.tar.gz |
Prevent creation of an invalid nvlist
If an nvlist is set as a child of another nvlist with
nvlist_move_nvlist then fail the operation and set the parent
nvlist to the error state.
Differential Revision: https://reviews.freebsd.org/D1880
Reviewers: jfv
MFC after: 1 month
Sponsored by: Sandvine Inc
-rw-r--r-- | lib/libnv/nvpair.c | 6 | ||||
-rw-r--r-- | lib/libnv/tests/nv_tests.cc | 33 |
2 files changed, 39 insertions, 0 deletions
diff --git a/lib/libnv/nvpair.c b/lib/libnv/nvpair.c index a2da8cc..45cca6a 100644 --- a/lib/libnv/nvpair.c +++ b/lib/libnv/nvpair.c @@ -1128,6 +1128,12 @@ nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) return (NULL); } + if (nvlist_error(value) != 0) { + errno = nvlist_error(value); + nvlist_destroy(value); + return (NULL); + } + nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value, 0, namefmt, nameap); if (nvp == NULL) diff --git a/lib/libnv/tests/nv_tests.cc b/lib/libnv/tests/nv_tests.cc index e2a9924..8730432 100644 --- a/lib/libnv/tests/nv_tests.cc +++ b/lib/libnv/tests/nv_tests.cc @@ -243,6 +243,22 @@ ATF_TEST_CASE_BODY(nvlist_add_nvlist__single_insert) nvlist_destroy(nvl); } +ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_nvlist__child_with_error); +ATF_TEST_CASE_BODY(nvlist_add_nvlist__child_with_error) +{ + nvlist_t *nvl, *parent; + + nvl = nvlist_create(0); + parent = nvlist_create(0); + + nvlist_set_error(nvl, EBADF); + nvlist_add_nvlist(parent, "test", nvl); + ATF_REQUIRE_EQ(nvlist_error(parent), EBADF); + + nvlist_destroy(nvl); + nvlist_destroy(parent); +} + ATF_TEST_CASE_WITHOUT_HEAD(nvlist_add_binary__single_insert); ATF_TEST_CASE_BODY(nvlist_add_binary__single_insert) { @@ -654,6 +670,21 @@ ATF_TEST_CASE_BODY(nvlist_move_nvlist__null_child) nvlist_destroy(parent); } +ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__child_with_error); +ATF_TEST_CASE_BODY(nvlist_move_nvlist__child_with_error) +{ + nvlist_t *nvl, *parent; + + nvl = nvlist_create(0); + parent = nvlist_create(0); + + nvlist_set_error(nvl, EBADF); + nvlist_move_nvlist(parent, "test", nvl); + ATF_REQUIRE_EQ(nvlist_error(parent), EBADF); + + nvlist_destroy(parent); +} + ATF_TEST_CASE_WITHOUT_HEAD(nvlist_move_nvlist__single_insert); ATF_TEST_CASE_BODY(nvlist_move_nvlist__single_insert) { @@ -1177,6 +1208,7 @@ ATF_INIT_TEST_CASES(tp) ATF_ADD_TEST_CASE(tp, nvlist_add_number__single_insert); ATF_ADD_TEST_CASE(tp, nvlist_add_string__single_insert); ATF_ADD_TEST_CASE(tp, nvlist_add_nvlist__single_insert); + ATF_ADD_TEST_CASE(tp, nvlist_add_nvlist__child_with_error); ATF_ADD_TEST_CASE(tp, nvlist_add_binary__single_insert); ATF_ADD_TEST_CASE(tp, nvlist_clone__empty_nvlist); @@ -1192,6 +1224,7 @@ ATF_INIT_TEST_CASES(tp) ATF_ADD_TEST_CASE(tp, nvlist_move_string__single_insert); ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__single_insert); ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__null_child); + ATF_ADD_TEST_CASE(tp, nvlist_move_nvlist__child_with_error); ATF_ADD_TEST_CASE(tp, nvlist_move_binary__single_insert); ATF_ADD_TEST_CASE(tp, nvlist_take_bool__single_remove); |