From nobody Sun Oct 15 13:19:23 2023 X-Original-To: dev-commits-src-branches@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 4S7gnS1nsCz4wwkW; Sun, 15 Oct 2023 13:19:24 +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 4S7gnS1MCXz3TKq; Sun, 15 Oct 2023 13:19:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1697375964; 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=mhtpQh32UVpRtYhggTOLdnw1vOCP4XT3V6fNW4tXYos=; b=BXwGWUPy8ZAbeXuBkamCW9uuUek1BrLFFGCjJIbKrl7R/yUyKDZYyLBZnvz71XaS5JdSid CzJIk1WQOutpyPr4fBzIq36Wdvv+Rqs507efMyGq+XjjWOzD7sGpvjMXehiqGNNwdGWcnI Ajb5E5sxzn5Tk7DwqKTljc6yrjoLVlea78A99g+Xs6IrhmkfllKpNx9clUb4fxP9pzP+/1 g8t3vWzTcHhRGeq7CHNVgQkIh8AFmjZdUB9l+qkE+OHrF2/xJYZ+ApqCh5qN4uD9Mv8uJq fRdmjQ+9z1CblZPHyGLqgJR66P3EwBrrDvcvIKIFgCysNH+H5DTk9l2Su/D1kw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1697375964; a=rsa-sha256; cv=none; b=kadHk5h2+815VkcOwKlr8/Vb+wDk3RSvU2iDrLgIRSNFzDQu3gxyaTFGuulTDdS5JmHCi0 pq/h1S03R+/XwBEmkPhBakI4MF2isaoXhknltSnWf9hnOjX3O3oNI6P/IN5AmGKAxi1cJF cpLY1qORHOKrnLVsyW7Mn2wtPRORdqSn9+GT/0MD5vINJXbpEjwBkm4O/YIw6qIgLWAUlP X4TSrg7H1URpST/L97Huq+7X7q4Da7pa/hplC/JEyn+zRHFXPsyYtjNdS2XGfNyUpfpskB kQ7z1BRS82u1D1LeRLPePi7oQp9qqFPFS4b5jHEf+QCz8KNSfG3dKvZoClHJog== 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=1697375964; 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=mhtpQh32UVpRtYhggTOLdnw1vOCP4XT3V6fNW4tXYos=; b=SMlqKps8zrBKmWOMx0assb3K3Omcgal4qIqdXInn6o7W2dvgtQHnszp3SPxutvnAOJ9XfP p1mux8hv7c3Yc6AGBeymBXCSB5cXXIOqElOIsTU1PL6fHbrS9HAtuBK04U7kAgMwy71ILQ 1EcfWFIU6LgvnvHW/D+YPoAuBBrcrDEd14/EkDDXyCYcnUs/SMhqzIEZv2ciOiDIpg1dT6 F4f/CbV8YsZLq5y8M8BLMDd+n/0/pmkED+vcqcqTY4BoWn0FfrFejN1mQJQlHkoNtWdKJP eD4VJe92oCeFQ5vWOvHRftsASsZVRaIBMNIsGdW9+85NpW4/OBm6pfnQMi/6uQ== 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 4S7gnS0Jt2z1Crb; Sun, 15 Oct 2023 13:19:24 +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 39FDJNrR060064; Sun, 15 Oct 2023 13:19:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 39FDJNSW060061; Sun, 15 Oct 2023 13:19:23 GMT (envelope-from git) Date: Sun, 15 Oct 2023 13:19:23 GMT Message-Id: <202310151319.39FDJNSW060061@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: ec3864cc6861 - stable/13 - fusefs: sanitize FUSE_READLINK results for embedded NULs List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/13 X-Git-Reftype: branch X-Git-Commit: ec3864cc68617edb106724a6d423b47ec455e31b Auto-Submitted: auto-generated The branch stable/13 has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=ec3864cc68617edb106724a6d423b47ec455e31b commit ec3864cc68617edb106724a6d423b47ec455e31b Author: Alan Somers AuthorDate: 2023-10-04 18:48:01 +0000 Commit: Alan Somers CommitDate: 2023-10-15 13:02:07 +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 8fa60ff95d4c..988e7aa3278e 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -2022,6 +2022,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";