From nobody Sat Oct 14 17:57:43 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 4S7B140nSjz4x4RB; Sat, 14 Oct 2023 17:57:44 +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 4S7B1372gwz4TRb; Sat, 14 Oct 2023 17:57:43 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1697306264; 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=2XYJx6sFeXmcQEOjVC3jNpcx5uaJjZK5lV0UwiHzseA=; b=et/yX9MWSulvUuwQnrw1WCUbFJHmouL8JkXwnYYsq2/t0x8bJ/9ehg+1EzvoCHkvKp0VXR qrZdUj3clbpGGiEPYJ5WkYCCnCjXds1n99qIXXmHhO85dtxSHcLKykY3c5Bqz9nce/PC1h t+gJ1mMVMz4csTvi1NWvOdqJrpDAlGx7rrgSsU21M8dSAkkItLfCFa6mJe1PprJiIBFEDx xlZ2x8loeuw4FXE9XWHYwjs7NVFJaArm0N96r6NaPuAtq/rZdEfEEfgLBKSZP9EU3mYaTY VcBWwxY+/hJH1/pFjMdwcspooD/2JeUCkGvkBUPz6CoKDYfm4Jhgli0rRYH0rA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1697306264; a=rsa-sha256; cv=none; b=FsUeDrZC/PvhcjdgedJJNtKJ0lQYVVIzyMzsGRAwf216CUnRLmuswda/bRDtr6hFtbO95O c4okK4JYwYm0FqtAJnezy1Z9iKvqBPmy+VOR9RnMCUQlWG3guverrv0Hoa0L2soMB1QzaX fupYtXDmpC/YOjepyot/eTwyZyzaN/5eN1EyDDRBpytDmKZpARq31krMHoVJ3HtXXQfy+I +y+pCN0cuW6IIEKrdNfap2Yvez2pw/WYJE6dm8A4SJCxzNnKFuofAe0t0+e2eNa14S4cTm 0gTpd7SaOqEerMWxcU9XQwnXWcm5sfdEa0DfS+3UsVU9rXQoxQQAacFt47HZ4g== 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=1697306264; 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=2XYJx6sFeXmcQEOjVC3jNpcx5uaJjZK5lV0UwiHzseA=; b=cwkxy2dnR0Ve1ePAzbc0xqezall25pcE8z5EdvYMSxkhwbkB/2mEpELdS1hEL4ciIz+Dn1 7BXjBierEx+vZfWdDOWqbmaLUFRopnajYSxDPuc8JDnUm/O1qPHnRXPti+WqdR9PJMq7rz JERMGRdnJkNpodJe41Ka5ygc3YdiF/sUWbXl4fNnS5EuoCTZwKtondD5maylgBFN6YUxDq G6Witl3vZuaws/lagYbXL+k8stQ9j/UyZSCq2EO7W5Elz/m6XffOn9B0E5idmczPEgvTYQ M4yeG6H/B8GqCHpDso3zyLbO6S2aYhUkAzbrw2r3l80ARmCtWcbTWMhibTot9A== 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 4S7B1361WjzgVN; Sat, 14 Oct 2023 17:57:43 +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 39EHvhhc030120; Sat, 14 Oct 2023 17:57:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 39EHvheG030117; Sat, 14 Oct 2023 17:57:43 GMT (envelope-from git) Date: Sat, 14 Oct 2023 17:57:43 GMT Message-Id: <202310141757.39EHvheG030117@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Alan Somers Subject: git: 8fca98f6881f - stable/14 - 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/stable/14 X-Git-Reftype: branch X-Git-Commit: 8fca98f6881fdd68a786f4366c345159ab0df408 Auto-Submitted: auto-generated The branch stable/14 has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=8fca98f6881fdd68a786f4366c345159ab0df408 commit 8fca98f6881fdd68a786f4366c345159ab0df408 Author: Alan Somers AuthorDate: 2023-10-04 18:48:01 +0000 Commit: Alan Somers CommitDate: 2023-10-14 17:57:09 +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 Sponsored by: Axcient Reviewed by: mjg, markj Differential Revision: https://reviews.freebsd.org/D42081 (cherry picked from commit 662ec2f781521c36b76af748d74bb0a3c2e27a76) --- 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";