From nobody Fri Jan 06 09:46:33 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 4NpJQ14N0Qz2pCvT; Fri, 6 Jan 2023 09:46:33 +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 4NpJQ13czpz3wWw; Fri, 6 Jan 2023 09:46:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1672998393; 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=ufiB6rqXBDDj+EVNQMU8t9RgMxJZ4n9/8ZRulOLz7ZA=; b=Qe9QLw+IQoUGd8Uf5xKoSoov6WKm45xKJ3+vY+1YM4oPkHXOOqlAmuC3nqHJonQjsi4uTO UzXTxtAB1b3n8gXvSzfZbbwWR8LjNZvrDrworyOth7n/1yWpVrQOHHEk8o2JjN5L537/PK UbhdxMR/uMYku+f8Q7dPCofopZ8XkOcZH+4ef9KI3Dz2ayi4qw1+WWl1sz0S7ig62FcAHu znZTwN3Ci7fnQQjkHHTHzZ3+w8zqiH3jWFc7XPehQYi0zkd2LCi6BUvv0BKUuAssHSiaNT JV1prCXxQHN/j7dbAI9MWpcIOYgMTeC8g2jf5tlYJ8zvmq76OKsO5a2o6KNy2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1672998393; 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=ufiB6rqXBDDj+EVNQMU8t9RgMxJZ4n9/8ZRulOLz7ZA=; b=ttyt+6lGHsUOyEmpVvZkRLRBSa/sbKtUiUJhM4Yo+lbryp21qs+kFqCO6srPjpyaPYfOEd g0/IxniX/QKfMjwTCPXoWMs/EPVS5WKstUY0ZZ1ioE+muRUV69GdfAD/390Wz0WB2wGjVX bS9OQwwNuTMw/kjBaUSC5P65gQ5Wxn/Pi6a9aBkEvi5s5s6BR/OTsRAyRYJC9ERXRKBt3H 0gEQ6SJ7dR04N0bd1EidV7DEdGJV2XgZzpp78FrH1CiGIv+10s7uFnkwpc05QkwDLX/E+A T5NWrKOuDgI3q8bC8UhXunyKzgqt2Kqe+KQ0JhtObYDhxJBG+nRQoVrzk6avSQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1672998393; a=rsa-sha256; cv=none; b=JBn7SyrKot3huy8HNomZeOd+wqH6kRx+5wSEzYRFFreRABxOzkqY1AO11SrMeTJarJZn1u Zfn0vpmzdyYGszhVg6IVPCdViyK4hwqhWXQ7DsWw8xT+ccu6dEJsl2cZK4QgDgE3cTXtpQ ojHPxe2cSKTyB/25WGefy5AjyNf49I+XYs2KwBkCiWreev5u4DReT/gSNYly8ThJ9Of8pc 3IoS8c4q/bFSbG2JlnPbRqX+G4Pn4cvm7pS0BM8BVmaCDWmA2mUXXcvBmn7QNSM/k2trMT nIWVE5tkBk0HrzZ1TyYNnbChK7qms9DjzqMRkWLrLcG1L8adKNfQ/9dhhRF+ww== 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 4NpJQ12h0gzQGn; Fri, 6 Jan 2023 09:46:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 3069kXnM090461; Fri, 6 Jan 2023 09:46:33 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 3069kXeq090460; Fri, 6 Jan 2023 09:46:33 GMT (envelope-from git) Date: Fri, 6 Jan 2023 09:46:33 GMT Message-Id: <202301060946.3069kXeq090460@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Doug Rabson Subject: git: d373650a5397 - stable/13 - Add support for mounting single files in nullfs 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: dfr X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: d373650a53977de4aba1da737525bd37eeba72ca Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by dfr: URL: https://cgit.FreeBSD.org/src/commit/?id=d373650a53977de4aba1da737525bd37eeba72ca commit d373650a53977de4aba1da737525bd37eeba72ca Author: Doug Rabson AuthorDate: 2022-11-23 14:51:13 +0000 Commit: Doug Rabson CommitDate: 2023-01-06 07:57:57 +0000 Add support for mounting single files in nullfs The main use-case for this is to support mounting config files and secrets into OCI containers. My current workaround copies the files into the container which is messy and risks secrets leaking into container images if the cleanup fails. This adds a VFCF flag to indicate whether the filesystem supports file mounts and allows fspath to be either a directory or a file if the flag is set. Test Plan: $ sudo mkdir -p /mnt $ sudo touch /mnt/foo $ sudo mount -t nullfs /COPYRIGHT /mnt/foo Reviewed by: mjg, kib Tested by: pho (cherry picked from commit 521fbb722c33663cf00a83bca70ad7cb790687b3) --- sys/fs/nullfs/null_vfsops.c | 13 ++++++++++++- sys/kern/vfs_lookup.c | 4 ++-- sys/kern/vfs_mount.c | 32 ++++++++++++++++++++++++++------ sys/sys/mount.h | 1 + 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c index 0bb98072edf4..1a83973313b1 100644 --- a/sys/fs/nullfs/null_vfsops.c +++ b/sys/fs/nullfs/null_vfsops.c @@ -156,6 +156,17 @@ nullfs_mount(struct mount *mp) } } + /* + * Lower vnode must be the same type as the covered vnode - we + * don't allow mounting directories to files or vice versa. + */ + if ((lowerrootvp->v_type != VDIR && lowerrootvp->v_type != VREG) || + lowerrootvp->v_type != mp->mnt_vnodecovered->v_type) { + NULLFSDEBUG("nullfs_mount: target must be same type as fspath"); + vput(lowerrootvp); + return (EINVAL); + } + xmp = (struct null_mount *) malloc(sizeof(struct null_mount), M_NULLFSMNT, M_WAITOK | M_ZERO); @@ -467,4 +478,4 @@ static struct vfsops null_vfsops = { .vfs_unlink_lowervp = nullfs_unlink_lowervp, }; -VFS_SET(null_vfsops, nullfs, VFCF_LOOPBACK | VFCF_JAIL); +VFS_SET(null_vfsops, nullfs, VFCF_LOOPBACK | VFCF_JAIL | VFCF_FILEMOUNT); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index bbceced68e50..3ded2180ac82 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -1154,8 +1154,8 @@ good: * Check to see if the vnode has been mounted on; * if so find the root of the mounted filesystem. */ - while (dp->v_type == VDIR && (mp = dp->v_mountedhere) && - (cnp->cn_flags & NOCROSSMOUNT) == 0) { + while ((dp->v_type == VDIR || dp->v_type == VREG) && + (mp = dp->v_mountedhere) && (cnp->cn_flags & NOCROSSMOUNT) == 0) { if (vfs_busy(mp, 0)) continue; vput(dp); diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index d17e1c7fbbd7..038ace288729 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -962,8 +962,13 @@ vfs_domount_first( error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN); if (error == 0) error = vinvalbuf(vp, V_SAVE, 0, 0); - if (error == 0 && vp->v_type != VDIR) - error = ENOTDIR; + if (vfsp->vfc_flags & VFCF_FILEMOUNT) { + if (error == 0 && vp->v_type != VDIR && vp->v_type != VREG) + error = EINVAL; + } else { + if (error == 0 && vp->v_type != VDIR) + error = ENOTDIR; + } if (error == 0 && (fsflags & MNT_EMPTYDIR) != 0) error = vfs_emptydir(vp); if (error == 0) { @@ -1376,22 +1381,33 @@ vfs_domount( /* * Get vnode to be covered or mount point's vnode in case of MNT_UPDATE. */ - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1 | WANTPARENT, UIO_SYSSPACE, fspath, td); error = namei(&nd); if (error != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; if ((fsflags & MNT_UPDATE) == 0) { if ((vp->v_vflag & VV_ROOT) != 0 && (fsflags & MNT_NOCOVER) != 0) { vput(vp); - return (EBUSY); + error = EBUSY; + goto out; } pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); strcpy(pathbuf, fspath); - error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN); + /* + * Note: we allow any vnode type here. If the path sanity check + * succeeds, the type will be validated in vfs_domount_first + * above. + */ + if (vp->v_type == VDIR) + error = vn_path_to_global_path(td, vp, pathbuf, + MNAMELEN); + else + error = vn_path_to_global_path_hardlink(td, vp, + nd.ni_dvp, pathbuf, MNAMELEN, + nd.ni_cnd.cn_nameptr, nd.ni_cnd.cn_namelen); if (error == 0) { error = vfs_domount_first(td, vfsp, pathbuf, vp, fsflags, optlist); @@ -1400,6 +1416,10 @@ vfs_domount( } else error = vfs_domount_update(td, vp, fsflags, optlist); +out: + NDFREE(&nd, NDF_ONLY_PNBUF); + vrele(nd.ni_dvp); + return (error); } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 0e7ecd646964..6e988a48922e 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -648,6 +648,7 @@ struct ovfsconf { #define VFCF_DELEGADMIN 0x00800000 /* supports delegated administration */ #define VFCF_SBDRY 0x01000000 /* Stop at Boundary: defer stop requests to kernel->user (AST) transition */ +#define VFCF_FILEMOUNT 0x02000000 /* allow mounting files */ typedef uint32_t fsctlop_t;