aboutsummaryrefslogtreecommitdiff
path: root/lib/libnv
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libnv')
-rw-r--r--lib/libnv/Makefile1
-rw-r--r--lib/libnv/common_impl.h1
-rw-r--r--lib/libnv/msgio.c1
-rw-r--r--lib/libnv/tests/Makefile9
-rw-r--r--lib/libnv/tests/dnv_tests.cc1
-rw-r--r--lib/libnv/tests/nv_array_tests.cc59
-rw-r--r--lib/libnv/tests/nvlist_add_test.c1
-rw-r--r--lib/libnv/tests/nvlist_exists_test.c1
-rw-r--r--lib/libnv/tests/nvlist_free_test.c1
-rw-r--r--lib/libnv/tests/nvlist_get_test.c1
-rw-r--r--lib/libnv/tests/nvlist_move_test.c1
-rw-r--r--lib/libnv/tests/nvlist_send_recv_test.c195
12 files changed, 258 insertions, 14 deletions
diff --git a/lib/libnv/Makefile b/lib/libnv/Makefile
index c9bf45e02050..f4225df297d6 100644
--- a/lib/libnv/Makefile
+++ b/lib/libnv/Makefile
@@ -1,4 +1,3 @@
-
SHLIBDIR?= /lib
.include <src.opts.mk>
diff --git a/lib/libnv/common_impl.h b/lib/libnv/common_impl.h
index 03de9749aaf6..27af1710540a 100644
--- a/lib/libnv/common_impl.h
+++ b/lib/libnv/common_impl.h
@@ -2,7 +2,6 @@
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
diff --git a/lib/libnv/msgio.c b/lib/libnv/msgio.c
index 002c626647d9..f6f75241ff06 100644
--- a/lib/libnv/msgio.c
+++ b/lib/libnv/msgio.c
@@ -30,7 +30,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/select.h>
diff --git a/lib/libnv/tests/Makefile b/lib/libnv/tests/Makefile
index fc377e38ce83..aea416539c4a 100644
--- a/lib/libnv/tests/Makefile
+++ b/lib/libnv/tests/Makefile
@@ -1,7 +1,16 @@
+.include <src.opts.mk>
ATF_TESTS_C= \
nvlist_send_recv_test
+.PATH: ${SRCTOP}/lib/libnv
+SRCS.nvlist_send_recv_test= msgio.c nvlist_send_recv_test.c
+CFLAGS.nvlist_send_recv_test+=-I${SRCTOP}/sys/contrib/libnv
+CFLAGS.nvlist_send_recv_test+=-I${SRCTOP}/lib/libnv
+.if ${MK_ASAN} != "yes"
+CFLAGS.nvlist_send_recv_test+=-DNO_ASAN
+.endif
+
ATF_TESTS_CXX= \
cnv_tests \
dnv_tests \
diff --git a/lib/libnv/tests/dnv_tests.cc b/lib/libnv/tests/dnv_tests.cc
index b66315713bca..cf478f1bd2a2 100644
--- a/lib/libnv/tests/dnv_tests.cc
+++ b/lib/libnv/tests/dnv_tests.cc
@@ -24,7 +24,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/dnv.h>
#include <sys/nv.h>
diff --git a/lib/libnv/tests/nv_array_tests.cc b/lib/libnv/tests/nv_array_tests.cc
index f5c448598b22..9acbaef67eba 100644
--- a/lib/libnv/tests/nv_array_tests.cc
+++ b/lib/libnv/tests/nv_array_tests.cc
@@ -1,6 +1,5 @@
/*-
- * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
- * All rights reserved.
+ * Copyright (c) 2015-2024 Mariusz Zaborski <oshogbo@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,10 +23,10 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/nv.h>
+#include <sys/mman.h>
#include <sys/socket.h>
#include <atf-c++.hpp>
@@ -1162,6 +1161,58 @@ ATF_TEST_CASE_BODY(nvlist_nvlist_array__pack)
free(packed);
}
+
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array_nonull__pack);
+ATF_TEST_CASE_BODY(nvlist_string_array_nonull__pack)
+{
+ nvlist_t *testnvl, *unpacked;
+ const char *somestr[3] = { "a", "b", "XXX" };
+ uint8_t *packed, *twopages, *dataptr, *secondpage;
+ size_t packed_size, page_size;
+ bool found;
+
+ page_size = sysconf(_SC_PAGESIZE);
+ testnvl = nvlist_create(0);
+ ATF_REQUIRE(testnvl != NULL);
+ ATF_REQUIRE_EQ(nvlist_error(testnvl), 0);
+ nvlist_add_string_array(testnvl, "nvl/string", somestr,
+ nitems(somestr));
+ ATF_REQUIRE_EQ(nvlist_error(testnvl), 0);
+
+ packed = (uint8_t *)nvlist_pack(testnvl, &packed_size);
+ ATF_REQUIRE(packed != NULL);
+
+ twopages = (uint8_t *)mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ATF_REQUIRE(twopages != MAP_FAILED);
+ dataptr = &twopages[page_size - packed_size];
+ secondpage = &twopages[page_size];
+
+ memset(twopages, 'A', page_size * 2);
+
+ mprotect(secondpage, page_size, PROT_NONE);
+ memcpy(dataptr, packed, packed_size);
+
+ found = false;
+ for (size_t i = 0; i < packed_size - 3; i++) {
+ if (dataptr[i] == 'X' && dataptr[i + 1] == 'X' &&
+ dataptr[i + 2] == 'X' && dataptr[i + 3] == '\0') {
+ dataptr[i + 3] = 'X';
+ found = true;
+ break;
+ }
+ }
+ ATF_REQUIRE(found == true);
+
+ unpacked = nvlist_unpack(dataptr, packed_size, 0);
+ ATF_REQUIRE(unpacked == NULL);
+
+ nvlist_destroy(testnvl);
+ free(packed);
+ munmap(twopages, page_size * 2);
+}
+
+
ATF_INIT_TEST_CASES(tp)
{
@@ -1191,5 +1242,7 @@ ATF_INIT_TEST_CASES(tp)
ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__pack)
ATF_ADD_TEST_CASE(tp, nvlist_string_array__pack)
ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__pack)
+
+ ATF_ADD_TEST_CASE(tp, nvlist_string_array_nonull__pack)
}
diff --git a/lib/libnv/tests/nvlist_add_test.c b/lib/libnv/tests/nvlist_add_test.c
index 4478efadf4e0..28f2b6f45446 100644
--- a/lib/libnv/tests/nvlist_add_test.c
+++ b/lib/libnv/tests/nvlist_add_test.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
diff --git a/lib/libnv/tests/nvlist_exists_test.c b/lib/libnv/tests/nvlist_exists_test.c
index 7450256ab760..808692feb85b 100644
--- a/lib/libnv/tests/nvlist_exists_test.c
+++ b/lib/libnv/tests/nvlist_exists_test.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
diff --git a/lib/libnv/tests/nvlist_free_test.c b/lib/libnv/tests/nvlist_free_test.c
index c715aef6657b..bb5eeaf7d04c 100644
--- a/lib/libnv/tests/nvlist_free_test.c
+++ b/lib/libnv/tests/nvlist_free_test.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
diff --git a/lib/libnv/tests/nvlist_get_test.c b/lib/libnv/tests/nvlist_get_test.c
index d6e4a9b4d65a..f06be569c90d 100644
--- a/lib/libnv/tests/nvlist_get_test.c
+++ b/lib/libnv/tests/nvlist_get_test.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
diff --git a/lib/libnv/tests/nvlist_move_test.c b/lib/libnv/tests/nvlist_move_test.c
index 3c99f4582c5e..2ef7ca4de384 100644
--- a/lib/libnv/tests/nvlist_move_test.c
+++ b/lib/libnv/tests/nvlist_move_test.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
diff --git a/lib/libnv/tests/nvlist_send_recv_test.c b/lib/libnv/tests/nvlist_send_recv_test.c
index 25edaa5c3c10..79297dfe2043 100644
--- a/lib/libnv/tests/nvlist_send_recv_test.c
+++ b/lib/libnv/tests/nvlist_send_recv_test.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2013 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
* the FreeBSD Foundation.
@@ -27,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -45,6 +43,9 @@
#include <atf-c.h>
+#include <nv_impl.h>
+#include <msgio.h>
+
#define ALPHABET "abcdefghijklmnopqrstuvwxyz"
#define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
@@ -544,6 +545,192 @@ ATF_TC_BODY(nvlist_send_recv__send_closed_fd__stream, tc)
nvlist_send_recv__send_closed_fd(SOCK_STREAM);
}
+ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_header_size);
+ATF_TC_BODY(nvlist_send_recv__overflow_header_size, tc)
+{
+ nvlist_t *nvl;
+ void *packed;
+ size_t packed_size;
+ struct nvlist_header *header;
+ int fd, socks[2], status;
+ pid_t pid;
+
+#ifdef NO_ASAN
+ atf_tc_skip("This test requires ASAN");
+#endif
+
+ ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ /* Child. */
+ fd = socks[0];
+ close(socks[1]);
+
+ nvl = nvlist_create(0);
+ ATF_REQUIRE(nvl != NULL);
+ ATF_REQUIRE(nvlist_empty(nvl));
+
+ packed = nvlist_pack(nvl, &packed_size);
+ ATF_REQUIRE(packed != NULL);
+ ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
+
+ header = (struct nvlist_header *)packed;
+ header->nvlh_size = SIZE_MAX - sizeof(struct nvlist_header) + 2;
+
+ ATF_REQUIRE_EQ(write(fd, packed, packed_size),
+ (ssize_t)sizeof(struct nvlist_header));
+
+ nvlist_destroy(nvl);
+ free(packed);
+
+ exit(0);
+ } else {
+ /* Parent */
+ fd = socks[1];
+ close(socks[0]);
+
+ errno = 0;
+ nvl = nvlist_recv(fd, 0);
+ ATF_REQUIRE(nvl == NULL);
+
+ /*
+ * Make sure it has failed on EINVAL, and not on
+ * errors returned by malloc or recv.
+ */
+ ATF_REQUIRE(errno == EINVAL);
+
+ ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
+ ATF_REQUIRE(status == 0);
+ close(fd);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(nvlist_send_recv__invalid_fd_size);
+ATF_TC_BODY(nvlist_send_recv__invalid_fd_size, tc)
+{
+ nvlist_t *nvl;
+ void *packed;
+ size_t packed_size;
+ struct nvlist_header *header;
+ int fd, socks[2], status;
+ pid_t pid;
+
+ ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ /* Child. */
+ fd = socks[0];
+ close(socks[1]);
+
+ nvl = nvlist_create(0);
+ ATF_REQUIRE(nvl != NULL);
+ ATF_REQUIRE(nvlist_empty(nvl));
+
+ nvlist_add_string(nvl, "nvl/string", "test");
+ ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+ packed = nvlist_pack(nvl, &packed_size);
+ ATF_REQUIRE(packed != NULL);
+ ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
+
+ header = (struct nvlist_header *)packed;
+ header->nvlh_descriptors = 0x20;
+
+ ATF_REQUIRE_EQ(write(fd, packed, packed_size),
+ (ssize_t)packed_size);
+
+ nvlist_destroy(nvl);
+ free(packed);
+
+ exit(0);
+ } else {
+ /* Parent */
+ fd = socks[1];
+ close(socks[0]);
+
+ nvl = nvlist_recv(fd, 0);
+ ATF_REQUIRE(nvl == NULL);
+
+ ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
+ ATF_REQUIRE(status == 0);
+ }
+
+ close(fd);
+}
+
+ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_fd_size);
+ATF_TC_BODY(nvlist_send_recv__overflow_fd_size, tc)
+{
+ nvlist_t *nvl;
+ void *packed;
+ size_t packed_size;
+ struct nvlist_header *header;
+ int fd, socks[2], fds[1], status;
+ pid_t pid;
+
+ ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ /* Child. */
+ fd = socks[0];
+ close(socks[1]);
+
+ nvl = nvlist_create(0);
+ ATF_REQUIRE(nvl != NULL);
+ ATF_REQUIRE(nvlist_empty(nvl));
+
+ nvlist_add_string(nvl, "nvl/string", "test");
+ ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
+
+ packed = nvlist_pack(nvl, &packed_size);
+ ATF_REQUIRE(packed != NULL);
+ ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
+
+ header = (struct nvlist_header *)packed;
+ header->nvlh_descriptors = 0x4000000000000002;
+
+ ATF_REQUIRE_EQ(write(fd, packed, packed_size),
+ (ssize_t)packed_size);
+
+ fds[0] = dup(STDERR_FILENO);
+ ATF_REQUIRE(fds[0] >= 0);
+ ATF_REQUIRE_EQ(fd_send(fd, fds, 1), 0);
+
+ nvlist_destroy(nvl);
+ free(packed);
+
+ close(fds[0]);
+ close(fd);
+
+ exit(0);
+ } else {
+ /* Parent */
+ fd = socks[1];
+ close(socks[0]);
+
+ nvl = nvlist_recv(fd, 0);
+ ATF_REQUIRE(nvl == NULL);
+
+ /* Make sure that fd was not parsed by nvlist */
+ ATF_REQUIRE(fd_recv(fd, fds, 1) == 0);
+
+ ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
+ ATF_REQUIRE(status == 0);
+
+ close(fds[0]);
+ close(fd);
+ }
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -554,5 +741,9 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__dgram);
ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__stream);
+ ATF_TP_ADD_TC(tp, nvlist_send_recv__overflow_header_size);
+ ATF_TP_ADD_TC(tp, nvlist_send_recv__invalid_fd_size);
+ ATF_TP_ADD_TC(tp, nvlist_send_recv__overflow_fd_size);
+
return (atf_no_error());
}