From nobody Sun Oct 15 02:13:09 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 4S7P0j33R4z4xXcL; Sun, 15 Oct 2023 02:13:09 +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 4S7P0j2YYwz3bFf; Sun, 15 Oct 2023 02:13:09 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1697335989; 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=IesMAGKIJivX4fHqnhncz720k/4B/qXW5Xslfv4KUM0=; b=F5W8CC97RO8sYdM400s0z9/NfEC0KTE/YbKAviB0XLrWXlzdndNw9fFbGSFtJgLhFTRfNe c6u4+o4UU/RLMrEwZnwysyC9xY1NaNvzxIjlOUlIcYWzLNXAzQiexdKU0BJmtlRBSVsQpO vOQnCeyWiVPxXIogz2yJgsH7wLCqBGRrwSVF4kqdp1JVG1s3EHYu9dniFuUzHEdiY1Wjee 1oAFwYLe7aKHgLJ/CtZjbqIl2cHu8o1eXQg/T54ZrLBGqRHjp6p5wPjQV/169FDOBfgSN0 LHRbNOjB6BDTdHgHe01Vi4n3dibuWcZHMeN9ThwhDCfIFqXNUwgGStBdL7JiFQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1697335989; a=rsa-sha256; cv=none; b=ugPIc7H+Ni6cclFntr4CeucyoS8HBtry6htIdbZbgfI35jS5cEZenlkrBSL2VxtYGhLDoD RJL/CQCEkStKqC3DML/bgcbZ3YNpxy9c6Fu1tbTH4vd3Hxr0PQAa40tUiEXs6hJWXu6aEl J+a7EENa7Vj/ix8itrYivwNkAO490rBqMiQv1CLzdUYFPrhcQaZEZsPxhkxgyANHj2+e7s DRET4YhS27/PFy1s5yElyy4iW8Z64F6xyFiT/eCeRJTCGIF2Npft7vvrQuKMFJbzdvZjQI 6LVpQ8HOco7hUg2ZsVZ3QEqs8atk3msYV5gXOpdKdDlG4YNv4U12XLtcLwbNWw== 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=1697335989; 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=IesMAGKIJivX4fHqnhncz720k/4B/qXW5Xslfv4KUM0=; b=Ht5+UOjgtlwJ225b+TeJps7/QxlfNUkGoPIFyOkqhN5Znrq2R/SnAlOUr9PbE+Yi1neUMj 0sbivSOiBxu3xt/rRa5HdxHVGoYC2XklrcD1jHhTr7YRkOqK0Ychh+3Z4VuQxFaKkrluiM iCXM7cjJn8x+mq2ahj65ySYBQ9mFObDKACb8relx0jW2/f2rlvqG9z+4vPTUTT2O5Gmkt1 KrSb7GsVsm4caOjkKl662SQuiGqICnZq7H2HNUohPYLb6Shky1BMO9+umExPO6dHMtu+ST i8Z1q46BOjw84dhZE6dmKRkFX0HBJci/Q+46GyhcY16F1V6Bpu8IH+80ifYPgQ== 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 4S7P0j1cdLzvcW; Sun, 15 Oct 2023 02:13:09 +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 39F2D9b3059475; Sun, 15 Oct 2023 02:13:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 39F2D9vl059472; Sun, 15 Oct 2023 02:13:09 GMT (envelope-from git) Date: Sun, 15 Oct 2023 02:13:09 GMT Message-Id: <202310150213.39F2D9vl059472@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: 0022bd418e6c - releng/14.0 - 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/releng/14.0 X-Git-Reftype: branch X-Git-Commit: 0022bd418e6c0c7c767a296a3e0d3782e5137dce Auto-Submitted: auto-generated The branch releng/14.0 has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=0022bd418e6c0c7c767a296a3e0d3782e5137dce commit 0022bd418e6c0c7c767a296a3e0d3782e5137dce Author: Alan Somers AuthorDate: 2023-10-04 18:48:01 +0000 Commit: Alan Somers CommitDate: 2023-10-15 02:13:05 +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 Approved by: gjb (re) Reviewed by: mjg, markj Differential Revision: https://reviews.freebsd.org/D42081 (cherry picked from commit 662ec2f781521c36b76af748d74bb0a3c2e27a76) (cherry picked from commit 8fca98f6881fdd68a786f4366c345159ab0df408) --- 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";