diff options
Diffstat (limited to 'lib/libnv')
-rw-r--r-- | lib/libnv/Makefile | 1 | ||||
-rw-r--r-- | lib/libnv/common_impl.h | 1 | ||||
-rw-r--r-- | lib/libnv/msgio.c | 1 | ||||
-rw-r--r-- | lib/libnv/tests/Makefile | 9 | ||||
-rw-r--r-- | lib/libnv/tests/dnv_tests.cc | 1 | ||||
-rw-r--r-- | lib/libnv/tests/nv_array_tests.cc | 59 | ||||
-rw-r--r-- | lib/libnv/tests/nvlist_add_test.c | 1 | ||||
-rw-r--r-- | lib/libnv/tests/nvlist_exists_test.c | 1 | ||||
-rw-r--r-- | lib/libnv/tests/nvlist_free_test.c | 1 | ||||
-rw-r--r-- | lib/libnv/tests/nvlist_get_test.c | 1 | ||||
-rw-r--r-- | lib/libnv/tests/nvlist_move_test.c | 1 | ||||
-rw-r--r-- | lib/libnv/tests/nvlist_send_recv_test.c | 195 |
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()); } |