From patchwork Fri Jul 19 11:41:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13737220 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 042301E871 for ; Fri, 19 Jul 2024 11:42:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389349; cv=none; b=PQEf+kc5GArrDP/PzphCc6NJPIX2ozZBM58GWj3eBpj19CbdFUsSo42hAc8qGtBoV2yE/EGPcHj0W+wgT9bOi/qwk94Q4z5WKbD0fdAQZs1skRMiGVO6wwZY8s7moOcccR150r3voarJBnc+1dgHTjfwuu4x5yEtjq1aN0s5BZA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389349; c=relaxed/simple; bh=xqaxZx8Uc26vypiRSSMPInvBcBTGnfSI3euLzrmAsiU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UcLXe03rlWcty4x2gzMjNOCcPkLtpLnAXoaPzg8FFCffPPtXguHL/7LrERZjLdWI+7yRG1q3I76BYSj1RKuxtjGpbVlWriZrfWZTvaD111dLsLAEwrgmhfD+5RsU3CJyp615W5IFCx+fZpeLxHW8WOwcf9zzokmPo/7ea8RmCeg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PIXDPRF4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PIXDPRF4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CA11C4AF0E; Fri, 19 Jul 2024 11:42:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721389348; bh=xqaxZx8Uc26vypiRSSMPInvBcBTGnfSI3euLzrmAsiU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PIXDPRF4g/3K3sggt0VFREfOvjxV1tdr95QrC2HH5GLbA4co+61MLEJEixBEMYIVQ 2vKnTTeJA7LXBv58w9NC4HvIoTSgY76bXbIR1hmpH3gPMG+JXTB0AF4PNY55lG+T/v 4WCXV0A6QDIfcL+9tK3zqDaGZu1ffo/Ne9DpSCba4XOYzGewk4Hcd/c5mVAbWZWboQ xvK1Iu0GqMeFYmHYLXZl63JUM8DpaVzfJthQBbIqLgIacSus1QlbictdBn47o0gLKO HotdzD146USUKczxL58E9/0QN63kByVBeAvDev17aWNXJhSfzJVZ5YDGElu6joGaHw R0jYM7E/pm+MQ== From: Christian Brauner Date: Fri, 19 Jul 2024 13:41:48 +0200 Subject: [PATCH RFC 1/5] fs: use all available ids Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240719-work-mount-namespace-v1-1-834113cab0d2@kernel.org> References: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> In-Reply-To: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Karel Zak , Stephane Graber , Christian Brauner , Alexander Mikhalitsyn X-Mailer: b4 0.15-dev-13183 X-Developer-Signature: v=1; a=openpgp-sha256; l=811; i=brauner@kernel.org; h=from:subject:message-id; bh=xqaxZx8Uc26vypiRSSMPInvBcBTGnfSI3euLzrmAsiU=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTNClRQefH4g/Wzb1u8t1seUdQo+fsue8V2Pc8/JdJph hcKnzAFdZSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExk9gNGhhvse5dUXt0s2hly 3uH32+LzB+buC7Dh9ppZ15R/NyfxejvD/+Dti1v7uNh6nnE5qqcsEJjL9rn1rFZ/lkV0zIYJohI LGQE= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The counter is unconditionally incremented for each mount allocation. If we set it to 1ULL << 32 we're losing 4294967296 as the first valid non-32 bit mount id. Signed-off-by: Christian Brauner --- fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 221db9de4729..328087a4df8a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -70,7 +70,7 @@ static DEFINE_IDA(mnt_id_ida); static DEFINE_IDA(mnt_group_ida); /* Don't allow confusion with old 32bit mount ID */ -#define MNT_UNIQUE_ID_OFFSET (1ULL << 32) +#define MNT_UNIQUE_ID_OFFSET (1ULL << 31) static atomic64_t mnt_id_ctr = ATOMIC64_INIT(MNT_UNIQUE_ID_OFFSET); static struct hlist_head *mount_hashtable __ro_after_init; From patchwork Fri Jul 19 11:41:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13737221 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A2AC1E871 for ; Fri, 19 Jul 2024 11:42:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389351; cv=none; b=cV4vgv/zYtEbhVeXL9+55lVtwa3YQRSniG9qatZ0pisgNpjz/acco/h5RlAOmBT4RsTfXifAPYqQo7nCWQpft1h1YqBIfFFvzkv7bqN5+8oOI/5t6dikofnRmHcD13Rvy05xkBtgf8E/bnezhesuIYRMzo8caG7mRanwXHwmpDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389351; c=relaxed/simple; bh=eYH1Sx5+EFqZZPyMC2duPjER2h+z3VYs2/4svFke7lk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QY+HxNGlRuY1ST4EvCDQHbrr5Ybgurfx0xYhx/vJ9Q5M2/bQxRC/s4liBtHhW1cvgQomSDSfh+DTCPCSGmfpn0+6z6u8xBuVGMK+wU05XwZozYalnjis7jIv2LajaeuKPlHN2uy+DojVJ+O5O2hPYDk+eIwOW8m0fJ+e64uiR/c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NqCf4XjA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NqCf4XjA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 32910C4AF09; Fri, 19 Jul 2024 11:42:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721389350; bh=eYH1Sx5+EFqZZPyMC2duPjER2h+z3VYs2/4svFke7lk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NqCf4XjAFJ2Yky7U933md7kXdn/sBFVpvCmIhixVt9mU08Bpz/oD+fa7gQ7sLGbWN cb+3OVai4RNvE8LkWok8RRR5xc/0o71bKgOR4boFPXyQbUdFMkbfTF/oqCTrRnujlr dWmjmVdEQ5h3Ms1WPPAGVL+UGvrL1t081B89qWboNl9OJTEuHXxz+qFTWyZbt7enJd 8WMtKfzMDYhrWrjjlb7R33Mp75tOe39kqAr9bnsHYUr6dZ4cdzkkoDjY2Xiq/lUKNd NQQQb2VCxk8PU+m3ACFOWam94iFHCDfHHYWd0vE10QHXN0kXxNvZzGXU9P54ouj35a BGQpDcXlOHrqg== From: Christian Brauner Date: Fri, 19 Jul 2024 13:41:49 +0200 Subject: [PATCH RFC 2/5] fs: allow mount namespace fd Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240719-work-mount-namespace-v1-2-834113cab0d2@kernel.org> References: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> In-Reply-To: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Karel Zak , Stephane Graber , Christian Brauner , Alexander Mikhalitsyn X-Mailer: b4 0.15-dev-13183 X-Developer-Signature: v=1; a=openpgp-sha256; l=2096; i=brauner@kernel.org; h=from:subject:message-id; bh=eYH1Sx5+EFqZZPyMC2duPjER2h+z3VYs2/4svFke7lk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTNClRYW3XJLSHcYm1T/4nJV5c8jLz0zmr7hR6roIszh ea/vsiq2FHKwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjCRu78ZGZ7Gz5ijXe+/JvF6 YZmgr78ax6WAXQfftb2fU9W+T+iGRAgjQ3Pr+7kn3aQ3C/fsfFaepu/pupXTz49Z2XN984WLluf ZOAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 We already allow a mount namespace id, enable mount namespace file descriptors as well. Signed-off-by: Christian Brauner --- fs/namespace.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 328087a4df8a..3ee8adb7f215 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5243,12 +5243,37 @@ static int copy_mnt_id_req(const struct mnt_id_req __user *req, * that, or if not simply grab a passive reference on our mount namespace and * return that. */ -static struct mnt_namespace *grab_requested_mnt_ns(u64 mnt_ns_id) +static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq) { - if (mnt_ns_id) - return lookup_mnt_ns(mnt_ns_id); - refcount_inc(¤t->nsproxy->mnt_ns->passive); - return current->nsproxy->mnt_ns; + struct mnt_namespace *mnt_ns; + + if (kreq->mnt_ns_id && kreq->spare) + return ERR_PTR(-EINVAL); + + if (kreq->mnt_ns_id) + return lookup_mnt_ns(kreq->mnt_ns_id); + + if (kreq->spare) { + struct ns_common *ns; + + CLASS(fd, f)(kreq->spare); + if (!f.file) + return ERR_PTR(-EBADF); + + if (!proc_ns_file(f.file)) + return ERR_PTR(-EINVAL); + + ns = get_proc_ns(file_inode(f.file)); + if (ns->ops->type != CLONE_NEWNS) + return ERR_PTR(-EINVAL); + + mnt_ns = to_mnt_ns(ns); + } else { + mnt_ns = current->nsproxy->mnt_ns; + } + + refcount_inc(&mnt_ns->passive); + return mnt_ns; } SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, @@ -5269,7 +5294,7 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, if (ret) return ret; - ns = grab_requested_mnt_ns(kreq.mnt_ns_id); + ns = grab_requested_mnt_ns(&kreq); if (!ns) return -ENOENT; @@ -5396,7 +5421,7 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, if (!kmnt_ids) return -ENOMEM; - ns = grab_requested_mnt_ns(kreq.mnt_ns_id); + ns = grab_requested_mnt_ns(&kreq); if (!ns) return -ENOENT; From patchwork Fri Jul 19 11:41:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13737222 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED54A1E871 for ; Fri, 19 Jul 2024 11:42:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389353; cv=none; b=mjKkKqe+uUpMUFUo65My1Me0ofHYiCXOD3QPHfXL7xfoYsIbfqilWPGsnCdFVbBTHn3ql7slKFvQqw74tE+Swb4vZHKBkfY1deeNVZr6aQPI7ih8yYutv/L85B8axfPDydnATE2pOPQXoCv4yEHGAuyCPjNJkXJ4UPqPYvvUqxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389353; c=relaxed/simple; bh=/UKV6eRiJx+RO3FmnB52Qrdd8JuCnRCdyfSUmERu0Io=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HnYA5RVpX3i6BZYEVUHX+/w4JNiHsh46uOfkTMTAmWQWuAcn3ZbKeRpP66uUY4mobRJSs61cRjoRoUa9EEv06G2Lx5SuMBtu4Mvsh6U1OgUfbvfL/l9x+9MPf3+z6Yg/ZmhZIcCMFK+ZTjJcue90AJNylxxdVgrBc/+wrRiLQZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ewNfkBay; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ewNfkBay" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3F351C32782; Fri, 19 Jul 2024 11:42:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721389352; bh=/UKV6eRiJx+RO3FmnB52Qrdd8JuCnRCdyfSUmERu0Io=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ewNfkBayxkna3D1pU+CIqu/78kJAyETd55KNqIP/zZojIOxnRx93R5tQRtOjXWqaT 1aBkmO0fO9v+WhfhlJxmxZMNPdQrqEuTmfBmT8RV3gWfZbEBU5FU8L+UBFslAFn8Pf f7CZRjZX1EIGRJqlcTRTvSvELt36z6S4CBpaf4WdyvvKtadqY8CqrseZMdlS03qsZy FWYG0G2s6h415iAEso0eziGYLlIZ47CMZstWqcmWxKgW5Kd/LTrb7FptAmM9++Af2k oZicOH43Jrc8aAzoO6cwtOUhiHwR3ey2b1tXLr+flGR3hf8KltJw1JGTqPdw3bi6pf b9IwtTcGMzOpg== From: Christian Brauner Date: Fri, 19 Jul 2024 13:41:50 +0200 Subject: [PATCH RFC 3/5] fs: add put_mnt_ns() cleanup helper Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240719-work-mount-namespace-v1-3-834113cab0d2@kernel.org> References: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> In-Reply-To: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Karel Zak , Stephane Graber , Christian Brauner , Alexander Mikhalitsyn X-Mailer: b4 0.15-dev-13183 X-Developer-Signature: v=1; a=openpgp-sha256; l=1033; i=brauner@kernel.org; h=from:subject:message-id; bh=/UKV6eRiJx+RO3FmnB52Qrdd8JuCnRCdyfSUmERu0Io=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTNClTw2bH1xZsW7xwjhwa3LWtsJdMvHfm/5ZrqxI9qD 0+ntbxs6ihlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhI+H6Gf7bPDk93nZ4/uW45 m4H62xsf1vf/sOeaV/PBUSZU5+SB1VsZGXrCXxVlvsjcoGXWKuNwmrvhku3u9m3JW8XTc3X1Hlj EcwMA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a simple helper to put a mount namespace reference. Signed-off-by: Christian Brauner --- include/linux/mnt_namespace.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h index 8f882f5881e8..70b366b64816 100644 --- a/include/linux/mnt_namespace.h +++ b/include/linux/mnt_namespace.h @@ -3,6 +3,9 @@ #define _NAMESPACE_H_ #ifdef __KERNEL__ +#include +#include + struct mnt_namespace; struct fs_struct; struct user_namespace; @@ -11,6 +14,7 @@ struct ns_common; extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, struct user_namespace *, struct fs_struct *); extern void put_mnt_ns(struct mnt_namespace *ns); +DEFINE_FREE(put_mnt_ns, struct mnt_namespace *, if (!IS_ERR_OR_NULL(_T)) put_mnt_ns(_T)) extern struct ns_common *from_mnt_ns(struct mnt_namespace *); extern const struct file_operations proc_mounts_operations; From patchwork Fri Jul 19 11:41:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13737223 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81F7A85931 for ; Fri, 19 Jul 2024 11:42:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389355; cv=none; b=bxnXeGkLkg2ztAdM+5/ay0gU85TfrOUBCn8JfVp2bHiWNew9bnhiCOpoGlQkpnplouJfnSt6RoJCdVpbci1HxaHlH6+tDeToDDidnxexT35MXtdR3zgppu7hC2ZjvzJnCwTvS5NqDyKPdFh/v63MFFuA2pXlsCMskg3O1Y/IpHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389355; c=relaxed/simple; bh=UdvVua2f64s/hO0aTGtXb1syPtlODuVi7B1i/6pCVYc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=t7lBa4EXA7nhSUcmcdmsiUH3dTWSznCbM8AA31cNdw9lrZLKBL5DBcdKSFv7eaLYuFhufKsCCxRhmH3c0Y8d0lgKWg4A4PVgYY7vehm57apmeZRsp8oDdxpO96HZnoX1ksuJKzQWNqqNKdqzfsHJRuehbJ23XcP6IR5srmRQumM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cpt01EdN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cpt01EdN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6129BC4AF09; Fri, 19 Jul 2024 11:42:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721389355; bh=UdvVua2f64s/hO0aTGtXb1syPtlODuVi7B1i/6pCVYc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cpt01EdN4luc4A+i8Mv2Rw+fZ78xyNEcoBf5N0hcFgVwqEVDuA2UFfAZXBeyBXOyV v2L1LTtojpAN6t/PO7YidPtKlYhokXaDdAuQNvVgrP/JoyC3uUDgn3pnKz2qXlNliV AAkHZdH/N9LXCmQ7D38nwLAg5dzf017Oq117WeWfU4h0a5Tq2381/9RS7gl2zI6Amx wofBPYq9W3MT62jFh5WOpOQu3aNzP5yASEa2wDsjCc11zkQfmUjlTsFleQN3ZZZCd4 oSAPH47eKKc/M+1sJzoWPjkB3RQaVwZbxpMooMI4x/eySjfsH102S9yjWAq4Nmy+Lw YWPmj6oo9eV7Q== From: Christian Brauner Date: Fri, 19 Jul 2024 13:41:51 +0200 Subject: [PATCH RFC 4/5] file: add fput() cleanup helper Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240719-work-mount-namespace-v1-4-834113cab0d2@kernel.org> References: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> In-Reply-To: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Karel Zak , Stephane Graber , Christian Brauner , Alexander Mikhalitsyn X-Mailer: b4 0.15-dev-13183 X-Developer-Signature: v=1; a=openpgp-sha256; l=826; i=brauner@kernel.org; h=from:subject:message-id; bh=UdvVua2f64s/hO0aTGtXb1syPtlODuVi7B1i/6pCVYc=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTNClRYV7l5815GMb3nF37JLMuINvD/ljbRYc2/WWKue hHata1aHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABM5HcHwm+Whazmb14XbsUpr N/R+97fRbWPqWvuSI1p1zRSrVD3HBkaGH6scfl+R9lLe7J4fdXj2xDVczIG3LEzEfb86JBdMWm3 JCwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a simple helper to put a file reference. Signed-off-by: Christian Brauner --- include/linux/file.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/file.h b/include/linux/file.h index 237931f20739..d1e768b06069 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -11,6 +11,7 @@ #include #include #include +#include struct file; @@ -96,6 +97,7 @@ extern void put_unused_fd(unsigned int fd); DEFINE_CLASS(get_unused_fd, int, if (_T >= 0) put_unused_fd(_T), get_unused_fd_flags(flags), unsigned flags) +DEFINE_FREE(fput, struct file *, if (!IS_ERR_OR_NULL(_T)) fput(_T)) /* * take_fd() will take care to set @fd to -EBADF ensuring that From patchwork Fri Jul 19 11:41:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13737224 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6341012C530 for ; Fri, 19 Jul 2024 11:42:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389357; cv=none; b=NAy/hVdvrfmTcqGJYvBmYCMFpVdSV5cfGVcVz8X/RNJiDfTaIW2Oklq2kC3hw/JeEg+G7+bFFlkrsh3/52E6v8DHufJGg0s72mOY284Koq77tM5fVNp9IViNAJGYSKSNZppsMJcGQKf3xjvOzOWvgw+RrkVQmbx/TP5ZlCVCA8k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721389357; c=relaxed/simple; bh=JiWYFxjv3zJ/IBNPWasmdceg7hk4TriYPu4AN062EIs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=q6egMxM5qgG0H5GLlesjciYlmpboqROtgxYHeuOi5+dqAF1hblek6YP5F1NYnkCiKdYQyY/usoogoWkxxE3pouOyPwk76EZsZQcuMyLgYtgxg62v5h4ryQB/gHHA+2T338R/UANA8NlGcJGWgwtGvS7UHSnI7rAZzOjlVSePq68= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OwlTpSnE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OwlTpSnE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9EF7DC4AF0A; Fri, 19 Jul 2024 11:42:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721389357; bh=JiWYFxjv3zJ/IBNPWasmdceg7hk4TriYPu4AN062EIs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OwlTpSnEusfqU1qCe5b5OU0YjrDymgSzP6Vt/BEqXiKFL7jEtiONtekn63pTOChCD FVkkY32b9bPGWPAfAiLjEl5gEsiiQDCvt32PqsDVNFxrh4e9niWmyTv33iNACB1zwS KvOswxzol7bMxraBwrLJk/6hTHorvgxIVo7HVH0FSyiAQjxe18o35xnHjCxyJCcXg6 kJRVyYoMsD237Y6MZs2VeP9cccHLpwIUpQv8ImJKRrEfvT9CBwo0goJTmBR2e57pBP btafFVJRAlqMhoIYgZDQhkbXQAFdAgAVCEOTLIKutzTU9qL12USaubnbJOgOv9NTCy d8n7R/y+Z7+CA== From: Christian Brauner Date: Fri, 19 Jul 2024 13:41:52 +0200 Subject: [PATCH RFC 5/5] nsfs: iterate through mount namespaces Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240719-work-mount-namespace-v1-5-834113cab0d2@kernel.org> References: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> In-Reply-To: <20240719-work-mount-namespace-v1-0-834113cab0d2@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Karel Zak , Stephane Graber , Christian Brauner , Alexander Mikhalitsyn X-Mailer: b4 0.15-dev-13183 X-Developer-Signature: v=1; a=openpgp-sha256; l=8889; i=brauner@kernel.org; h=from:subject:message-id; bh=JiWYFxjv3zJ/IBNPWasmdceg7hk4TriYPu4AN062EIs=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTNClSwFD+X//7nNWnLcHGd4xtLk9RnmHCIbXLc13j8X lNJjvLcjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIl8mMLIsLr+9dUJR3t1XRZo 7LjKxGex9Y2NC3fW5xMSQrMOevOUqTIyzFaL7Nj8dt20pb0Wh+Rez/IMtm8I+rI3gO8Up/Yaozs l7AA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 It is already possible to list mounts in other mount namespaces and to retrieve namespace file descriptors without having to go through procfs by deriving them from pidfds. Augment these abilities by adding the ability to retrieve information about a mount namespace via NS_MNT_GET_INFO. This will return the mount namespace id and the number of mounts currently in the mount namespace. The number of mounts can be used to size the buffer that needs to be used for listmount() and is in general useful without having to actually iterate through all the mounts. The structure is extensible. And add the ability to iterate through all mount namespaces over which the caller holds privilege returning the file descriptor for the next or previous mount namespace. To retrieve a mount namespace the caller must be privileged wrt to it's owning user namespace. This means that PID 1 on the host can list all mounts in all mount namespaces or that a container can list all mounts of its nested containers. Optionally pass a structure for NS_MNT_GET_INFO with NS_MNT_GET_{PREV,NEXT} to retrieve information about the mount namespace in one go. Both ioctls can be implemented for other namespace types easily. Together with recent api additions this means one can iterate through all mounts in all mount namespaces without ever touching procfs. Signed-off-by: Christian Brauner --- fs/mount.h | 13 ++++++ fs/namespace.c | 35 ++++++++++++++-- fs/nsfs.c | 102 +++++++++++++++++++++++++++++++++++++++++++++- include/uapi/linux/nsfs.h | 15 +++++++ 4 files changed, 159 insertions(+), 6 deletions(-) diff --git a/fs/mount.h b/fs/mount.h index ad4b1ddebb54..c1db0c709c6a 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -155,3 +155,16 @@ static inline void move_from_ns(struct mount *mnt, struct list_head *dt_list) extern void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor); bool has_locked_children(struct mount *mnt, struct dentry *dentry); +struct mnt_namespace *__lookup_next_mnt_ns(struct mnt_namespace *mnt_ns, bool previous); +static inline struct mnt_namespace *lookup_next_mnt_ns(struct mnt_namespace *mntns) +{ + return __lookup_next_mnt_ns(mntns, false); +} +static inline struct mnt_namespace *lookup_prev_mnt_ns(struct mnt_namespace *mntns) +{ + return __lookup_next_mnt_ns(mntns, true); +} +static inline struct mnt_namespace *to_mnt_ns(struct ns_common *ns) +{ + return container_of(ns, struct mnt_namespace, ns); +} diff --git a/fs/namespace.c b/fs/namespace.c index 3ee8adb7f215..60e20f15e87e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2060,14 +2060,41 @@ static bool is_mnt_ns_file(struct dentry *dentry) dentry->d_fsdata == &mntns_operations; } -static struct mnt_namespace *to_mnt_ns(struct ns_common *ns) +struct ns_common *from_mnt_ns(struct mnt_namespace *mnt) { - return container_of(ns, struct mnt_namespace, ns); + return &mnt->ns; } -struct ns_common *from_mnt_ns(struct mnt_namespace *mnt) +struct mnt_namespace *__lookup_next_mnt_ns(struct mnt_namespace *mntns, bool previous) { - return &mnt->ns; + guard(read_lock)(&mnt_ns_tree_lock); + for (;;) { + struct rb_node *node; + + if (previous) + node = rb_prev(&mntns->mnt_ns_tree_node); + else + node = rb_next(&mntns->mnt_ns_tree_node); + if (!node) + return ERR_PTR(-ENOENT); + + mntns = node_to_mnt_ns(node); + node = &mntns->mnt_ns_tree_node; + + if (!ns_capable_noaudit(mntns->user_ns, CAP_SYS_ADMIN)) + continue; + + /* + * Holding mnt_ns_tree_lock prevents the mount namespace from + * being freed but it may well be on it's deathbed. We want an + * active reference, not just a passive one here as we're + * persisting the mount namespace. + */ + if (!refcount_inc_not_zero(&mntns->ns.count)) + continue; + + return mntns; + } } static bool mnt_ns_loop(struct dentry *dentry) diff --git a/fs/nsfs.c b/fs/nsfs.c index 97c37a9631e5..67ee176b8824 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "mount.h" #include "internal.h" @@ -128,6 +129,30 @@ int open_related_ns(struct ns_common *ns, } EXPORT_SYMBOL_GPL(open_related_ns); +static int copy_ns_info_to_user(const struct mnt_namespace *mnt_ns, + struct mnt_ns_info __user *uinfo, size_t usize, + struct mnt_ns_info *kinfo) +{ + /* + * If userspace and the kernel have the same struct size it can just + * be copied. If userspace provides an older struct, only the bits that + * userspace knows about will be copied. If userspace provides a new + * struct, only the bits that the kernel knows aobut will be copied and + * the size value will be set to the size the kernel knows about. + */ + kinfo->size = min(usize, sizeof(*kinfo)); + kinfo->mnt_ns_id = mnt_ns->seq; + kinfo->nr_mounts = READ_ONCE(mnt_ns->nr_mounts); + /* Subtract the root mount of the mount namespace. */ + if (kinfo->nr_mounts) + kinfo->nr_mounts--; + + if (copy_to_user(uinfo, kinfo, kinfo->size)) + return -EFAULT; + + return 0; +} + static long ns_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -135,6 +160,8 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl, struct pid_namespace *pid_ns; struct task_struct *tsk; struct ns_common *ns = get_proc_ns(file_inode(filp)); + struct mnt_namespace *mnt_ns; + bool previous = false; uid_t __user *argp; uid_t uid; int ret; @@ -156,7 +183,6 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl, uid = from_kuid_munged(current_user_ns(), user_ns->owner); return put_user(uid, argp); case NS_GET_MNTNS_ID: { - struct mnt_namespace *mnt_ns; __u64 __user *idp; __u64 id; @@ -211,7 +237,79 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl, if (!ret) ret = -ESRCH; - break; + return ret; + } + } + + /* extensible ioctls */ + switch (_IOC_NR(ioctl)) { + case _IOC_NR(NS_MNT_GET_INFO): { + struct mnt_ns_info kinfo = {}; + struct mnt_ns_info __user *uinfo = (struct mnt_ns_info __user *)arg; + size_t usize = _IOC_SIZE(ioctl); + + if (ns->ops->type != CLONE_NEWNS) + return -EINVAL; + + if (!uinfo) + return -EINVAL; + + if (usize < MNT_NS_INFO_SIZE_VER0) + return -EINVAL; + + return copy_ns_info_to_user(to_mnt_ns(ns), uinfo, usize, &kinfo); + } + case _IOC_NR(NS_MNT_GET_PREV): + previous = true; + fallthrough; + case _IOC_NR(NS_MNT_GET_NEXT): { + struct mnt_ns_info kinfo = {}; + struct mnt_ns_info __user *uinfo = (struct mnt_ns_info __user *)arg; + struct path path __free(path_put) = {}; + struct file *f __free(fput) = NULL; + size_t usize = _IOC_SIZE(ioctl); + + if (ns->ops->type != CLONE_NEWNS) + return -EINVAL; + + if (usize < MNT_NS_INFO_SIZE_VER0) + return -EINVAL; + + if (previous) + mnt_ns = lookup_prev_mnt_ns(to_mnt_ns(ns)); + else + mnt_ns = lookup_next_mnt_ns(to_mnt_ns(ns)); + if (IS_ERR(mnt_ns)) + return PTR_ERR(mnt_ns); + + ns = to_ns_common(mnt_ns); + /* Transfer ownership of @mnt_ns reference to @path. */ + ret = path_from_stashed(&ns->stashed, nsfs_mnt, ns, &path); + if (ret) + return ret; + + CLASS(get_unused_fd, fd)(O_CLOEXEC); + if (fd < 0) + return fd; + + f = dentry_open(&path, O_RDONLY, current_cred()); + if (IS_ERR(f)) + return PTR_ERR(f); + + if (uinfo) { + /* + * If @uinfo is passed return all information about the + * mount namespace as well. + */ + ret = copy_ns_info_to_user(to_mnt_ns(ns), uinfo, usize, &kinfo); + if (ret) + return ret; + } + + /* Transfer reference of @f to caller's fdtable. */ + fd_install(fd, no_free_ptr(f)); + /* File descriptor is live so hand it off to the caller. */ + return take_fd(fd); } default: ret = -ENOTTY; diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h index b133211331f6..bfb9666860a1 100644 --- a/include/uapi/linux/nsfs.h +++ b/include/uapi/linux/nsfs.h @@ -26,4 +26,19 @@ /* Return thread-group leader id of pid in the target pid namespace. */ #define NS_GET_TGID_IN_PIDNS _IOR(NSIO, 0x9, int) +struct mnt_ns_info { + __u32 size; + __u32 nr_mounts; + __u64 mnt_ns_id; +}; + +#define MNT_NS_INFO_SIZE_VER0 16 /* size of first published struct */ + +/* Get information about namespace. */ +#define NS_MNT_GET_INFO _IOR(NSIO, 10, struct mnt_ns_info) +/* Get next namespace. */ +#define NS_MNT_GET_NEXT _IOR(NSIO, 11, struct mnt_ns_info) +/* Get previous namespace. */ +#define NS_MNT_GET_PREV _IOR(NSIO, 12, struct mnt_ns_info) + #endif /* __LINUX_NSFS_H */