From nobody Wed Apr 29 14:49:26 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4g5KvW5V3Lz6bks0 for ; Wed, 29 Apr 2026 14:49:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4g5KvV68bnz4KV9 for ; Wed, 29 Apr 2026 14:49:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777474166; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LIV4RnW/OEKoCZNOHCN8Bg8NWp3Hki0O3/vRnjbObqA=; b=YHCJ6kN6IdqM1r5bjYNpCPnFBsL0maslUsZ3FHLXn2a5ZXEQhA7G7s0X0tvvMtqH0qMUzs K45BkuNFj53nciMxAAzMY1FLNUD6ODh6L7Gayb+S5XTfK9xOuK1TLWXzLL0QeR2UFJYOP5 8NoYlWYjn3V7wbZYRxLPRPl+kXm9Xb5LsaqJ1apZpTxLqhexOUV+XTYsrxVsze33j+fX1Q BX0l46yMgjAsPs5SdcbkCh9ws3GiWG+90BE6HqYPWIud2fyX1XszIOfdzmkpMR1GQC4JFS 2e6+RfwfhINXD/Nv/7ac0aBqvmKHG4RTC0INK/cL+sdqZ0J+XolaLROx9Xbeaw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777474166; a=rsa-sha256; cv=none; b=ZnKh7WaysCWxotIcgnkAFody+BLUg4Y4kxVhP3xt6LKNd/2pKXIS41rm9c/3RnokwSh/NE 0/cu1nemJG/TMnUla8MkdLwETQ9E+0brp8qPyz0y4EbBPnH4jagaR+AMVnXyZa+r0Vg1LZ wO3vQ0i62XsRrFXBMDTBQ/nnyhR1tSBV3xiHYeTb1NNTsvCoHVl8yhyDH/CkznLnPlhsTI 14bIXF4dIy/YHRJhqqybdZ+TO91M+BqjicmKJwr9oLA7A4tF5h8mx1C6ZVVSRGN7jJzaWM 8adcQALutNOoYVH7huvEkft0KqbxaeiKnMrTEcZzJzvwlzQ6FJKbOWqU60a0eA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777474166; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LIV4RnW/OEKoCZNOHCN8Bg8NWp3Hki0O3/vRnjbObqA=; b=uo5Auqei7ac407rMH5QkDl2W0b5mLJNUTC6zthFSE4PkAlSPYd63ZiTDtaSg7uu5obs6jX 2pRAnbgwoSQV/N7oTNMwEen5wM9T7EiGi3gyT3Os7jDgSejcmfm1vg2El5PgmAWwV1IYl4 WJ7BABs7Rhgc/RaITy7nmOM+tWfQVKV27C2bvtRP3O8+OdfGTJDpi+mBrvFYafz0Mbfnkc 4Q1vFS87kctxLnfeAJkMLrgoWvJE0ugq+njpOYJE2ykmbl+CabPGmQpPNvKYZW6FZ1sVwb fCkkvjXHse4L7W7/8JNdONBwq21UO30x/nYz1FwHqW80ECiLMimmNnINIk/RMg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g5KvV50k3zl7S for ; Wed, 29 Apr 2026 14:49:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3cb76 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 29 Apr 2026 14:49:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Mariusz Zaborski From: Mark Johnston Subject: git: 0963be1dbf88 - releng/14.3 - libnv: add tests to verify potential overflow issues List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/releng/14.3 X-Git-Reftype: branch X-Git-Commit: 0963be1dbf8886423c0c4efade79661989db9a77 Auto-Submitted: auto-generated Date: Wed, 29 Apr 2026 14:49:26 +0000 Message-Id: <69f21a76.3cb76.236c649e@gitrepo.freebsd.org> The branch releng/14.3 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=0963be1dbf8886423c0c4efade79661989db9a77 commit 0963be1dbf8886423c0c4efade79661989db9a77 Author: Mariusz Zaborski AuthorDate: 2024-08-29 13:46:01 +0000 Commit: Mark Johnston CommitDate: 2026-04-28 20:33:04 +0000 libnv: add tests to verify potential overflow issues Approved by: so Differential Revision: https://reviews.freebsd.org/D46131 (cherry picked from commit 241a7ddd7112982ed41ccdd047c1dad59ee0256e) --- lib/libnv/tests/Makefile | 9 ++ lib/libnv/tests/nvlist_send_recv_test.c | 193 ++++++++++++++++++++++++++++++++ sys/contrib/libnv/nv_impl.h | 8 ++ sys/contrib/libnv/nvlist.c | 7 -- 4 files changed, 210 insertions(+), 7 deletions(-) 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 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/nvlist_send_recv_test.c b/lib/libnv/tests/nvlist_send_recv_test.c index 5d4f392ed49c..cd97ccb6b9b9 100644 --- a/lib/libnv/tests/nvlist_send_recv_test.c +++ b/lib/libnv/tests/nvlist_send_recv_test.c @@ -44,6 +44,9 @@ #include +#include +#include + #define ALPHABET "abcdefghijklmnopqrstuvwxyz" #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF) @@ -543,6 +546,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) { @@ -553,5 +742,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()); } diff --git a/sys/contrib/libnv/nv_impl.h b/sys/contrib/libnv/nv_impl.h index e9cd3ffabc3f..4ac57fc7b497 100644 --- a/sys/contrib/libnv/nv_impl.h +++ b/sys/contrib/libnv/nv_impl.h @@ -42,6 +42,14 @@ struct nvpair; typedef struct nvpair nvpair_t; #endif +struct nvlist_header { + uint8_t nvlh_magic; + uint8_t nvlh_version; + uint8_t nvlh_flags; + uint64_t nvlh_descriptors; + uint64_t nvlh_size; +} __packed; + #define NV_TYPE_NVLIST_ARRAY_NEXT 254 #define NV_TYPE_NVLIST_UP 255 diff --git a/sys/contrib/libnv/nvlist.c b/sys/contrib/libnv/nvlist.c index 92d6e655876a..00ba3b41f3a3 100644 --- a/sys/contrib/libnv/nvlist.c +++ b/sys/contrib/libnv/nvlist.c @@ -118,13 +118,6 @@ MALLOC_DEFINE(M_NVLIST, "nvlist", "kernel nvlist"); #define NVLIST_HEADER_MAGIC 0x6c #define NVLIST_HEADER_VERSION 0x00 -struct nvlist_header { - uint8_t nvlh_magic; - uint8_t nvlh_version; - uint8_t nvlh_flags; - uint64_t nvlh_descriptors; - uint64_t nvlh_size; -} __packed; nvlist_t * nvlist_create(int flags)