From nobody Sat Oct 7 14:24:52 2023 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 4S2nch61Cbz4wX7Q; Sat, 7 Oct 2023 14:24:52 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4S2nch5ZXGz4cdD; Sat, 7 Oct 2023 14:24:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1696688692; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=9EjGhQiNRXg/TG8exDgsNyccePkRqg0ZGJxioiq1H+s=; b=b5XEovb0AMrVczpmWWpO5kJdoO01M1kAiknffmvKbpOqPwwuXgpTmRMu2uNcV89x/SXQmS zSVcw+difCrI5vBCvzZY8d0XS//UHpU35AmJHnndAyAdNHqFMVHf9hm9VAwjQwPzWK5jpk M/GipbWcvh7FxZ5ysHYGijyW7A66qDsFPjz+L7Ujk0yVGjI1mkgHLIYypVawjp6NOTYE2X NZGumn8ERiwAfKVTVVmUCuw1KgrKedxDb5+tfgVn8szoiMY95ehwQEHOmICnhnVD5wqdtA HAYfdm1hPcKjaUNUc3/89uzxBFtjoEThxc9z2XR2UZdnpkH/VuzeXxXsUlDI5Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1696688692; a=rsa-sha256; cv=none; b=FXPJBYrKfSB8SJu8jXjNAi6J96p6tuQ1kT9ss5gSGY9UmAXHchkH/oIzBlrNc/T1mFLNhq TTNWov/hQq0mhjjBSL1MKhlRRcUZali96YGoJA9rYvbFswyDNHuMMAAp9mhMagk1BBp8NA d5c3laSWDsXhx2I6vW+ijs9C9oJ5RjB3cfcQK0Xe9GOtkYB8Nj7/Y3FbgCRaEmJauipjib rMPwgwJDD41ipPitkuHw07ugZIRRSs7KUK4QpIAJ19QjFRwXfHt8h8r7NvExudc+FFwyeH DfFI1LxOP4zYVe0zRnB+OVXttxFOgm460iiyrnH6Kl73zMcdCbT7LeirhzkbKQ== 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=1696688692; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=9EjGhQiNRXg/TG8exDgsNyccePkRqg0ZGJxioiq1H+s=; b=qbVWtfbbq/XL6cJVN+wU0Ix8RlND8Jm0i6CDKksIuHL2W+ZRYtw/klq+LYaXCJzF+1N9P8 yfBt75rVtNpVj4QkciP/Lo3JeKqN+gpoFmDTZIujp6U6H391eFhWt7QoXmDVlLkm2y96GV ZrrodHrfw05YSFk5Ik4ba22NTTBIDgyAok9EGEZBrUoSU3PRTkhP+lUvy0c2uBFyGt534R hhaRxaRr0916PxFO5VEeT6kA5Romjod1IxSb5SOWpSfTUWZP++S8SeNoV2DDabMEvbvIft 1x7/ar+AdzZgWsnHU6BJjwap/yzGhs7GrhBt60F3gOyGhUM9iqTg9SnIsdJTpg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4S2nch4WvSzZNv; Sat, 7 Oct 2023 14:24:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 397EOqHG086648; Sat, 7 Oct 2023 14:24:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 397EOq0u086645; Sat, 7 Oct 2023 14:24:52 GMT (envelope-from git) Date: Sat, 7 Oct 2023 14:24:52 GMT Message-Id: <202310071424.397EOq0u086645@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Alan Somers Subject: git: 662ec2f78152 - main - fusefs: sanitize FUSE_READLINK results for embedded NULs 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: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: asomers X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 662ec2f781521c36b76af748d74bb0a3c2e27a76 Auto-Submitted: auto-generated The branch main has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=662ec2f781521c36b76af748d74bb0a3c2e27a76 commit 662ec2f781521c36b76af748d74bb0a3c2e27a76 Author: Alan Somers AuthorDate: 2023-10-04 18:48:01 +0000 Commit: Alan Somers CommitDate: 2023-10-07 14:22:03 +0000 fusefs: sanitize FUSE_READLINK results for embedded NULs If VOP_READLINK returns a path that contains a NUL, it will trigger an assertion in vfs_lookup. Sanitize such paths in fusefs, rejecting any and warning the user about the misbehaving server. PR: 274268 MFC after: 1 week Sponsored by: Axcient Reviewed by: mjg, markj Differential Revision: https://reviews.freebsd.org/D42081 --- sys/fs/fuse/fuse_ipc.h | 1 + sys/fs/fuse/fuse_vnops.c | 7 +++++++ tests/sys/fs/fusefs/readlink.cc | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/sys/fs/fuse/fuse_ipc.h b/sys/fs/fuse/fuse_ipc.h index 27f3662741c5..0ec556138be0 100644 --- a/sys/fs/fuse/fuse_ipc.h +++ b/sys/fs/fuse/fuse_ipc.h @@ -239,6 +239,7 @@ struct fuse_data { #define FSESS_WARN_CACHE_INCOHERENT 0x200000 /* Read cache incoherent */ #define FSESS_WARN_WB_CACHE_INCOHERENT 0x400000 /* WB cache incoherent */ #define FSESS_WARN_ILLEGAL_INODE 0x800000 /* Illegal inode for new file */ +#define FSESS_WARN_READLINK_EMBEDDED_NUL 0x1000000 /* corrupt READLINK output */ #define FSESS_MNTOPTS_MASK ( \ FSESS_DAEMON_CAN_SPY | FSESS_PUSH_SYMLINKS_IN | \ FSESS_DEFAULT_PERMISSIONS | FSESS_INTR) diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 21ee378b24c6..3249e5988801 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -2007,6 +2007,13 @@ fuse_vnop_readlink(struct vop_readlink_args *ap) if (err) { goto out; } + if (strnlen(fdi.answ, fdi.iosize) + 1 < fdi.iosize) { + struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp)); + fuse_warn(data, FSESS_WARN_READLINK_EMBEDDED_NUL, + "Returned an embedded NUL from FUSE_READLINK."); + err = EIO; + goto out; + } if (((char *)fdi.answ)[0] == '/' && fuse_get_mpdata(vnode_mount(vp))->dataflags & FSESS_PUSH_SYMLINKS_IN) { char *mpth = vnode_mount(vp)->mnt_stat.f_mntonname; diff --git a/tests/sys/fs/fusefs/readlink.cc b/tests/sys/fs/fusefs/readlink.cc index ff9aa08f6fae..30815f2cd4b6 100644 --- a/tests/sys/fs/fusefs/readlink.cc +++ b/tests/sys/fs/fusefs/readlink.cc @@ -79,6 +79,45 @@ TEST_F(Readlink, eloop) EXPECT_EQ(ELOOP, errno); } +/* + * If a malicious or buggy server returns a NUL in the FUSE_READLINK result, it + * should be handled gracefully. + * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274268 + */ +TEST_F(Readlink, embedded_nul) +{ + const char FULLPATH[] = "mountpoint/src"; + const char RELPATH[] = "src"; + const char dst[] = "dst\0stuff"; + char buf[80]; + const uint64_t ino = 42; + + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, entry); + out.body.entry.attr.mode = S_IFLNK | 0777; + out.body.entry.nodeid = ino; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = UINT64_MAX; + }))); + + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_READLINK && + in.header.nodeid == ino); + }, Eq(true)), + _) + ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { + memcpy(out.body.str, dst, sizeof(dst)); + out.header.len = sizeof(out.header) + sizeof(dst) + 1; + }))); + + EXPECT_EQ(-1, readlink(FULLPATH, buf, sizeof(buf))); + EXPECT_EQ(EIO, errno); + EXPECT_EQ(-1, access(FULLPATH, R_OK)); + EXPECT_EQ(EIO, errno); +} + TEST_F(Readlink, ok) { const char FULLPATH[] = "mountpoint/src";