From nobody Wed Sep 10 23:39:17 2025 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 3985732A80C; Wed, 10 Sep 2025 14:37:11 +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=1757515031; cv=none; b=Kx7SCTi/VDOZawHYoJN/COwd4zXdEc8Sug1BNURdlyHiPN6ZDdUkhSNhlQ8QJJ6oDCCUqLl449/e4rlmonicYVwk3oP+7C9znu1w2HIwEymMWSENX8remhQuZHgi6GiSfAgORISERzyTqRGDvX3N0d4zH/mFCqpIe5/1YRKApRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515031; c=relaxed/simple; bh=dcXgRxvD4Lbzl66IOipe3Yjd7eUcYeh/PyxSo3B1aCE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OHPQqhnDd+eUgE0tF0mjbwNvp528LXeLZtB5K3UkXR7nMShUG/Zu7Uylm5H4ItoNJ+57CcovyPimhjIq95O/XAfT5UziQAGDRrW+aNTX69L0ZUkuIwnc9oVWGY+MI4XhW34Qv6u1Fx6sEtcioLTgkHKcEF6S1odZIYROLz1nrvE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uUi0NwHX; 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="uUi0NwHX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1DEEEC4CEF0; Wed, 10 Sep 2025 14:37:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515031; bh=dcXgRxvD4Lbzl66IOipe3Yjd7eUcYeh/PyxSo3B1aCE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uUi0NwHXAELciPrrvG/LmCCu646U1f9tXLk2Y8ur4dugGN1rdEsTIcwZ9ZSLPwKjm dQwZc43gnWQzlYZf1NWaRPxapfPv121fFnx43DyF25bXTgk8sKBjyn0lATDbR6WKKc /ZMiD8bmRtaLPak0OeZe131hqzvCHJKPYiX36OCmhC0j0CRDiJFHxdvxe0rcixwZpk XECS7bkrU/X24Uix6mFq1sTw14jMkKCXevKU/L2/aDPixqmKPVtAds/l4N+6ogPLOD rxIDwQgUwms/PXrAjgMfzPZIEp+FrRlCxe392EwyAd5OW4SUnG1luStIb3iP4Z/clA molJK5GAVfycQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:46 +0200 Subject: [PATCH 01/32] pidfs: validate extensible ioctls Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-1-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1442; i=brauner@kernel.org; h=from:subject:message-id; bh=dcXgRxvD4Lbzl66IOipe3Yjd7eUcYeh/PyxSo3B1aCE=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7GWfm/e37OokHfmHf6Ys5InXvawUHP5ZoMNmY1cqo +Oz+8tCO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACby+Q8jwzW33TePqJpsP6zB 9u7qhSv2k/K1KwL8fsmnml/Vd1WbPoOR4UDr4ms7U97Ob0qRjn9iZHZItuhrnOpZm0apQwtaDp8 x4wMA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Validate extensible ioctls stricter than we do now. Signed-off-by: Christian Brauner Reviewed-by: Aleksa Sarai Reviewed-by: Jan Kara --- fs/pidfs.c | 2 +- include/linux/fs.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/fs/pidfs.c b/fs/pidfs.c index edc35522d75c..0a5083b9cce5 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -440,7 +440,7 @@ static bool pidfs_ioctl_valid(unsigned int cmd) * erronously mistook the file descriptor for a pidfd. * This is not perfect but will catch most cases. */ - return (_IOC_TYPE(cmd) =3D=3D _IOC_TYPE(PIDFD_GET_INFO)); + return extensible_ioctl_valid(cmd, PIDFD_GET_INFO, PIDFD_INFO_SIZE_VER0); } =20 return false; diff --git a/include/linux/fs.h b/include/linux/fs.h index d7ab4f96d705..2f2edc53bf3c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -4023,4 +4023,18 @@ static inline bool vfs_empty_path(int dfd, const cha= r __user *path) =20 int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter); =20 +static inline bool extensible_ioctl_valid(unsigned int cmd_a, + unsigned int cmd_b, size_t min_size) +{ + if (_IOC_DIR(cmd_a) !=3D _IOC_DIR(cmd_b)) + return false; + if (_IOC_TYPE(cmd_a) !=3D _IOC_TYPE(cmd_b)) + return false; + if (_IOC_NR(cmd_a) !=3D _IOC_NR(cmd_b)) + return false; + if (_IOC_SIZE(cmd_a) < min_size) + return false; + return true; +} + #endif /* _LINUX_FS_H */ --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 BA4C132A82D; Wed, 10 Sep 2025 14:37:17 +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=1757515037; cv=none; b=T90s/wEw8TvIlvtODYFxqmZZZ9PvQz9LmiLaqD1+QQoaM0AzHuZmldhaVBXdNvscvAh35VyERGjIC1GXbB6JRmQ6nYZyupRnR+8PIUHITWD1ZOoEDRdkEshpd2FCfBb3wKAy/4naHhRZYm++yQGcauqWbriiK/jBlk+JTNVhR2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515037; c=relaxed/simple; bh=4DSLJ0TDAmWPOipYbwhpaBlzGQi13TeCv46x7pWryak=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oIdL15ZNw/vPdX0m4DX88RGM57xCJ10qOYz9A7ltFOan84JTgRnPajB3paijUGPxxV4Ize2pk1cOr0w+7XB3iaN89GL3W1zb46kovuu4HCUceQKNaRngmWGq21blUP6/w+GC1VgQyITAtb04WYb3X+TpnkWlRAkmJuxJf8TXZf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hrNBqVHE; 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="hrNBqVHE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8CFC2C4CEF0; Wed, 10 Sep 2025 14:37:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515037; bh=4DSLJ0TDAmWPOipYbwhpaBlzGQi13TeCv46x7pWryak=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hrNBqVHEvwgF0wc0JzWFTb221izubC5GRAtDH4r7Ox9sdt++1A/9lpm+bTW6LY0NR LnFpU9QqhJv92ZgNdk5rNUor4wk9DZO+Rr7It0GNC3UIYslfyIKztzEU9JkUFPi6Ww Y9sV7OMaslefEkRtbbwyYwdQJ0tMIRSv8rG9GCGKj6up7o6ZNXxdaoMGFc+5k7vXDv AF+8UZzUHsKdzxbluaKClfFOuY+YgSIpCVC8pbNWz9r8WkK9X0pQG6N1wOkSM/rl+8 1NTJG21lGjdWIzn06wb0EI1mnG+eYb1uSwCeY/dgrUiQh3H0jPJ9qn3kxop1YZVTXl xTw8s6v5kprHw== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:47 +0200 Subject: [PATCH 02/32] nsfs: validate extensible ioctls Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-2-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=879; i=brauner@kernel.org; h=from:subject:message-id; bh=4DSLJ0TDAmWPOipYbwhpaBlzGQi13TeCv46x7pWryak=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7GW/UeDIlDPzOMtvgbpShYzMnu/7/FzOfKzsCW9Wq jCac25tRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwETM1zIyrNzHoH+a+3Wzm1Fw D+esu0+YNVYxJW5//cz097S+1F1qXxn+meT9mKnxf/YpfYUZj9dH91uUJC7+NcFFZGnw/JmXl4R cYAMA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Validate extensible ioctls stricter than we do now. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- fs/nsfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nsfs.c b/fs/nsfs.c index 59aa801347a7..34f0b35d3ead 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -169,9 +169,11 @@ static bool nsfs_ioctl_valid(unsigned int cmd) /* Extensible ioctls require some extra handling. */ switch (_IOC_NR(cmd)) { case _IOC_NR(NS_MNT_GET_INFO): + return extensible_ioctl_valid(cmd, NS_MNT_GET_INFO, MNT_NS_INFO_SIZE_VER= 0); case _IOC_NR(NS_MNT_GET_NEXT): + return extensible_ioctl_valid(cmd, NS_MNT_GET_NEXT, MNT_NS_INFO_SIZE_VER= 0); case _IOC_NR(NS_MNT_GET_PREV): - return (_IOC_TYPE(cmd) =3D=3D _IOC_TYPE(cmd)); + return extensible_ioctl_valid(cmd, NS_MNT_GET_PREV, MNT_NS_INFO_SIZE_VER= 0); } =20 return false; --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 AB888334379; Wed, 10 Sep 2025 14:37:23 +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=1757515043; cv=none; b=S98zORo53TaZKC8EQIlT32Im3fIN63OoVbWQykkiVCDWSYv7zJ5SDvAnUkRL4LtxZePSYubEZevGZRYCTTlYhn5rRPxwo+psGy6IdLOogbHkOsyeGsNOcckLRoPgBLv2eFONjyzEt7WMT24FgWyoSI9bGV1jI4CiBcikYnBN5AE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515043; c=relaxed/simple; bh=hlPdSkw0/u4fF427i2FMAlYZXzvrtzVNFa+EeyOD1Bk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TeBPlimcRFi0c5x4cHRcVLBvXDNo/BBobtPDdqvt1Whu6eg5lo2i7JknewU/YPe1Aqa8udIIvODl2ldTiWe3Coy1SAbj96OEvw3EdP+jt53w9Lr9Gcdn2YLvbTXmwuFANy+Ew2RjL/c6lZuGTLt9UaPax8f/UUqZNEoBlSYnuGk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y9QziZBd; 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="Y9QziZBd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B44E2C4CEEB; Wed, 10 Sep 2025 14:37:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515043; bh=hlPdSkw0/u4fF427i2FMAlYZXzvrtzVNFa+EeyOD1Bk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Y9QziZBd0Xfzc0k/r5hAFGohisjw14iJaQyLCxbG5+1s/fTXCFtLFrLkkSq/eTlX5 O8p1ntOjYorqNP/nX8D96b7puZvl/zp+aOknGEY8LFIGuw7WKeV/kB2UcfW/neieYF sY27AFZhq7pTCwQTSQRbqWcEwaDYAXuavdYjed5c0nu/stMgUtOZhS/rR3o1a8T+dp EtcvePxTOhVaXUE7F/BfWmGfZ5QcQMerTkv0rLWHC6jKoRi3a8Ir6SWM1XqfW3OECo 3WG+YdVlHw1eUVW7XQiXssh53X7Z2MCBjy6YeE6b8v1MnQrRgtEyMzOlLNqn/l7CoL ocXG37wpvE+/g== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:48 +0200 Subject: [PATCH 03/32] block: use extensible_ioctl_valid() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-3-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1199; i=brauner@kernel.org; h=from:subject:message-id; bh=hlPdSkw0/u4fF427i2FMAlYZXzvrtzVNFa+EeyOD1Bk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7GVnSFA6qy+kdChh/aztN45MnV18JMfglArXv9Llq dvYtxRe6yhlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE9gQLk4BmMjTdQz/q7+z7Gab/uWn4s45 2bKdB1M1nC8E8yVOFe/7/2iNeaGWDiND+/W3R+zcPizMLtrO4b56+4Y/DDzLp5YWmvPaHZBmiOF jBAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Use the new extensible_ioctl_valid() helper which is equivalent to what is done here. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara Reviewed-by: Jens Axboe --- block/blk-integrity.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 056b8948369d..609d75d6a39b 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -58,16 +58,14 @@ int blk_rq_count_integrity_sg(struct request_queue *q, = struct bio *bio) int blk_get_meta_cap(struct block_device *bdev, unsigned int cmd, struct logical_block_metadata_cap __user *argp) { - struct blk_integrity *bi =3D blk_get_integrity(bdev->bd_disk); + struct blk_integrity *bi; struct logical_block_metadata_cap meta_cap =3D {}; size_t usize =3D _IOC_SIZE(cmd); =20 - if (_IOC_DIR(cmd) !=3D _IOC_DIR(FS_IOC_GETLBMD_CAP) || - _IOC_TYPE(cmd) !=3D _IOC_TYPE(FS_IOC_GETLBMD_CAP) || - _IOC_NR(cmd) !=3D _IOC_NR(FS_IOC_GETLBMD_CAP) || - _IOC_SIZE(cmd) < LBMD_SIZE_VER0) + if (extensible_ioctl_valid(cmd, FS_IOC_GETLBMD_CAP, LBMD_SIZE_VER0)) return -ENOIOCTLCMD; =20 + bi =3D blk_get_integrity(bdev->bd_disk); if (!bi) goto out; =20 --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 78CC131AF06; Wed, 10 Sep 2025 14:37:29 +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=1757515049; cv=none; b=UcmFEF/C/p5zp2phcCQIJzWc4784cOXeRAQ6G2lXWTuTErXIS+AfhUXoFM8F/B2QZ+yPtyM6e+FbD9/MmbNShOFH+UrdxXMxAsxZko+aSzJqbPdT1vRkfIds+2QHoerEiKcvDFaQEAjbNVt9/Ddako07YMVXdRpDsBewErJZRYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515049; c=relaxed/simple; bh=ygHSdVECEky2ur8dAJ5kFJhfsJSwR30ApmvwmuGj5yo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EW8c/RH+JMDajKKFuoPUS4BIxrh0JCxzIR9rrqtru2kYboYM3cjkmcYPR8iL+owpgZw6Iepu45Gc3UsNUGqbab1gKImM+/qcJ6tw44Tjkn9b+dq3jYMqrCgyFCkWOlEM+F/WYL1mCpmeQqQeFjXvLDKartmnl+2yc1DFTVxaMe8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uXRhCXHQ; 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="uXRhCXHQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B19E0C4CEF9; Wed, 10 Sep 2025 14:37:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515049; bh=ygHSdVECEky2ur8dAJ5kFJhfsJSwR30ApmvwmuGj5yo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uXRhCXHQM7+BUFhrfe33B3BKlUxIF6zIEfkqE2XLwfVf1LpLaqTmqV3mRAvy3avlu USavCz2kLkAYOedsFmywNwuPf2EOBoE+bXWiBR+oTYBDQEBEsccwemEkusIuuMILef M9Eud7NUYL51LxCBsEJU2gWr5u0sU0DpddjGZUiLWdaldcIAgwPBgAi6CBFgU0e8ac 7Qjvo2lliTqzQyty/+wFP8ETdrvurZ67+w96MQREIXgpOWLIlQt938lnKyN2vkSVS9 l+DAybyDdjw+s/ciqZs6CDXsf8MwdFkSt39Vau0gA9wGt3XU6VGY9mqWTEJKzkr85h nTJSbkPvcJnKQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:49 +0200 Subject: [PATCH 04/32] ns: move to_ns_common() to ns_common.h Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-4-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=2191; i=brauner@kernel.org; h=from:subject:message-id; bh=ygHSdVECEky2ur8dAJ5kFJhfsJSwR30ApmvwmuGj5yo=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7GVfK1sx13oB05HdnhZHJJXX5zNGnXrYpHykLen5X t2Fi55GdpSwMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExEYgvDV6EcPy6lps4Xy6Nr q8V3Tk/8c2PilJAP9Z/5W/zbPmZ8ZfhfXzfPfpus+qkFOqcXt/RtTLxwT/KMx+dja/01TRkaC1t 4AA== X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Move the helper to ns_common.h where it belongs. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- include/linux/ns_common.h | 20 ++++++++++++++++++++ include/linux/nsproxy.h | 11 ----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 7d22ea50b098..bc2e0758e1c9 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -6,6 +6,15 @@ =20 struct proc_ns_operations; =20 +struct cgroup_namespace; +struct ipc_namespace; +struct mnt_namespace; +struct net; +struct pid_namespace; +struct time_namespace; +struct user_namespace; +struct uts_namespace; + struct ns_common { struct dentry *stashed; const struct proc_ns_operations *ops; @@ -13,4 +22,15 @@ struct ns_common { refcount_t count; }; =20 +#define to_ns_common(__ns) \ + _Generic((__ns), \ + struct cgroup_namespace *: &(__ns)->ns, \ + struct ipc_namespace *: &(__ns)->ns, \ + struct mnt_namespace *: &(__ns)->ns, \ + struct net *: &(__ns)->ns, \ + struct pid_namespace *: &(__ns)->ns, \ + struct time_namespace *: &(__ns)->ns, \ + struct user_namespace *: &(__ns)->ns, \ + struct uts_namespace *: &(__ns)->ns) + #endif diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h index dab6a1734a22..e6bec522b139 100644 --- a/include/linux/nsproxy.h +++ b/include/linux/nsproxy.h @@ -42,17 +42,6 @@ struct nsproxy { }; extern struct nsproxy init_nsproxy; =20 -#define to_ns_common(__ns) \ - _Generic((__ns), \ - struct cgroup_namespace *: &(__ns->ns), \ - struct ipc_namespace *: &(__ns->ns), \ - struct net *: &(__ns->ns), \ - struct pid_namespace *: &(__ns->ns), \ - struct mnt_namespace *: &(__ns->ns), \ - struct time_namespace *: &(__ns->ns), \ - struct user_namespace *: &(__ns->ns), \ - struct uts_namespace *: &(__ns->ns)) - /* * A structure to encompass all bits needed to install * a partial or complete new set of namespaces. --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 BA5CB32A821; Wed, 10 Sep 2025 14:37: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=1757515055; cv=none; b=IwkvNljj8GnE4v9BX4k0x07it1o0etEZlUjZJbIZrLpW7640y/3KgSPt6T3zUr2mAZ/LGmpGjIG5/MvTyEXqtF9oVs+BQjVucLgLJWbpAmghebwLpFV2ioBuDVzXRy5JZkVxsAoIZZUtMylH1M7DxXOAo0cTcJdCdhpm+7tPDtk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515055; c=relaxed/simple; bh=8FRw/l3sXiggMAyyDWj2ModuYi+3rG5Eie/HR+m5jhg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RHdtuZFiYRAHHAtyCU9MzyCeel/Pas9pmJeWJU+UWUPwHgV6ovrIiXn+bL28xF5C4Jsem7x1lRN2p7ke2GgTwO2mqXr3fbXh2dZTVWybNtxsTwIun3RmiSieDmuJ9tBynN8RGYmlhs1aRpgvKilIA/gPd7+XpmTynwDue51Js58= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BERmH5tK; 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="BERmH5tK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CB113C4CEEB; Wed, 10 Sep 2025 14:37:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515055; bh=8FRw/l3sXiggMAyyDWj2ModuYi+3rG5Eie/HR+m5jhg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BERmH5tKAeTvYAOvix3kN635Rw0RXR5WSDHcImBrNPyr1ZrPnTNiH4IX8bC31r8js YDpc40DPKToQFGnWNQcb7KD3JBejge20E3E31XY5dUUFgWDgIRUlE29o1yqxcbjrTt PuWbopF7b6cXNCTWEgVsMEqh0vRHViKhf/aEI7ty4WXa1fe39Kf3txMXopAIyXgOcA OZFluMkckXlIi4wzdPVU4vl9IoKJTmhERo8Cv0C/th+uTKoR7njWc1JbmQiASbfETb uUcCVfSnz8EPA2ZMiB4cG3507JBHcKHyW/w6NZvnMTPgN0Q85qStWXsiqQbKp6Lj29 HhoZsM7dF1LLA== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:50 +0200 Subject: [PATCH 05/32] nsfs: add nsfs.h header Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-5-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=2368; i=brauner@kernel.org; h=from:subject:message-id; bh=8FRw/l3sXiggMAyyDWj2ModuYi+3rG5Eie/HR+m5jhg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7GWXWXjOL29TmvmqWz/S5CbdMr1WGCFW9N7aNEKUx evMzsa0jlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIloXGNkOHYv1+NFppa4/aFP cdt4NOV7JXcwcmzZ6Rmd6LsisqHkH8Nvdi/u2e2rf2ndvsQcI1f3xaeJie+x5tyIxQvu8Uo/uPu OBQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 And move the stuff out from proc_ns.h where it really doesn't belong. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- include/linux/nsfs.h | 26 ++++++++++++++++++++++++++ include/linux/proc_ns.h | 13 +------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/include/linux/nsfs.h b/include/linux/nsfs.h new file mode 100644 index 000000000000..fb84aa538091 --- /dev/null +++ b/include/linux/nsfs.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2025 Christian Brauner */ + +#ifndef _LINUX_NSFS_H +#define _LINUX_NSFS_H + +#include + +struct path; +struct task_struct; +struct proc_ns_operations; + +int ns_get_path(struct path *path, struct task_struct *task, + const struct proc_ns_operations *ns_ops); +typedef struct ns_common *ns_get_path_helper_t(void *); +int ns_get_path_cb(struct path *path, ns_get_path_helper_t ns_get_cb, + void *private_data); + +bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino); + +int ns_get_name(char *buf, size_t size, struct task_struct *task, + const struct proc_ns_operations *ns_ops); +void nsfs_init(void); + +#endif /* _LINUX_NSFS_H */ + diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h index 4b20375f3783..5e1a4b378b79 100644 --- a/include/linux/proc_ns.h +++ b/include/linux/proc_ns.h @@ -5,7 +5,7 @@ #ifndef _LINUX_PROC_NS_H #define _LINUX_PROC_NS_H =20 -#include +#include #include =20 struct pid_namespace; @@ -75,16 +75,5 @@ static inline int ns_alloc_inum(struct ns_common *ns) #define ns_free_inum(ns) proc_free_inum((ns)->inum) =20 #define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private) -extern int ns_get_path(struct path *path, struct task_struct *task, - const struct proc_ns_operations *ns_ops); -typedef struct ns_common *ns_get_path_helper_t(void *); -extern int ns_get_path_cb(struct path *path, ns_get_path_helper_t ns_get_c= b, - void *private_data); - -extern bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino); - -extern int ns_get_name(char *buf, size_t size, struct task_struct *task, - const struct proc_ns_operations *ns_ops); -extern void nsfs_init(void); =20 #endif /* _LINUX_PROC_NS_H */ --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 70CAA32CF6C; Wed, 10 Sep 2025 14:37:41 +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=1757515061; cv=none; b=pfUs2egxBWD0XJzYWkIQyYTF0941vDcIUej3+iTq7yusreHecfGttchy6N1O6vwpIcQPG2fB130EwtzKbqAS1YX/8U33gRNZHWP78dhQBOR2XGh6vJ4lqpV5VmKnihPqbkRTwHcnCmdfOAsc9kOW+Myii5OUJUQRGyuvvWa4FfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515061; c=relaxed/simple; bh=B7r5xME705JZrGrmvpUjQFvU/5IFdDDiURc8AUJwiiQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uR/uzzhyag90UAHhK1dCn7ITTDEh2E75qCQe6B14trHVrfOK77pT0KkSaFnSleNnHEbZRzbdfkc6TslEWur/Dy59nUw+EgzH8dnS9VqyVwSI8fBe6HD7t7BNiSXG8sC6tYsw0MVDY6sYqEbOgcIy50G3YjSacp5IFkiMPw/c7jk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EYrDm3fo; 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="EYrDm3fo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CB1F1C4CEF0; Wed, 10 Sep 2025 14:37:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515061; bh=B7r5xME705JZrGrmvpUjQFvU/5IFdDDiURc8AUJwiiQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EYrDm3foVgRyetarOPPjGBoKL2jTXbEF663pJ31nlzq+EkFi4aicPOLyWGk0pSsVg 7cEYzyu+yorQ401tF4RAPXrix8y4scRYTaAYzme7koY7wTXU9cNFmEernTGng4pyq8 pF08kk1+/JWQhNa8O1tlLB9KMhu28Umklv2TsL1Vd+9QL7bVaef5L3haS2UasPdwFy 82b56iaBwX0cxZq+q6Lb87l/ZJnW/JZizBfcY9ce04Z+bZfXMiK7lMTndKW6AjO6Fc uR9zu8Q7mR4ASbQFJUeIfWp4MAJmsfbS9pOp01yrjqiR8o3wPOjdVokw7Sv3i8hVF5 t0Sp1JCGUUp2g== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:51 +0200 Subject: [PATCH 06/32] ns: uniformly initialize ns_common Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-6-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1007; i=brauner@kernel.org; h=from:subject:message-id; bh=B7r5xME705JZrGrmvpUjQFvU/5IFdDDiURc8AUJwiiQ=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OWYG3gylSNZ7e36oD8rmc/dLJxQHzZ5Qgz/jTK/C bcihT5O7yhlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZjIueMMfziTxU4wauybahl0 I6f+QpvjMqPdW+zW1jnPE6tPb/LdsJmR4cksdlvXEGMRHvadktu3yLnx+tSr++TZn57q2GWn/Uu QHQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 No point in cargo-culting the same code across all the different types. Use one common initializer. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- include/linux/proc_ns.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h index 5e1a4b378b79..dbb119bda097 100644 --- a/include/linux/proc_ns.h +++ b/include/linux/proc_ns.h @@ -72,6 +72,22 @@ static inline int ns_alloc_inum(struct ns_common *ns) return proc_alloc_inum(&ns->inum); } =20 +static inline int ns_common_init(struct ns_common *ns, + const struct proc_ns_operations *ops, + bool alloc_inum) +{ + if (alloc_inum) { + int ret; + ret =3D proc_alloc_inum(&ns->inum); + if (ret) + return ret; + } + refcount_set(&ns->count, 1); + ns->stashed =3D NULL; + ns->ops =3D ops; + return 0; +} + #define ns_free_inum(ns) proc_free_inum((ns)->inum) =20 #define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private) --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 DB96B32CF8F; Wed, 10 Sep 2025 14:37:47 +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=1757515068; cv=none; b=IK9TrKm7pxdRTakWpJb3bbKW8ze9GYrfypDutwqJTcg3cnKlVWSbg51JF7LmblTRw1rnadR4BiwwvYD4Gz3JvBNHV0fnkna/skU0j3eNy277lepqQbxfi52RO1V6qxmwpR95rcXWS+/w0h6itPGNJpquC+3EgrM/toHZsQqRM0Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515068; c=relaxed/simple; bh=Uyf4OUbQ4N9dntxnaqhQjswkZw9lycGwkUdINuCLOMY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OZbktQmdkYMSGT54TGrLwbKN6A45PL4+OGmrT1cdB/QDvG2eR6/CaMWk5s7ZuI6iKRE6ezwsZLBClBCaBLzvsYcs17Mu8J9FKzR61fdzcV0hSd6zsNbHZqp30GtqcBYzSEGphndbuBf301RoBJq7MLi/u1UGx9CXAXplE2gkrlA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F8oCGAZj; 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="F8oCGAZj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C5335C4CEF0; Wed, 10 Sep 2025 14:37:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515067; bh=Uyf4OUbQ4N9dntxnaqhQjswkZw9lycGwkUdINuCLOMY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=F8oCGAZjorilhalkKn/ywx/TJ/Tok4E+xiv9lQeGdPrOuw8pN0k6qqOZyyxTg4uxt R96lBeq9IPrld9W+9TZJyTEY+9GZ+c94IBPhjTKK96vNW+WobsmdPeRUa7i+5jv+70 yDAyEXFPIfY2fHigc0by2sjr73XKF6t8b1l/ERZJWuJSLW3JDRYbSiYfjhvn25kQRz m1AmgFb+9h7oi4MmcrN5OvG3R+Wn1pcB9k805jqV3NDy0tTbXJBGw1im2dIxCVdv7E 4JktcHvY1uA9x6x2oRHVB34u3wxY3F6Br1HbuOzjYZ69zf1Peg223bb6Iiix3wQswZ awm3DX268On+w== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:52 +0200 Subject: [PATCH 07/32] mnt: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-7-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1089; i=brauner@kernel.org; h=from:subject:message-id; bh=Uyf4OUbQ4N9dntxnaqhQjswkZw9lycGwkUdINuCLOMY=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OXg+P0gyTyYayKDzIEXK1RT1hfe/v3ijWhhpJonv 69ZjaRlRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwEQm3GL4Kx/VezdaRvvapt7n O1u7FSSPHtB5mbdkt7fdxz+Crz13ODP8M4jb0uBfFNHfM+lRvVLbgekiomf/xDhaf29y/HCu/vZ 3RgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- fs/namespace.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index ddfd4457d338..14c5cdbdd6e1 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4177,18 +4177,15 @@ static struct mnt_namespace *alloc_mnt_ns(struct us= er_namespace *user_ns, bool a dec_mnt_namespaces(ucounts); return ERR_PTR(-ENOMEM); } - if (!anon) { - ret =3D ns_alloc_inum(&new_ns->ns); - if (ret) { - kfree(new_ns); - dec_mnt_namespaces(ucounts); - return ERR_PTR(ret); - } + + ret =3D ns_common_init(&new_ns->ns, &mntns_operations, !anon); + if (ret) { + kfree(new_ns); + dec_mnt_namespaces(ucounts); + return ERR_PTR(ret); } - new_ns->ns.ops =3D &mntns_operations; if (!anon) new_ns->seq =3D atomic64_inc_return(&mnt_ns_seq); - refcount_set(&new_ns->ns.count, 1); refcount_set(&new_ns->passive, 1); new_ns->mounts =3D RB_ROOT; INIT_LIST_HEAD(&new_ns->mnt_ns_list); --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 D609331A540; Wed, 10 Sep 2025 14:37:53 +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=1757515074; cv=none; b=L3y6V2a6+i9aH62UUVEAhPkEPvMRgSjGfN1lyupOBnwpT4bKHqa+qorc99Ms9U1UEb64ami+lnjT+jHvy8dLYsX2P1hjyYESy03OmHkgs1AASy+y0pCIcxwhQAi9XjoL0b7lHCGTcxkHROLIywhH0jo92+DQ0DP8ksK4f51UHc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515074; c=relaxed/simple; bh=NK6WI3X3NLXas2ddU8r5M1j0jQ0BhLKIUJlLyAEhkI4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nCzaRFVWRRGQ+g76fgdnvMItrkQcsBMu3H/Espafa/2AxmiDZ1dIiRTJXXvYj8Ybrv1cuM/uwisRYz7ptbYWAn+gUWhVjP4A2TjRLtSSPJFlGwDYOz17JP9jGK4Xom2ETV34oXxkwZAHozARtEc161S4K7p1QLf8dMUgsZM/TH8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qdjNU8KV; 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="qdjNU8KV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0876BC4CEEB; Wed, 10 Sep 2025 14:37:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515073; bh=NK6WI3X3NLXas2ddU8r5M1j0jQ0BhLKIUJlLyAEhkI4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qdjNU8KViBVgxHOsL+lnmjDw6MQElPNtYllJgpKnF17n0FK8coJWnUrJUsi26jaWV is1+DG7fwt2V1qKDK17XWmxUCLvXbibyuUX/gNpEpd+jF3S7nHSvU0Rv57gvOuLbSz 59eehrkWkzR2b42DsHv3waMRsWpXc9njF6ayuDFW3HacGK6BtsYwNy/TqP5bxfKLKl UFMhdsJ+faM1lEn8n0lPGmVmZynHiNkwUsFlWPeu7L5f1s7z5UZP3QhdiZ7SD5qlVh 4BWIwSOez6hsG9HxAvXUp9iML80jkeKfYAIwzemiNzOMacdXwMi9g+AeMnPQRQqzJr qdaJJrE7DaEGQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:53 +0200 Subject: [PATCH 08/32] ipc: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-8-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=740; i=brauner@kernel.org; h=from:subject:message-id; bh=NK6WI3X3NLXas2ddU8r5M1j0jQ0BhLKIUJlLyAEhkI4=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OVov7TLt/Ngfmnm2t0v3DcEd/6ZrjWV9V179gKVx 5O7e9ZodpSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExEKZKRYY5R7q+4BL1PS2zm zt5vZvdr+aJtih4aoq9fXl+xUNnNtpuRYUFKUI2I6xnZwxpT0oKbNydwxmsrr+HRKPgUulDynl4 HMwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- ipc/namespace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ipc/namespace.c b/ipc/namespace.c index 4df91ceeeafe..d4188a88ee57 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -61,12 +61,10 @@ static struct ipc_namespace *create_ipc_ns(struct user_= namespace *user_ns, if (ns =3D=3D NULL) goto fail_dec; =20 - err =3D ns_alloc_inum(&ns->ns); + err =3D ns_common_init(&ns->ns, &ipcns_operations, true); if (err) goto fail_free; - ns->ns.ops =3D &ipcns_operations; =20 - refcount_set(&ns->ns.count, 1); ns->user_ns =3D get_user_ns(user_ns); ns->ucounts =3D ucounts; =20 --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 330B531A540; Wed, 10 Sep 2025 14:37:59 +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=1757515080; cv=none; b=lBqW1kB0oc8yUvvz1BzreBmY1HACXZx7YdeW9YWGnlq+sEv7/n741VAxT342+P5zpzLIZ8JSZl6SSWs8c3npnKQIlKflrn+p3nFIrtGRCoa3IiVThxCt/ePFtDMWs84Cv1m830Zba5KBMFMDtTrovrwtwZ2TGETay/IGLSKmkbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515080; c=relaxed/simple; bh=oLTEkd9LPucYI91jao02VqhHmofn8nqyUbSyayMXIto=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GlACwxpiGfd/Wm6j6j9Cc4/OXtvhg/VwvmqDyNPc7xhOxaJOtD2wxuDOZchLLtxYFnYXgJdGypiWaLu0Ljv17N8G3YTogf6i0d2vpuuQVU1MOZzxdVQEgq2mlVojziRJUIee2tQbBCUd0liJlAeZNvqmpEQHTsqH8vfvNTshoYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PvxGHMeV; 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="PvxGHMeV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36BB9C4CEEB; Wed, 10 Sep 2025 14:37:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515079; bh=oLTEkd9LPucYI91jao02VqhHmofn8nqyUbSyayMXIto=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PvxGHMeVvUXzDP5m3PMB+FTPaMiNaGPf2S+VA/toc1PtQKYPmDUVHuCIj3x4OZat4 +3ydbMzYZUAYSJPYvJJp384A2rK9bOyc46Pz5nQojmPaoLnsuG3pfJVmxONaVXAMTW DtiySdUWlkzrfwsGyDYrePnHNpM2ue4+pQ7FCBfzsbljMWFKjQgDYcS9kIHAmOtVZ0 nTr5uy1ft82iyVqIb8ptNteMZ0BYaqPYo0jyPUjwOvyUbuY3kpgDZYPWxWQ9HKtUiJ eLhGgW452v1kdytRAHLPZcaul7mvl56csR9H0EFYf+aAF3ZjCzfkgb6rr/h8htqsYM Plg6WqsvTz/+w== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:54 +0200 Subject: [PATCH 09/32] cgroup: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-9-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1134; i=brauner@kernel.org; h=from:subject:message-id; bh=oLTEkd9LPucYI91jao02VqhHmofn8nqyUbSyayMXIto=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OUQ7ogyf1DNuPPJFEnNSrH9jIELt04VzZaYa5RS5 c4xP82to5SFQYyLQVZMkcWh3SRcbjlPxWajTA2YOaxMIEMYuDgFYCKtRYwMZ4IPT58zK3lKwq0z e3bOe5f+rnJbmK68lE3NtNCv3xZ0P2X4H+H683xM+N7MiXJbtHf0Pbrkt+jIj+DalqmfWZuOqu5 m4AUA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- kernel/cgroup/namespace.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c index 144a464e45c6..0391b6ab0bf1 100644 --- a/kernel/cgroup/namespace.c +++ b/kernel/cgroup/namespace.c @@ -21,20 +21,16 @@ static void dec_cgroup_namespaces(struct ucounts *ucoun= ts) =20 static struct cgroup_namespace *alloc_cgroup_ns(void) { - struct cgroup_namespace *new_ns; + struct cgroup_namespace *new_ns __free(kfree) =3D NULL; int ret; =20 new_ns =3D kzalloc(sizeof(struct cgroup_namespace), GFP_KERNEL_ACCOUNT); if (!new_ns) return ERR_PTR(-ENOMEM); - ret =3D ns_alloc_inum(&new_ns->ns); - if (ret) { - kfree(new_ns); + ret =3D ns_common_init(&new_ns->ns, &cgroupns_operations, true); + if (ret) return ERR_PTR(ret); - } - refcount_set(&new_ns->ns.count, 1); - new_ns->ns.ops =3D &cgroupns_operations; - return new_ns; + return no_free_ptr(new_ns); } =20 void free_cgroup_ns(struct cgroup_namespace *ns) --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 2BD2632F74D; Wed, 10 Sep 2025 14:38:05 +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=1757515086; cv=none; b=UvXpx9HdKO2Ihwav8a0y+E710dtit01EjqvA/iV1SIxr0UZu8VjRHaBFAI0F377Ut2Nkw5nDV6hE94G5diEmSljizEHaamaOmbZRFsMr+oihi0mwP66DpyWe7eH1CQWhuC32hgz+lGiXok+Tcg2QuvJ6tOKwHM/A1R2RLlntruI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515086; c=relaxed/simple; bh=Cv4oIC9snRZNh6Az+KnfKIPi91lVOlLOl59hcQq05as=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mGukN6sr9AJYt6UxZ3S0e5g6mighiZg54MWH/XvUWGj4VUYF2gzrgH98ZAhH+wXyUYqTn8lUw1Z9mQfAu/A3DtVwMnyLvTg5Cc433spzjUBcMAM3eAXyDUYh7Z9b6qNBhnKEtk1cIUMoyHSE/KOaeCMYqyQYGfN+3jMosQ2J4WM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i0iMavcc; 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="i0iMavcc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 33CEBC4CEF0; Wed, 10 Sep 2025 14:38:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515085; bh=Cv4oIC9snRZNh6Az+KnfKIPi91lVOlLOl59hcQq05as=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=i0iMavccwG8XQvqcWy1HTa0bjwQkh+CJQtTpY8VFmtWstUwthNsi2dveZCIYbrAR4 LE1VotWlsW2FbiyyRLiIrZgbmEkyJJGP5yqvewekoYO/UjSQoUcYbZlxCxAVpwzQqJ xEc8JyxWfwlxSnpuDKh2VlP11Cz4mMreS3YjCrY8McUXFpUq0YigdcTYusuZ6K46Wv hDILOHd5R4IEYMW16mO1wChyyzQWLU33CQXx8w8cAVNpSvVd7w4EHlDN1SqLjgyMPX JFvjpkLY813U2vusvMsDjPpTGvq4fZrG7n9lCkTcyj0G8BgS363n9qQ4cR4L4ldrY5 ZL/GWKfiyV25A== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:55 +0200 Subject: [PATCH 10/32] pid: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-10-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=946; i=brauner@kernel.org; h=from:subject:message-id; bh=Cv4oIC9snRZNh6Az+KnfKIPi91lVOlLOl59hcQq05as=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OXo2fh2k1TApy2HxNMdGbYsvRl3sdiUa2I4U09o1 E2ugOnXO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACbS08jwv+R/a/D/A7nu8zq+ 5rKceTN9Fk/2/Mlly6Ulv7UE6yWpH2Rk+PXg+ewv0Q2Tln90XWMs9yt29tz9LdKNNyYcYbf95hP xhAkA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- kernel/pid_namespace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 7098ed44e717..20ce4052d1c5 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -102,17 +102,15 @@ static struct pid_namespace *create_pid_namespace(str= uct user_namespace *user_ns if (ns->pid_cachep =3D=3D NULL) goto out_free_idr; =20 - err =3D ns_alloc_inum(&ns->ns); + err =3D ns_common_init(&ns->ns, &pidns_operations, true); if (err) goto out_free_idr; - ns->ns.ops =3D &pidns_operations; =20 ns->pid_max =3D PID_MAX_LIMIT; err =3D register_pidns_sysctls(ns); if (err) goto out_free_inum; =20 - refcount_set(&ns->ns.count, 1); ns->level =3D level; ns->parent =3D get_pid_ns(parent_pid_ns); ns->user_ns =3D get_user_ns(user_ns); --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 2D53732F74D; Wed, 10 Sep 2025 14:38:11 +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=1757515092; cv=none; b=Nqkv0FPrYfEuL1wV20w84l+3ZpqrjXLt5nGsYnFUoyg0wudj9n+Kcn95xaHVZ57nOZ8R+dTiV9mDhi21eqkTyoDk1EbqeUnLeRV2pNLxpIozFMqR1maz6HTcisUYoLTaaAKUDAjba49DGdMGYve2ZrZxV/f14JW4SmI1z0pHA3A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515092; c=relaxed/simple; bh=iiPFC5SPYrdUEWp7Bw5ri9JWaFV5ytA5eNIM6tGTIgE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KxP9pliAUkiUwn94F1ulPW9WIyAvSms9xK7vMmvhLOI7hTgN/pCx73xYEhCIwNkYD/KN5aa3C2TInLvM4sK81DV9+sMN+zZ8834YMX+1cFvqOPp96q0eX/R6ED2tyG3aywbaHa1yZFu+UdCDBZZB3x63siUvsFh2xAR28bSHEWA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AYvkz+cf; 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="AYvkz+cf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2CADFC4CEEB; Wed, 10 Sep 2025 14:38:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515091; bh=iiPFC5SPYrdUEWp7Bw5ri9JWaFV5ytA5eNIM6tGTIgE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=AYvkz+cfX0obtODPvJ6wd/mWGSPoffsYFJm0datfvhBzNtKNQvq4Sx3li9LYX7upi aQ1L7+Bzrev6MY3XZvJLWusvSruvX42icMSDaMvOr6+5sDlJbMN9It51L4Iro2SuJ5 fbRDsi9nGrTbgo6I6zsj/mpp0ty9GktoQbdakeM/bTf6RiPU0fSd2cfqfCxwCk8XRS nLsVow8WlyO8tuqabnQLLzfya+BWQ5/qGv/eUpp2Q+Xl2iz96YYoMvvdr5dyYT2IG7 LwOaD+QTGMEJ7J2FChYbqq35pH9xu7J6FTRM63NG9wfZ5TcFAPbACCm6WooYMbkoBt MEohRrz3bOKrw== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:56 +0200 Subject: [PATCH 11/32] time: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-11-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=957; i=brauner@kernel.org; h=from:subject:message-id; bh=iiPFC5SPYrdUEWp7Bw5ri9JWaFV5ytA5eNIM6tGTIgE=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OXIn3Fi343fhasjU/Ra2OOaN/Ik1L8N1DtoFbjv4 eH+wqYfHSUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABNJvc3wTVfgsnecaLDqxZfW 091sFU4vfLCEs5tt0f+Zd7J5N3CtZvjvcfPQV/Oy35NyGHKiLP7qvNqaXc/hOX+O5jxO81PbKx7 zAQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara Reviewed-by: Thomas Gleixner --- kernel/time/namespace.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 667452768ed3..80b3d2ce2fb6 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -92,18 +92,15 @@ static struct time_namespace *clone_time_ns(struct user= _namespace *user_ns, if (!ns) goto fail_dec; =20 - refcount_set(&ns->ns.count, 1); - ns->vvar_page =3D alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!ns->vvar_page) goto fail_free; =20 - err =3D ns_alloc_inum(&ns->ns); + err =3D ns_common_init(&ns->ns, &timens_operations, true); if (err) goto fail_free_page; =20 ns->ucounts =3D ucounts; - ns->ns.ops =3D &timens_operations; ns->user_ns =3D get_user_ns(user_ns); ns->offsets =3D old_ns->offsets; ns->frozen_offsets =3D false; --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 1FD2232BF22; Wed, 10 Sep 2025 14:38:17 +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=1757515098; cv=none; b=cE57IEfrDMIGLMSSNu/7oEvMlr2Tj/Epw59LCVCrA+nlcwcHw/RKp2EZyoUM5MV/E0VUTV36ReFIbWMZDX9BnqN5n387i9VcH0HqLo0ajyB4+S4NhnuP5myepmpoDbkiJVdAxftOyYBbbUCMaVpxRG9QfgxJVZH1v5BqvDgZB60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515098; c=relaxed/simple; bh=ccs2mPITvV7+tId/BLNyWx+lXkz4V4lk4FOMDck+H58=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=t42IZsPLFMNcpjQy0JWjafzt6rH7gIvTjmj6uguIHHA6CIvXXyyV+mkWj0u9Ze+2xPt645/XBzEc+sHkCPdnY3mC+aolPJ8IlzHjkpSF9cQRhnRIRtLIEYPQU/wzZggw8yP0TXxMK2fnz3xw76Oz7uh+mWGzycx/DXETKIOvMP8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ueyqyW/d; 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="ueyqyW/d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4571CC4CEF0; Wed, 10 Sep 2025 14:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515097; bh=ccs2mPITvV7+tId/BLNyWx+lXkz4V4lk4FOMDck+H58=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ueyqyW/dGhM8OGZDuxLW5JsOsfhwDmPetMD4JrYdT7VyNmiwHWrSdI+Sozmsx20Qm spB3thrhcrBVyFvwGgbTcFsTpNHxDKmHcUq+nMyKPZv/lBNHlJzD6XX5xnEd4wChiX AnnTGaZAksoek63PLTNB2LXoaL7ZrCLX2fYhK2pOMGr2D/WtF/Hbc/l/drV5kWiUay /FgG0+KY5vupnmn1zP7lNr7/Zy81OnCWJjsTmCPP2CfdNSa+Q/MuRX5OedY2kUwMpc h8NARbPO7EzqxxOpCFSo5Dcv7qR0RteSKtlA6TTbc39Ae5YoYraPLSrwvpF/2p30eq G675Un6AFTuaQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:57 +0200 Subject: [PATCH 12/32] uts: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-12-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1376; i=brauner@kernel.org; h=from:subject:message-id; bh=ccs2mPITvV7+tId/BLNyWx+lXkz4V4lk4FOMDck+H58=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OXwljvywTKfUfygeUJ53n61TSvkN366tGK36u9Zi 3llb9506ChlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZjIF22Gv8Kae2LYV7X3Rj0t Y9j6Y+/ltw+y+D4e3rou+/GhidwNHwsZ/kcFrJ4Y7WGi9jd2aoR7qV2aV/LJ+z8FNZmY11sXOvP fYwIA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- kernel/utsname.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/kernel/utsname.c b/kernel/utsname.c index b1ac3ca870f2..02037010b378 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -27,16 +27,6 @@ static void dec_uts_namespaces(struct ucounts *ucounts) dec_ucount(ucounts, UCOUNT_UTS_NAMESPACES); } =20 -static struct uts_namespace *create_uts_ns(void) -{ - struct uts_namespace *uts_ns; - - uts_ns =3D kmem_cache_alloc(uts_ns_cache, GFP_KERNEL); - if (uts_ns) - refcount_set(&uts_ns->ns.count, 1); - return uts_ns; -} - /* * Clone a new ns copying an original utsname, setting refcount to 1 * @old_ns: namespace to clone @@ -55,17 +45,15 @@ static struct uts_namespace *clone_uts_ns(struct user_n= amespace *user_ns, goto fail; =20 err =3D -ENOMEM; - ns =3D create_uts_ns(); + ns =3D kmem_cache_zalloc(uts_ns_cache, GFP_KERNEL); if (!ns) goto fail_dec; =20 - err =3D ns_alloc_inum(&ns->ns); + err =3D ns_common_init(&ns->ns, &utsns_operations, true); if (err) goto fail_free; =20 ns->ucounts =3D ucounts; - ns->ns.ops =3D &utsns_operations; - down_read(&uts_sem); memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); ns->user_ns =3D get_user_ns(user_ns); --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 13C723314D4; Wed, 10 Sep 2025 14:38:23 +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=1757515104; cv=none; b=kMThdHKI+VJjcG9uOHjnEgWxcJFO25EpWH0GUKd4ovIo2j2E1o0iwhR2NsjVr4J6aQ47Os+0X1kdGXeZWJQxBmUstrLSP9KpdSMHR0eTt1QgDskLio8gLlmnrnHT/+2YyCZlQzfBFkvXyV5E2SaIIweAcHcEu9B7h7Clgsr2vxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515104; c=relaxed/simple; bh=2Pb+C09AD3Ch8zyPOBqZ4ir9gSxZa2YXPjiwgVDz5cU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gzO98m7l3ioVIa9v3uxyYNiE7Vnt7+ZE3eL2aCWeiAGcWtyaKJQuAYNO+kxGMsqK9OheHtjLx2Tii3X+DeUSmZf/jsoyjPAzj9W14vJ9HTR1mxX0DVI1MK9VQ1Ec5syCWQCgYVigWu8vBTgwXxuNaoDYodxjXSapbpT5U3v2O7A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RoA1MDpk; 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="RoA1MDpk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2B9CDC4CEEB; Wed, 10 Sep 2025 14:38:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515103; bh=2Pb+C09AD3Ch8zyPOBqZ4ir9gSxZa2YXPjiwgVDz5cU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RoA1MDpk9S+ycSKb/Q+l+kZDQIZH5mDrtrLuYDtbwiGpz30Uhq+sfvSy2CQYDnSR5 wg7hzq7eYSjWPE+Z6MBC3TyBfpUCuPzrOtIeV+TcOhVAc4y32dVRqMg1DcuBYHDdKx W1lv1OEpocUHLD0TFu2imsiQZRs9EcORK01Y64oS49umndyHGmW2IaNsyN6hj3LYAH gHe4KpMrGeQ1PL09gAmBQk16BERVL+KtvqORXx7/bHJjG3H1aOZSzZED1lISoh9/0G tYlK+EEMLX7z01ucOjdvu2eI1slN05SbPIuqUdsJhE1S/G1Ku1Hm8JYGzFk5Cq1RZP Quhg4OYKyUNbw== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:58 +0200 Subject: [PATCH 13/32] user: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-13-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=874; i=brauner@kernel.org; h=from:subject:message-id; bh=2Pb+C09AD3Ch8zyPOBqZ4ir9gSxZa2YXPjiwgVDz5cU=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OWQVtxd+Ip3bqPKpWIPt+Mu1t7KLJ/urTU58Ki5X 7pu/uppHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABNxcWJk2Ou+LOxd0g/NsjNF O2W2vVryxUOktTjt072T+xQeMU7sfcnI8FzUsFY+gvdo/yq1+r6zge/q+g8cfHlNQlJ/BatYdcg pbgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- kernel/user_namespace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 682f40d5632d..98f4fe84d039 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -124,12 +124,11 @@ int create_user_ns(struct cred *new) goto fail_dec; =20 ns->parent_could_setfcap =3D cap_raised(new->cap_effective, CAP_SETFCAP); - ret =3D ns_alloc_inum(&ns->ns); + + ret =3D ns_common_init(&ns->ns, &userns_operations, true); if (ret) goto fail_free; - ns->ns.ops =3D &userns_operations; =20 - refcount_set(&ns->ns.count, 1); /* Leave the new->user_ns reference with the new user namespace. */ ns->parent =3D parent_ns; ns->level =3D parent_ns->level + 1; --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 AB03C3314D4; Wed, 10 Sep 2025 14:38:29 +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=1757515109; cv=none; b=RnjDu7J/y53u4vXnvYT7TpNVRk0Pr3R1a+SZ6a8wFaZmpcISC162XBOokIgEk+VS1qWRH3XRVxMShZUlcmJNEWnKq/zVmIVJ4YJIn9R1zgTT7kDVnTWkRqJBqVIyX2tkCWyvo9F4o96ptyAm0cHgeNfDy/TXFGRkf2Fn9rTubx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515109; c=relaxed/simple; bh=8/A1bxZ4UuUeHxhFjq1bHDTfg5yr2/KaJ6j+CBu56xs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o8f0AaMQS9Fo1zuAvIHWoQvT+mgQvyJhq/Eh/PriKs/A0sTAMTW04EyftS8qKHyxNtgWKiSP5rgtvDbtWJPY7V/hTRCi4afXFfvLIhcz833algqUymDqnluzoL1//TU9fj5Sw4RQjJ1UsfeICz3ClycxUki+FSK6JTuMQycVsD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pgs65Z6x; 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="Pgs65Z6x" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 16DEEC4CEF8; Wed, 10 Sep 2025 14:38:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515109; bh=8/A1bxZ4UuUeHxhFjq1bHDTfg5yr2/KaJ6j+CBu56xs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Pgs65Z6xM1PIgXjGvgjovg59qxYMsyu37WjGBi25eC04mZXDq4hh922v9lOurccAF dkn5Fcqu1HXXobdVQnH4DR1VvsqOkqj0mnQe2hCPXCKhi4f7UcL/jxMGO+ttj7yKnF zYTRcHdLEKipxd9m/wk0Iqkch13qkTO6YYAsyY52+FM/z6IvUInU4gRNimr4uV3DUK 2V04rbcrkNrEcjYD8JOxi70s4lLnSTwEGtKMWk7bkW0mWUiSzP/2VnJlNsrqHa9UAX 31HPh2PfpJDxFEC9ITzoNduk0Zf/aoi2vx9NSavNg81zbkr73uFmf2o8g/yb/vvILA 2Am80cLUWhYuw== From: Christian Brauner Date: Wed, 10 Sep 2025 16:36:59 +0200 Subject: [PATCH 14/32] net: use ns_common_init() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-14-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=2959; i=brauner@kernel.org; h=from:subject:message-id; bh=8/A1bxZ4UuUeHxhFjq1bHDTfg5yr2/KaJ6j+CBu56xs=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OU4PZ95/+Ut/0WPSvw/Vni2xE5lmsvintqTXjpXW B+vaa5P7ChlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZjIbhlGhjfcfgvWn1tT395t mn8p6oaY86ku/4w9q9SOnQp5uFqiQp3hf0r+9MfTP/1yljr/4nFaYNL2eNu66d2vc+J0JKYHOm+ eywEA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Don't cargo-cult the same thing over and over. Signed-off-by: Christian Brauner --- net/core/net_namespace.c | 46 ++++++++++++++++++++++++++++++++------------= -- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 1b6f3826dd0e..dafb3d947043 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -397,10 +397,22 @@ static __net_init void preinit_net_sysctl(struct net = *net) } =20 /* init code that must occur even if setup_net() is not called. */ -static __net_init void preinit_net(struct net *net, struct user_namespace = *user_ns) +static __net_init int preinit_net(struct net *net, struct user_namespace *= user_ns) { + const struct proc_ns_operations *ns_ops; + int ret; + +#ifdef CONFIG_NET_NS + ns_ops =3D &netns_operations; +#else + ns_ops =3D NULL; +#endif + + ret =3D ns_common_init(&net->ns, ns_ops, false); + if (ret) + return ret; + refcount_set(&net->passive, 1); - refcount_set(&net->ns.count, 1); ref_tracker_dir_init(&net->refcnt_tracker, 128, "net_refcnt"); ref_tracker_dir_init(&net->notrefcnt_tracker, 128, "net_notrefcnt"); =20 @@ -420,6 +432,7 @@ static __net_init void preinit_net(struct net *net, str= uct user_namespace *user_ INIT_LIST_HEAD(&net->ptype_all); INIT_LIST_HEAD(&net->ptype_specific); preinit_net_sysctl(net); + return 0; } =20 /* @@ -559,7 +572,9 @@ struct net *copy_net_ns(unsigned long flags, goto dec_ucounts; } =20 - preinit_net(net, user_ns); + rv =3D preinit_net(net, user_ns); + if (rv < 0) + goto dec_ucounts; net->ucounts =3D ucounts; get_user_ns(user_ns); =20 @@ -573,6 +588,7 @@ struct net *copy_net_ns(unsigned long flags, =20 if (rv < 0) { put_userns: + ns_free_inum(&net->ns); #ifdef CONFIG_KEYS key_remove_domain(net->key_domain); #endif @@ -812,17 +828,14 @@ static void net_ns_net_debugfs(struct net *net) =20 static __net_init int net_ns_net_init(struct net *net) { -#ifdef CONFIG_NET_NS - net->ns.ops =3D &netns_operations; -#endif - net->ns.inum =3D PROC_NET_INIT_INO; - if (net !=3D &init_net) { - int ret =3D ns_alloc_inum(&net->ns); - if (ret) - return ret; - } + int ret =3D 0; + + if (net =3D=3D &init_net) + net->ns.inum =3D PROC_NET_INIT_INO; + else + ret =3D proc_alloc_inum(&to_ns_common(net)->inum); net_ns_net_debugfs(net); - return 0; + return ret; } =20 static __net_exit void net_ns_net_exit(struct net *net) @@ -1282,7 +1295,12 @@ void __init net_ns_init(void) #ifdef CONFIG_KEYS init_net.key_domain =3D &init_net_key_domain; #endif - preinit_net(&init_net, &init_user_ns); + /* + * This currently cannot fail as the initial network namespace + * has a static inode number. + */ + if (preinit_net(&init_net, &init_user_ns)) + panic("Could not preinitialize the initial network namespace"); =20 down_write(&pernet_ops_rwsem); if (setup_net(&init_net)) --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 0E8D93314CB; Wed, 10 Sep 2025 14:38: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=1757515116; cv=none; b=L1akY0QSgZZ5tmd9n1B7zLlMF8VoxY2JRSuzHeVVKptPOM5/OUYiZvvVUTKjfwlJgCQSTvozzICpsTriGSj7JvT7qegGJQxroJxWdeh1ebHMxXP7CkasTMNEd9H+mHNuyBzjiCoqzvqJDVI11zsslqyKTiVy7hhSy2Od4ArW2e0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515116; c=relaxed/simple; bh=UnI5m7SqHWsMxkZIWEiFZAf4ouVfPgpP2czPm9uoPxs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qsbOFqZ2m321eITe+ipIqJDRg3hpA8jlE01vWH7TV9MKhECCeZRZ5mC6wgvL2rOE25rxTFRC/z22xvw9hBoXXA6PcU97cOWbbhp8Qkt9C8R8AoCjlEFXlegzXkSIt7k0zoNqZdU1YXmg9fuUOUzy6JNBD06ZcPy1pCYtZprJd6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=s7D27ayK; 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="s7D27ayK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08346C4CEFB; Wed, 10 Sep 2025 14:38:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515115; bh=UnI5m7SqHWsMxkZIWEiFZAf4ouVfPgpP2czPm9uoPxs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=s7D27ayKL2ko/bOsxxIYGseQoCeIRO0vBs6zyp95hOSVeVYiG8aXuhPWyKoDfJjQ5 hvk8P5uyqLkLt8imKU53ABEBWZNgRKn18z3e0eYsPPdpgufZdI4xAQYsbvY7Cxgd92 5p1L9eAWZmrQ7XSSPAoMWj1LyuumDfrmCYhoNnu7tpvHWQ09uDoEiAva4iRv2LjctR bO/FGIbF3rG2aG0SwxVJJeN6Wh3mEwbvFiTLAymj3zIJ02afHyDX4AucKPby0xxTO8 at/XTK4vDBYvzjBIu0XalEiaPR3s4jqFbveFLms55G3WmiKdWgwklqqGEr4YdGETnE vZHVogV27V77A== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:00 +0200 Subject: [PATCH 15/32] ns: remove ns_alloc_inum() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-15-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=711; i=brauner@kernel.org; h=from:subject:message-id; bh=UnI5m7SqHWsMxkZIWEiFZAf4ouVfPgpP2czPm9uoPxs=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OUQM5ud87fs/cWkSx36k6uyOnYvu6z9IunXc1+D+ HfhPE67O0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACayyZXhf+HpmZ+SA6at8V4W npuhMtOC87Da5ScHRKL27y+SMFWTeMfI0LVH9+LGQo0k1e5wRmdDDr/Em2+nqvZ9DJ8YwDk3fFk mJwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 It's now unused. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- include/linux/proc_ns.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h index dbb119bda097..e50d312f9fee 100644 --- a/include/linux/proc_ns.h +++ b/include/linux/proc_ns.h @@ -66,12 +66,6 @@ static inline void proc_free_inum(unsigned int inum) {} =20 #endif /* CONFIG_PROC_FS */ =20 -static inline int ns_alloc_inum(struct ns_common *ns) -{ - WRITE_ONCE(ns->stashed, NULL); - return proc_alloc_inum(&ns->inum); -} - static inline int ns_common_init(struct ns_common *ns, const struct proc_ns_operations *ops, bool alloc_inum) --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 EF6A83314CB; Wed, 10 Sep 2025 14:38:41 +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=1757515122; cv=none; b=LW5VtPzKbXTcP+4JG2MhFVcRNWjtB2cqiOgNIcF2XGyG36uU79jyoC0Ecv9GTbufm7Z2jDRS3JPpEqwFwP/0eSXkAovvXvS2BK1sK3abml/AOlWSVeF+c2OrFLUCvb2s0eJBLkjqYAi6VbD7Ccj2kMZJ+b8EV3YxWK+r7GWIf8k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515122; c=relaxed/simple; bh=5xiw6OfhVh00mJOtdBSreH+JI53YjCepXuhC3AtIEBE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iJ43wyQmUn9LVYqhwa0BS09nkzJA9+l/no5sIr9SUK+cf1ysJy5e8hui6/kSEeF83B7Ey6UtR9tn9tA4eiWqARG0eC7tdGhXWbCQ3oz+5dhwL1dN9+vXXvODmnm9W31+E/OJgnATpVftmfkQuW28IYE86Z1GD8kGJXGA/a0VaD8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WvZ32OCb; 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="WvZ32OCb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0DAE7C4CEEB; Wed, 10 Sep 2025 14:38:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515121; bh=5xiw6OfhVh00mJOtdBSreH+JI53YjCepXuhC3AtIEBE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WvZ32OCb/62PzeZgf/1TtawmrWgUHwOTVRXzH17ulrhcR+Ksk7kkbQ+UwRpgxPm5p onu1Hl8epxXGK5mKVJT2miHZjzUHVBN0iFMz8jX/nr/fqH18Y6SvqRuHBgPvkgkg+7 ye6444eIu3/Coi7nz5rsuJg6h6cTRjmJ1JMDxflmVTMMxTt3QZmjoBgIas6+P+bwha V9577vXlJmZAF7Y+b0qo6418EvwcUvvTib38JDg3B8RF4FQoUiKeGJ+6STLadZHGOa srWc0S0f0JQ2MM+LOzviMEUBiNDe9VnoJN9iAxM6DTB07UH4OHbOrBrC97yHbE+77a XfVB724Gf1ErQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:01 +0200 Subject: [PATCH 16/32] nstree: make iterator generic Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-16-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=11888; i=brauner@kernel.org; h=from:subject:message-id; bh=5xiw6OfhVh00mJOtdBSreH+JI53YjCepXuhC3AtIEBE=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OWwsd1o5PbwvdvW3faGJdpGlyzWOywx8rguHXDWf D0X8871HaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABMRdGdkmKGi3s5uJzFVLHa1 crG3FtNTztNTdkd8eit8/dHBx78dbjP8L/safJcxqHthSe7jE4zva8Uu1AoyCrscsWj/7nj6wNN kdgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Move the namespace iteration infrastructure originally introduced for mount namespaces into a generic library usable by all namespace types. Signed-off-by: Christian Brauner --- include/linux/ns_common.h | 9 ++ include/linux/nstree.h | 89 ++++++++++++++++++ include/linux/proc_ns.h | 3 + kernel/Makefile | 2 +- kernel/nstree.c | 233 ++++++++++++++++++++++++++++++++++++++++++= ++++ 5 files changed, 335 insertions(+), 1 deletion(-) diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index bc2e0758e1c9..7224072cccc5 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -3,6 +3,7 @@ #define _LINUX_NS_COMMON_H =20 #include +#include =20 struct proc_ns_operations; =20 @@ -20,6 +21,14 @@ struct ns_common { const struct proc_ns_operations *ops; unsigned int inum; refcount_t count; + union { + struct { + u64 ns_id; + struct rb_node ns_tree_node; + struct list_head ns_list_node; + }; + struct rcu_head ns_rcu; + }; }; =20 #define to_ns_common(__ns) \ diff --git a/include/linux/nstree.h b/include/linux/nstree.h new file mode 100644 index 000000000000..e26951a83924 --- /dev/null +++ b/include/linux/nstree.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_NSTREE_H +#define _LINUX_NSTREE_H + +#include +#include +#include +#include +#include +#include + +/** + * struct ns_tree - Namespace tree + * @ns_tree: Rbtree of namespaces of a particular type + * @ns_list: Sequentially walkable list of all namespaces of this type + * @ns_tree_lock: Seqlock to protect the tree and list + */ +struct ns_tree { + struct rb_root ns_tree; + struct list_head ns_list; + seqlock_t ns_tree_lock; + int type; +}; + +extern struct ns_tree cgroup_ns_tree; +extern struct ns_tree ipc_ns_tree; +extern struct ns_tree mnt_ns_tree; +extern struct ns_tree net_ns_tree; +extern struct ns_tree pid_ns_tree; +extern struct ns_tree time_ns_tree; +extern struct ns_tree user_ns_tree; +extern struct ns_tree uts_ns_tree; + +#define to_ns_tree(__ns) \ + _Generic((__ns), \ + struct cgroup_namespace *: &(cgroup_ns_tree), \ + struct ipc_namespace *: &(ipc_ns_tree), \ + struct net *: &(net_ns_tree), \ + struct pid_namespace *: &(pid_ns_tree), \ + struct mnt_namespace *: &(mnt_ns_tree), \ + struct time_namespace *: &(time_ns_tree), \ + struct user_namespace *: &(user_ns_tree), \ + struct uts_namespace *: &(uts_ns_tree)) + +u64 ns_tree_gen_id(struct ns_common *ns); +void __ns_tree_add_raw(struct ns_common *ns, struct ns_tree *ns_tree); +void __ns_tree_remove(struct ns_common *ns, struct ns_tree *ns_tree); +struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns_type); +struct ns_common *__ns_tree_adjoined_rcu(struct ns_common *ns, + struct ns_tree *ns_tree, + bool previous); + +static inline void __ns_tree_add(struct ns_common *ns, struct ns_tree *ns_= tree) +{ + ns_tree_gen_id(ns); + __ns_tree_add_raw(ns, ns_tree); +} + +/** + * ns_tree_add_raw - Add a namespace to a namespace + * @ns: Namespace to add + * + * This function adds a namespace to the appropriate namespace tree + * without assigning a id. + */ +#define ns_tree_add_raw(__ns) __ns_tree_add_raw(to_ns_common(__ns), to_ns_= tree(__ns)) + +/** + * ns_tree_add - Add a namespace to a namespace tree + * @ns: Namespace to add + * + * This function assigns a new id to the namespace and adds it to the + * appropriate namespace tree and list. + */ +#define ns_tree_add(__ns) __ns_tree_add(to_ns_common(__ns), to_ns_tree(__n= s)) + +/** + * ns_tree_remove - Remove a namespace from a namespace tree + * @ns: Namespace to remove + * + * This function removes a namespace from the appropriate namespace + * tree and list. + */ +#define ns_tree_remove(__ns) __ns_tree_remove(to_ns_common(__ns), to_ns_t= ree(__ns)) + +#define ns_tree_adjoined_rcu(__ns, __previous) \ + __ns_tree_adjoined_rcu(to_ns_common(__ns), to_ns_tree(__ns), __previous) + +#endif /* _LINUX_NSTREE_H */ diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h index e50d312f9fee..7f89f0829e60 100644 --- a/include/linux/proc_ns.h +++ b/include/linux/proc_ns.h @@ -79,6 +79,9 @@ static inline int ns_common_init(struct ns_common *ns, refcount_set(&ns->count, 1); ns->stashed =3D NULL; ns->ops =3D ops; + ns->ns_id =3D 0; + RB_CLEAR_NODE(&ns->ns_tree_node); + INIT_LIST_HEAD(&ns->ns_list_node); return 0; } =20 diff --git a/kernel/Makefile b/kernel/Makefile index c60623448235..b807516a1b43 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -8,7 +8,7 @@ obj-y =3D fork.o exec_domain.o panic.o \ sysctl.o capability.o ptrace.o user.o \ signal.o sys.o umh.o workqueue.o pid.o task_work.o \ extable.o params.o \ - kthread.o sys_ni.o nsproxy.o \ + kthread.o sys_ni.o nsproxy.o nstree.o \ notifier.o ksysfs.o cred.o reboot.o \ async.o range.o smpboot.o ucount.o regset.o ksyms_common.o =20 diff --git a/kernel/nstree.c b/kernel/nstree.c new file mode 100644 index 000000000000..bbe8bedc924c --- /dev/null +++ b/kernel/nstree.c @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include + +struct ns_tree mnt_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(mnt_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(mnt_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWNS, +}; + +struct ns_tree net_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(net_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(net_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWNET, +}; +EXPORT_SYMBOL_GPL(net_ns_tree); + +struct ns_tree uts_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(uts_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(uts_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWUTS, +}; + +struct ns_tree user_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(user_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(user_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWUSER, +}; + +struct ns_tree ipc_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(ipc_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(ipc_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWIPC, +}; + +struct ns_tree pid_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(pid_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(pid_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWPID, +}; + +struct ns_tree cgroup_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(cgroup_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(cgroup_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWCGROUP, +}; + +struct ns_tree time_ns_tree =3D { + .ns_tree =3D RB_ROOT, + .ns_list =3D LIST_HEAD_INIT(time_ns_tree.ns_list), + .ns_tree_lock =3D __SEQLOCK_UNLOCKED(time_ns_tree.ns_tree_lock), + .type =3D CLONE_NEWTIME, +}; + +DEFINE_COOKIE(namespace_cookie); + +static inline struct ns_common *node_to_ns(const struct rb_node *node) +{ + if (!node) + return NULL; + return rb_entry(node, struct ns_common, ns_tree_node); +} + +static inline int ns_cmp(struct rb_node *a, const struct rb_node *b) +{ + struct ns_common *ns_a =3D node_to_ns(a); + struct ns_common *ns_b =3D node_to_ns(b); + u64 ns_id_a =3D ns_a->ns_id; + u64 ns_id_b =3D ns_b->ns_id; + + if (ns_id_a < ns_id_b) + return -1; + if (ns_id_a > ns_id_b) + return 1; + return 0; +} + +void __ns_tree_add_raw(struct ns_common *ns, struct ns_tree *ns_tree) +{ + struct rb_node *node, *prev; + + VFS_WARN_ON_ONCE(!ns->ns_id); + + write_seqlock(&ns_tree->ns_tree_lock); + + VFS_WARN_ON_ONCE(ns->ops->type !=3D ns_tree->type); + + node =3D rb_find_add_rcu(&ns->ns_tree_node, &ns_tree->ns_tree, ns_cmp); + /* + * If there's no previous entry simply add it after the + * head and if there is add it after the previous entry. + */ + prev =3D rb_prev(&ns->ns_tree_node); + if (!prev) + list_add_rcu(&ns->ns_list_node, &ns_tree->ns_list); + else + list_add_rcu(&ns->ns_list_node, &node_to_ns(prev)->ns_list_node); + + write_sequnlock(&ns_tree->ns_tree_lock); + + VFS_WARN_ON_ONCE(node); +} + +void __ns_tree_remove(struct ns_common *ns, struct ns_tree *ns_tree) +{ + VFS_WARN_ON_ONCE(RB_EMPTY_NODE(&ns->ns_tree_node)); + VFS_WARN_ON_ONCE(list_empty(&ns->ns_list_node)); + VFS_WARN_ON_ONCE(ns->ops->type !=3D ns_tree->type); + + write_seqlock(&ns_tree->ns_tree_lock); + rb_erase(&ns->ns_tree_node, &ns_tree->ns_tree); + list_bidir_del_rcu(&ns->ns_list_node); + RB_CLEAR_NODE(&ns->ns_tree_node); + write_sequnlock(&ns_tree->ns_tree_lock); +} +EXPORT_SYMBOL_GPL(__ns_tree_remove); + +static int ns_find(const void *key, const struct rb_node *node) +{ + const u64 ns_id =3D *(u64 *)key; + const struct ns_common *ns =3D node_to_ns(node); + + if (ns_id < ns->ns_id) + return -1; + if (ns_id > ns->ns_id) + return 1; + return 0; +} + + +static struct ns_tree *ns_tree_from_type(int ns_type) +{ + switch (ns_type) { + case CLONE_NEWCGROUP: + return &cgroup_ns_tree; + case CLONE_NEWIPC: + return &ipc_ns_tree; + case CLONE_NEWNS: + return &mnt_ns_tree; + case CLONE_NEWNET: + return &net_ns_tree; + case CLONE_NEWPID: + return &pid_ns_tree; + case CLONE_NEWUSER: + return &user_ns_tree; + case CLONE_NEWUTS: + return &uts_ns_tree; + case CLONE_NEWTIME: + return &time_ns_tree; + } + + return NULL; +} + +struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns_type) +{ + struct ns_tree *ns_tree; + struct rb_node *node; + unsigned int seq; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "suspicious ns_tree_lookup_rcu() = usage"); + + ns_tree =3D ns_tree_from_type(ns_type); + if (!ns_tree) + return NULL; + + do { + seq =3D read_seqbegin(&ns_tree->ns_tree_lock); + node =3D rb_find_rcu(&ns_id, &ns_tree->ns_tree, ns_find); + if (node) + break; + } while (read_seqretry(&ns_tree->ns_tree_lock, seq)); + + if (!node) + return NULL; + + VFS_WARN_ON_ONCE(node_to_ns(node)->ops->type !=3D ns_type); + + return node_to_ns(node); +} + +/** + * ns_tree_adjoined_rcu - find the next/previous namespace in the same + * tree + * @ns: namespace to start from + * @previous: if true find the previous namespace, otherwise the next + * + * Find the next or previous namespace in the same tree as @ns. If + * there is no next/previous namespace, -ENOENT is returned. + */ +struct ns_common *__ns_tree_adjoined_rcu(struct ns_common *ns, + struct ns_tree *ns_tree, bool previous) +{ + struct list_head *list; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "suspicious ns_tree_adjoined_rcu(= ) usage"); + + if (previous) + list =3D rcu_dereference(list_bidir_prev_rcu(&ns->ns_list_node)); + else + list =3D rcu_dereference(list_next_rcu(&ns->ns_list_node)); + if (list_is_head(list, &ns_tree->ns_list)) + return ERR_PTR(-ENOENT); + + VFS_WARN_ON_ONCE(list_entry_rcu(list, struct ns_common, ns_list_node)->op= s->type !=3D ns_tree->type); + + return list_entry_rcu(list, struct ns_common, ns_list_node); +} + +/** + * ns_tree_gen_id - generate a new namespace id + * @ns: namespace to generate id for + * + * Generates a new namespace id and assigns it to the namespace. All + * namespaces types share the same id space and thus can be compared + * directly. IOW, when two ids of two namespace are equal, they are + * identical. + */ +u64 ns_tree_gen_id(struct ns_common *ns) +{ + guard(preempt)(); + ns->ns_id =3D gen_cookie_next(&namespace_cookie); + return ns->ns_id; +} --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 B7C5B3314CB; Wed, 10 Sep 2025 14:38:47 +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=1757515127; cv=none; b=J7eDdcrB3skHJt0EC8KKXJ0shNTWklT9RlKuRHcrV8iKDW96sF/g8tvv1wMz87TgoR/VTUaNjWthc2bFrlOpkDklMDGMA4wAJpJXiiElI4LRCbA4WNOtZ4+S3BjfkrmY0TNhDD2Kone8ttg3gqsjSgwuIqy5BLE9mkLtEqeViQY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515127; c=relaxed/simple; bh=h6pPZagManEkVWvCyxTyeCe5dDf8QrfREZWSn3EHa7o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=svUn1pG2xsE6a3wVIT3FQJRYG1KdC5xFRWCtw6/qCmrOvEEGsQsqKNobqzQ0irOZaMRVYdSdtWjVFWOwKq8GfXk/oYuBVx5lG14ooQZwUJFSH98NOIcvUU5n1WS7Pkb/TFS8nm4ihrjmeJlU8TMd2LIl5zbrggD4bfVtidmdRL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PdCB3yVq; 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="PdCB3yVq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11C9DC4CEF0; Wed, 10 Sep 2025 14:38:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515127; bh=h6pPZagManEkVWvCyxTyeCe5dDf8QrfREZWSn3EHa7o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PdCB3yVq9t0T0x2kBA0rA0PYCOyjE2lxO91lE6ATW/fBUa121rQhN6ibg0YaUHzHS Jib6zzShmwa9TZNNgU/ZugYwA1LYvNz/mBSIEdjtRwtYCPT9qdpF09i+Z73cP3P8pi ppBqKoAZ1ZLwZF/GyVUeM7sDXbK02C7S9E9VeM4+u8woT85I5gcarCGJAQ5kK9wWEM koYNmZl/5o/6hi7TPdcSoKWAaqB2wstzuDkVuLC6+D3HDcc5w9f9KuEUaIAuQLXOyo yyQXCnIZk/O2v6f77noVl3JaAU9uJoTi8g6NkPtgkgMAjfFWoYHu2sGLT3jmCW8MnV mr29U2fIP/+aw== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:02 +0200 Subject: [PATCH 17/32] mnt: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-17-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=10962; i=brauner@kernel.org; h=from:subject:message-id; bh=h6pPZagManEkVWvCyxTyeCe5dDf8QrfREZWSn3EHa7o=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OW48S/48JWpzS+nBz6rMSqYrdnxv9Vey+Tw2vv2T DueKkZrd5SyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExkTzUjw4Z7r3OPFLntzdjG aP9g9n//Yob9O7LDpvM9kTy3dJFe5heGPxxFv5dPcD9+u+rAc99b2/2uqvEp7uATvnChINbPwsn yHT8A X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Move the mount namespace to the generic iterator. This allows us to drop a bunch of members from struct mnt_namespace. t Signed-off-by: Christian Brauner --- fs/mount.h | 10 +--- fs/namespace.c | 141 +++++++++++++----------------------------------------= ---- fs/nsfs.c | 4 +- 3 files changed, 35 insertions(+), 120 deletions(-) diff --git a/fs/mount.h b/fs/mount.h index 97737051a8b9..76bf863c9ae2 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -17,11 +17,7 @@ struct mnt_namespace { }; struct user_namespace *user_ns; struct ucounts *ucounts; - u64 seq; /* Sequence number to prevent loops */ - union { - wait_queue_head_t poll; - struct rcu_head mnt_ns_rcu; - }; + wait_queue_head_t poll; u64 seq_origin; /* Sequence number of origin mount namespace */ u64 event; #ifdef CONFIG_FSNOTIFY @@ -30,8 +26,6 @@ struct mnt_namespace { #endif unsigned int nr_mounts; /* # of mounts in the namespace */ unsigned int pending_mounts; - struct rb_node mnt_ns_tree_node; /* node in the mnt_ns_tree */ - struct list_head mnt_ns_list; /* entry in the sequential list of mounts n= amespace */ refcount_t passive; /* number references not pinning @mounts */ } __randomize_layout; =20 @@ -173,7 +167,7 @@ static inline bool is_local_mountpoint(const struct den= try *dentry) =20 static inline bool is_anon_ns(struct mnt_namespace *ns) { - return ns->seq =3D=3D 0; + return ns->ns.ns_id =3D=3D 0; } =20 static inline bool anon_ns_root(const struct mount *m) diff --git a/fs/namespace.c b/fs/namespace.c index 14c5cdbdd6e1..40a8d75f6b16 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -33,6 +33,7 @@ #include #include #include +#include =20 #include "pnode.h" #include "internal.h" @@ -80,13 +81,10 @@ static DECLARE_RWSEM(namespace_sem); static HLIST_HEAD(unmounted); /* protected by namespace_sem */ static LIST_HEAD(ex_mountpoints); /* protected by namespace_sem */ static struct mnt_namespace *emptied_ns; /* protected by namespace_sem */ -static DEFINE_SEQLOCK(mnt_ns_tree_lock); =20 #ifdef CONFIG_FSNOTIFY LIST_HEAD(notify_list); /* protected by namespace_sem */ #endif -static struct rb_root mnt_ns_tree =3D RB_ROOT; /* protected by mnt_ns_tree= _lock */ -static LIST_HEAD(mnt_ns_list); /* protected by mnt_ns_tree_lock */ =20 enum mount_kattr_flags_t { MOUNT_KATTR_RECURSE =3D (1 << 0), @@ -119,53 +117,12 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock); =20 static inline struct mnt_namespace *node_to_mnt_ns(const struct rb_node *n= ode) { + struct ns_common *ns; + if (!node) return NULL; - return rb_entry(node, struct mnt_namespace, mnt_ns_tree_node); -} - -static int mnt_ns_cmp(struct rb_node *a, const struct rb_node *b) -{ - struct mnt_namespace *ns_a =3D node_to_mnt_ns(a); - struct mnt_namespace *ns_b =3D node_to_mnt_ns(b); - u64 seq_a =3D ns_a->seq; - u64 seq_b =3D ns_b->seq; - - if (seq_a < seq_b) - return -1; - if (seq_a > seq_b) - return 1; - return 0; -} - -static inline void mnt_ns_tree_write_lock(void) -{ - write_seqlock(&mnt_ns_tree_lock); -} - -static inline void mnt_ns_tree_write_unlock(void) -{ - write_sequnlock(&mnt_ns_tree_lock); -} - -static void mnt_ns_tree_add(struct mnt_namespace *ns) -{ - struct rb_node *node, *prev; - - mnt_ns_tree_write_lock(); - node =3D rb_find_add_rcu(&ns->mnt_ns_tree_node, &mnt_ns_tree, mnt_ns_cmp); - /* - * If there's no previous entry simply add it after the - * head and if there is add it after the previous entry. - */ - prev =3D rb_prev(&ns->mnt_ns_tree_node); - if (!prev) - list_add_rcu(&ns->mnt_ns_list, &mnt_ns_list); - else - list_add_rcu(&ns->mnt_ns_list, &node_to_mnt_ns(prev)->mnt_ns_list); - mnt_ns_tree_write_unlock(); - - WARN_ON_ONCE(node); + ns =3D rb_entry(node, struct ns_common, ns_tree_node); + return container_of(ns, struct mnt_namespace, ns); } =20 static void mnt_ns_release(struct mnt_namespace *ns) @@ -181,32 +138,16 @@ DEFINE_FREE(mnt_ns_release, struct mnt_namespace *, i= f (_T) mnt_ns_release(_T)) =20 static void mnt_ns_release_rcu(struct rcu_head *rcu) { - mnt_ns_release(container_of(rcu, struct mnt_namespace, mnt_ns_rcu)); + mnt_ns_release(container_of(rcu, struct mnt_namespace, ns.ns_rcu)); } =20 static void mnt_ns_tree_remove(struct mnt_namespace *ns) { /* remove from global mount namespace list */ - if (!is_anon_ns(ns)) { - mnt_ns_tree_write_lock(); - rb_erase(&ns->mnt_ns_tree_node, &mnt_ns_tree); - list_bidir_del_rcu(&ns->mnt_ns_list); - mnt_ns_tree_write_unlock(); - } - - call_rcu(&ns->mnt_ns_rcu, mnt_ns_release_rcu); -} - -static int mnt_ns_find(const void *key, const struct rb_node *node) -{ - const u64 mnt_ns_id =3D *(u64 *)key; - const struct mnt_namespace *ns =3D node_to_mnt_ns(node); + if (!is_anon_ns(ns)) + ns_tree_remove(ns); =20 - if (mnt_ns_id < ns->seq) - return -1; - if (mnt_ns_id > ns->seq) - return 1; - return 0; + call_rcu(&ns->ns.ns_rcu, mnt_ns_release_rcu); } =20 /* @@ -225,28 +166,21 @@ static int mnt_ns_find(const void *key, const struct = rb_node *node) */ static struct mnt_namespace *lookup_mnt_ns(u64 mnt_ns_id) { - struct mnt_namespace *ns; - struct rb_node *node; - unsigned int seq; + struct mnt_namespace *mnt_ns; + struct ns_common *ns; =20 guard(rcu)(); - do { - seq =3D read_seqbegin(&mnt_ns_tree_lock); - node =3D rb_find_rcu(&mnt_ns_id, &mnt_ns_tree, mnt_ns_find); - if (node) - break; - } while (read_seqretry(&mnt_ns_tree_lock, seq)); - - if (!node) + ns =3D ns_tree_lookup_rcu(mnt_ns_id, CLONE_NEWNS); + if (!ns) return NULL; =20 /* * The last reference count is put with RCU delay so we can * unconditonally acquire a reference here. */ - ns =3D node_to_mnt_ns(node); - refcount_inc(&ns->passive); - return ns; + mnt_ns =3D container_of(ns, struct mnt_namespace, ns); + refcount_inc(&mnt_ns->passive); + return mnt_ns; } =20 static inline void lock_mount_hash(void) @@ -1017,7 +951,7 @@ static inline bool check_anonymous_mnt(struct mount *m= nt) return false; =20 seq =3D mnt->mnt_ns->seq_origin; - return !seq || (seq =3D=3D current->nsproxy->mnt_ns->seq); + return !seq || (seq =3D=3D current->nsproxy->mnt_ns->ns.ns_id); } =20 /* @@ -2155,19 +2089,16 @@ struct ns_common *from_mnt_ns(struct mnt_namespace = *mnt) =20 struct mnt_namespace *get_sequential_mnt_ns(struct mnt_namespace *mntns, b= ool previous) { + struct ns_common *ns; + guard(rcu)(); =20 for (;;) { - struct list_head *list; - - if (previous) - list =3D rcu_dereference(list_bidir_prev_rcu(&mntns->mnt_ns_list)); - else - list =3D rcu_dereference(list_next_rcu(&mntns->mnt_ns_list)); - if (list_is_head(list, &mnt_ns_list)) - return ERR_PTR(-ENOENT); + ns =3D ns_tree_adjoined_rcu(mntns, previous); + if (IS_ERR(ns)) + return ERR_CAST(ns); =20 - mntns =3D list_entry_rcu(list, struct mnt_namespace, mnt_ns_list); + mntns =3D to_mnt_ns(ns); =20 /* * The last passive reference count is put with RCU @@ -2207,7 +2138,7 @@ static bool mnt_ns_loop(struct dentry *dentry) if (!mnt_ns) return false; =20 - return current->nsproxy->mnt_ns->seq >=3D mnt_ns->seq; + return current->nsproxy->mnt_ns->ns.ns_id >=3D mnt_ns->ns.ns_id; } =20 struct mount *copy_tree(struct mount *src_root, struct dentry *dentry, @@ -3070,7 +3001,7 @@ static struct file *open_detached_copy(struct path *p= ath, bool recursive) if (is_anon_ns(src_mnt_ns)) ns->seq_origin =3D src_mnt_ns->seq_origin; else - ns->seq_origin =3D src_mnt_ns->seq; + ns->seq_origin =3D src_mnt_ns->ns.ns_id; } =20 mnt =3D __do_loopback(path, recursive); @@ -4153,15 +4084,6 @@ static void free_mnt_ns(struct mnt_namespace *ns) mnt_ns_tree_remove(ns); } =20 -/* - * Assign a sequence number so we can detect when we attempt to bind - * mount a reference to an older mount namespace into the current - * mount namespace, preventing reference counting loops. A 64bit - * number incrementing at 10Ghz will take 12,427 years to wrap which - * is effectively never, so we can ignore the possibility. - */ -static atomic64_t mnt_ns_seq =3D ATOMIC64_INIT(1); - static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, = bool anon) { struct mnt_namespace *new_ns; @@ -4185,11 +4107,11 @@ static struct mnt_namespace *alloc_mnt_ns(struct us= er_namespace *user_ns, bool a return ERR_PTR(ret); } if (!anon) - new_ns->seq =3D atomic64_inc_return(&mnt_ns_seq); + ns_tree_gen_id(&new_ns->ns); + RB_CLEAR_NODE(&new_ns->ns.ns_tree_node); + INIT_LIST_HEAD(&new_ns->ns.ns_list_node); refcount_set(&new_ns->passive, 1); new_ns->mounts =3D RB_ROOT; - INIT_LIST_HEAD(&new_ns->mnt_ns_list); - RB_CLEAR_NODE(&new_ns->mnt_ns_tree_node); init_waitqueue_head(&new_ns->poll); new_ns->user_ns =3D get_user_ns(user_ns); new_ns->ucounts =3D ucounts; @@ -4275,7 +4197,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags= , struct mnt_namespace *ns, if (pwdmnt) mntput(pwdmnt); =20 - mnt_ns_tree_add(new_ns); + ns_tree_add_raw(new_ns); return new_ns; } =20 @@ -5385,7 +5307,7 @@ static int statmount_sb_source(struct kstatmount *s, = struct seq_file *seq) static void statmount_mnt_ns_id(struct kstatmount *s, struct mnt_namespace= *ns) { s->sm.mask |=3D STATMOUNT_MNT_NS_ID; - s->sm.mnt_ns_id =3D ns->seq; + s->sm.mnt_ns_id =3D ns->ns.ns_id; } =20 static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq) @@ -6090,7 +6012,6 @@ static void __init init_mount_tree(void) ns =3D alloc_mnt_ns(&init_user_ns, true); if (IS_ERR(ns)) panic("Can't allocate initial namespace"); - ns->seq =3D atomic64_inc_return(&mnt_ns_seq); ns->ns.inum =3D PROC_MNT_INIT_INO; m =3D real_mount(mnt); ns->root =3D m; @@ -6105,7 +6026,7 @@ static void __init init_mount_tree(void) set_fs_pwd(current->fs, &root); set_fs_root(current->fs, &root); =20 - mnt_ns_tree_add(ns); + ns_tree_add(ns); } =20 void __init mnt_init(void) diff --git a/fs/nsfs.c b/fs/nsfs.c index 34f0b35d3ead..6f8008177133 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -139,7 +139,7 @@ static int copy_ns_info_to_user(const struct mnt_namesp= ace *mnt_ns, * the size value will be set to the size the kernel knows about. */ kinfo->size =3D min(usize, sizeof(*kinfo)); - kinfo->mnt_ns_id =3D mnt_ns->seq; + kinfo->mnt_ns_id =3D mnt_ns->ns.ns_id; kinfo->nr_mounts =3D READ_ONCE(mnt_ns->nr_mounts); /* Subtract the root mount of the mount namespace. */ if (kinfo->nr_mounts) @@ -221,7 +221,7 @@ static long ns_ioctl(struct file *filp, unsigned int io= ctl, =20 mnt_ns =3D container_of(ns, struct mnt_namespace, ns); idp =3D (__u64 __user *)arg; - id =3D mnt_ns->seq; + id =3D mnt_ns->ns.ns_id; return put_user(id, idp); } case NS_GET_PID_FROM_PIDNS: --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 D293A35AACA; Wed, 10 Sep 2025 14:38:53 +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=1757515134; cv=none; b=TzL1oPAk7pBqwg+BMKrAtqOmC1ejl3oE12gGoxMPRfT2uODqT590AI538tWyS+vSpFLtAmK1+R+acFJI3I4bA4WBR2oz5vUmGBrSVlsqFiRY8TP85H0PnYs4ua1tP3hakATXVwDDNU19PtbTteJZkp7S2MLrJvZSJ2podeRA4No= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515134; c=relaxed/simple; bh=RvFeGI2dajh/uWdk6ZQQzDx/eoO/tdatpOIxDDd51DM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PF65InOs1OvhJJatQs8aorbbF83g6dMQ1o+daFJ4jlYHGEiGtjD6vyxroyK60Otwa4AcCFmtQ0IuHeU9q/H55fVQi2AbyYnfVIE7fOMMn3j+H4wyC/vF16uHc+4qnY4Z4o7slJl2/fZosbqLzWeC1NO1sCrSG5aAbQGCWN7VAM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cNSxojO/; 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="cNSxojO/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18928C4CEEB; Wed, 10 Sep 2025 14:38:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515133; bh=RvFeGI2dajh/uWdk6ZQQzDx/eoO/tdatpOIxDDd51DM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cNSxojO/1LYvZNyxyrmdUEta7H4YZFjaxNW+msfaTODmiPO0f2SzoF852yrPKnceq 79JsILqca50TYBwuzzMG5ZzUDOcal6leKm5OQXJtS/EXl3gP1GI0s0bRQ4JB9D/jD8 Cuq3uflPHIS9ZxPswx6ZZDTevUaEzZKhrq3OP+nqTdYNhPLomIyl1QB8RiliBHSZLF IWnTbYnQPCxaY9ILVPN/eVUY8dkSoZ6w3nPrRyRzwalseaF+qGcH1xqIuwUE8OPPJA gm0EhBiQg2c0x01IKF/qfylwNsONYcZw6Q+uaWNmj7ueBFw/gzyFsmbNZDTcj9jkzm zRT3NLHeHzkbQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:03 +0200 Subject: [PATCH 18/32] cgroup: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-18-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1771; i=brauner@kernel.org; h=from:subject:message-id; bh=RvFeGI2dajh/uWdk6ZQQzDx/eoO/tdatpOIxDDd51DM=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OXobvnJkqPU4Rf6ualKL+tQhfS1P6+yvk2TPzBRe YfSnW8zO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACaSZs7wP9V1whZW5nyvGgkB c53u10t7fIL3P1PbN02ch4PlIttNUUaGm6f85nSxSTJvNpaJ/dz1/OUNteS6SOkXe1L0XnEYC+9 hAgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. Signed-off-by: Christian Brauner Acked-by: Tejun Heo --- kernel/cgroup/cgroup.c | 2 ++ kernel/cgroup/namespace.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 312c6a8b55bb..092e6bf081ed 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -59,6 +59,7 @@ #include #include #include +#include #include =20 #define CREATE_TRACE_POINTS @@ -6312,6 +6313,7 @@ int __init cgroup_init(void) WARN_ON(register_filesystem(&cpuset_fs_type)); #endif =20 + ns_tree_add(&init_cgroup_ns); return 0; } =20 diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c index 0391b6ab0bf1..fc12c416dfeb 100644 --- a/kernel/cgroup/namespace.c +++ b/kernel/cgroup/namespace.c @@ -5,7 +5,7 @@ #include #include #include - +#include =20 /* cgroup namespaces */ =20 @@ -30,16 +30,19 @@ static struct cgroup_namespace *alloc_cgroup_ns(void) ret =3D ns_common_init(&new_ns->ns, &cgroupns_operations, true); if (ret) return ERR_PTR(ret); + ns_tree_add(new_ns); return no_free_ptr(new_ns); } =20 void free_cgroup_ns(struct cgroup_namespace *ns) { + ns_tree_remove(ns); put_css_set(ns->root_cset); dec_cgroup_namespaces(ns->ucounts); put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); - kfree(ns); + /* Concurrent nstree traversal depends on a grace period. */ + kfree_rcu(ns, ns.ns_rcu); } EXPORT_SYMBOL(free_cgroup_ns); =20 --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 E5E7B315D34; Wed, 10 Sep 2025 14:38:59 +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=1757515140; cv=none; b=hPCG86Y30m5wj4XBClTf37uZ3+9vdrGWxjFrB2gJVYRwfOvHVC6t65DoZoZPcf/OaHGT3/yA6zzvxkvKIiSOrUx0jPD8F428PiBkrnnwk2uywTu8LvTCrulHYiVN3hHLtXiBQwH0NjHL+zFm1pjk6B0nqYSpgTJR2o65gSP1/08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515140; c=relaxed/simple; bh=SZfqMg6X4elv6PVRXbYLnsx0Kwlyt6iqs4u/5eCFwbk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=F2nGcXbK50X2vfUlmOXelS/U0Ko/bVf2ejMXO5i1CGCoxNALUJln5TFCEk0R2uD5gEQxFVASVN+09GDfTLIHJ1gnH25RCgs7H9o8OZNZuAZQiVknU/XFvU+wDzujviFMhTyLJKnrf5zFJ/eDeO0rgfwDrGRNpRkJX4s/tNJGKn8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c/kUIU0V; 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="c/kUIU0V" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3913FC4CEEB; Wed, 10 Sep 2025 14:38:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515139; bh=SZfqMg6X4elv6PVRXbYLnsx0Kwlyt6iqs4u/5eCFwbk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=c/kUIU0VAfPGzEOXITyI4Ht1mcsq8Zwr+dRtmaKlgIN0Rt2eXG8Y68R41AwxnQi5H C4j3yNj7nxKR131qjX7KAENZ8u8ZI44qEAyc+xj0uPqYozE/O+610YeCCxndBrvtkk xsrM39vEmU/Rx8zK4+BPVi2PSGBgj1PySSiTTICzBY4bpwJbUIj7XC7ImucQ1emEPG 7xGpRN0uPwg8n+C11rLUbDH5LoCACMH8XpF2Fh5zb0yxm+MqSzUoxE3jy6hrGPrlTW y21O38uZcE8NVjAWA4com46q6dNs+eOgE5fsB5p17mLUu6rAYyF75d78q5XIdDUwac FKv0/Guz8F85Q== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:04 +0200 Subject: [PATCH 19/32] ipc: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-19-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1794; i=brauner@kernel.org; h=from:subject:message-id; bh=SZfqMg6X4elv6PVRXbYLnsx0Kwlyt6iqs4u/5eCFwbk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OWYc+k40zWf1pit+VWXD3k4sdpqzLy1xcVwdtGBa 2bca7x+d5SyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExkRQQjw8PNr+0dQ1w33v35 7KBavgXzkXPRYelhZU3yn6dcnsL0Xp2RofPN5+y/4vM3c04QPBzy4kmaRenxBWdn/fl2wK3q4rU LnvwA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. Signed-off-by: Christian Brauner --- ipc/msgutil.c | 1 + ipc/namespace.c | 3 +++ ipc/shm.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/ipc/msgutil.c b/ipc/msgutil.c index c7be0c792647..bbf61275df41 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -15,6 +15,7 @@ #include #include #include +#include =20 #include "util.h" =20 diff --git a/ipc/namespace.c b/ipc/namespace.c index d4188a88ee57..9f923c1a1eb3 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -15,6 +15,7 @@ #include #include #include +#include #include =20 #include "util.h" @@ -85,6 +86,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_na= mespace *user_ns, =20 sem_init_ns(ns); shm_init_ns(ns); + ns_tree_add(ns); =20 return ns; =20 @@ -201,6 +203,7 @@ void put_ipc_ns(struct ipc_namespace *ns) mq_clear_sbinfo(ns); spin_unlock(&mq_lock); =20 + ns_tree_remove(ns); if (llist_add(&ns->mnt_llist, &free_ipc_list)) schedule_work(&free_ipc_work); } diff --git a/ipc/shm.c b/ipc/shm.c index a9310b6dbbc3..3db36773dd10 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -45,6 +45,7 @@ #include #include #include +#include =20 #include =20 @@ -148,6 +149,7 @@ void shm_exit_ns(struct ipc_namespace *ns) static int __init ipc_ns_init(void) { shm_init_ns(&init_ipc_ns); + ns_tree_add(&init_ipc_ns); return 0; } =20 --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 D15AC315D34; Wed, 10 Sep 2025 14:39:05 +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=1757515146; cv=none; b=f99u2QWa8MoX5zYCQyIE8mvQFDVAw6UxrSy+6iyLUmndedEMjmVGW8sBy6iSLpELVKQJbfRs9H7MywzMOS7W8PbbwpnqRaGWIoyWSjMMjS99v7rl50NdZpI51cpxMl2ko+pklxvKN5CCfmxdtCOQ5LJd51cYhheeIFJ+wfLmd6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515146; c=relaxed/simple; bh=oRiUykJBQlga5zzzIWDVy4MBnAL3DsvpFayNB03RaHE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P8zGtLKmO7/gyZwHyL9Rd8feph/k8/6fZZCYQ+MqehbrAVb0jjA4H5FvWXXHYV1VUTT4OkqDMuY5kkhtH9DSm/d++CxeiXXRCik64BD3JKYGUXqt2EJZ7vAfyrUxSBbT/gz7ebYSk+gWvSZoYO+tdI1XnkAhtoAckyyLIGlRP2Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TFZGoyG/; 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="TFZGoyG/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45032C4CEFB; Wed, 10 Sep 2025 14:39:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515145; bh=oRiUykJBQlga5zzzIWDVy4MBnAL3DsvpFayNB03RaHE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TFZGoyG/GiHUMR8YVToC8GQ1OzLSta6G7n5Awy2McTrAlN/O060DW1PkblGtmiqwD oV+CVvgTzE0qDfswWMZ6o7NDzFx48qSPIB8efED+62Wpzj62CK/c7QA8xMqEfMDuXk ZJ+O+QK9Wvb3clsNCV9/hSOKq3YZEyD50GJ95O0LFlrnd+N0Yjm0NY7p5miBUDcEzg F1+6HgdaV0nItBn6Zzd3C/0HAT1x/wQNYCOZuYz71nzgDwCgqagH52tf7pkY9p81gE Ujuu1HR4a/fVa8eR64Hb9i3M2KhBFEV3ndUiqS+uUKJBtPcanhra0OKm4GT0umqXop ecXBij+QenReA== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:05 +0200 Subject: [PATCH 20/32] net: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-20-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=2327; i=brauner@kernel.org; h=from:subject:message-id; bh=oRiUykJBQlga5zzzIWDVy4MBnAL3DsvpFayNB03RaHE=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OWQrLYIdJ/EVht1x/1xW/KhAN/VDWJ537N9lTM39 laV7XHqKGVhEONikBVTZHFoNwmXW85TsdkoUwNmDisTyBAGLk4BmMgrbkaGtxdWRqu8mHdJZlLM Tof79ZNXtQv9ObT794GW75FLL+qdPsvIsDBWrOH32jnsXExxN/w5Gos48yNq1c8uOmQm7fYi2u4 3KwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. The network namespace has a separate list with different lifetime rules which we can just leave in tact. We have a similar concept for mount namespaces as well where it is on two differenet lists for different purposes. Signed-off-by: Christian Brauner --- include/net/net_namespace.h | 1 + net/core/net_namespace.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 025a7574b275..42075748dff1 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -11,6 +11,7 @@ #include #include #include +#include =20 #include #include diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index dafb3d947043..b85e303400be 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -20,6 +20,7 @@ #include #include #include +#include =20 #include #include @@ -445,7 +446,7 @@ static __net_init int setup_net(struct net *net) LIST_HEAD(net_exit_list); int error =3D 0; =20 - net->net_cookie =3D atomic64_inc_return(&net_aligned_data.net_cookie); + net->net_cookie =3D ns_tree_gen_id(&net->ns); =20 list_for_each_entry(ops, &pernet_list, list) { error =3D ops_init(ops, net); @@ -455,6 +456,7 @@ static __net_init int setup_net(struct net *net) down_write(&net_rwsem); list_add_tail_rcu(&net->list, &net_namespace_list); up_write(&net_rwsem); + ns_tree_add_raw(net); out: return error; =20 @@ -675,8 +677,10 @@ static void cleanup_net(struct work_struct *work) =20 /* Don't let anyone else find us. */ down_write(&net_rwsem); - llist_for_each_entry(net, net_kill_list, cleanup_list) + llist_for_each_entry(net, net_kill_list, cleanup_list) { + ns_tree_remove(net); list_del_rcu(&net->list); + } /* Cache last net. After we unlock rtnl, no one new net * added to net_namespace_list can assign nsid pointer * to a net from net_kill_list (see peernet2id_alloc()). --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 24CB9246774; Wed, 10 Sep 2025 14:39:11 +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=1757515152; cv=none; b=pW6e/gSIN6Osgus2GF8eeAI/Pks0eSiSPeSBfA60h9XE3plhMzZLXcKDArA0NNemqGNEY+oUDpwQ4A9XM9IswrDVw99RGmFrBvgaTCYhjgtRYlEhHL94gObnypi8iNajSlBactOAD6k4LbNvFRNc3Ej1GfihhEjODIKJNOKpDfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515152; c=relaxed/simple; bh=0dDnDj24i/MfTfri3RDCElEpJVNXM5ePPuTvy2KpYKw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ngjgRg+91mvNXVLm79Fp7AswUnhWRBX41+MSIIrPhNBcsYLARlOOlIHeAnSCy6q2kgW8zkQwL/WiJEP7dklH5ir2s4QlVOC1nrTKQG5c2USwYJHiL9NIWLtTDy5WR2nnwAZlv1BpRANaEQhVYUVZYqLWP2dFYN36+eCQbV1s5+4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MnpkegUG; 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="MnpkegUG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30C85C4CEEB; Wed, 10 Sep 2025 14:39:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515151; bh=0dDnDj24i/MfTfri3RDCElEpJVNXM5ePPuTvy2KpYKw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MnpkegUGxO1vBgAdFeYyhSsrw6WMs4xZKi9nh5Zz1O1xhA/kNk6t/Oz8wFZoYaTCC FsL8MRdyinzyIwB8aH0bD/cWXVWv5VpOWuzRejbTmrkB7bjg57y4jVPYL1T5aMAw/H lJRRt2KXaWGA1FgLvSDIqFlZlEvbE8dyUN9BE93u9Ub/mVy6ySxBndeZ66wAAb3W3d /dZzPpKrhVKGrroVV26z7DK3Edayhu+idNZSuv+TDWN1h1N5jXh4CKb2Nwyi2uo3+0 orrp6rVK0A2FCpRr2lc/pfZmMcx2RGlZY+3yxaYfSbPAgemSk/SNUuPWERYUN1Y5mU +e8pr0aDZ+pcg== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:06 +0200 Subject: [PATCH 21/32] pid: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-21-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1243; i=brauner@kernel.org; h=from:subject:message-id; bh=0dDnDj24i/MfTfri3RDCElEpJVNXM5ePPuTvy2KpYKw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OVor/r77utiEc4rArO39PmXXN92fWsco40155W3b 3qW7ONY31HKwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjAR/l8Mf3gq2bhKV7ksCUte a/bqhmlFVklnNfOaxD+pP5nyZT4rsDH897UTYDKfXDJf+FFxca7Czc8hzHm1alM+doRydniuaGp jAAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. Signed-off-by: Christian Brauner --- kernel/pid_namespace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 20ce4052d1c5..228ae20299f9 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "pid_sysctl.h" =20 @@ -122,6 +123,7 @@ static struct pid_namespace *create_pid_namespace(struc= t user_namespace *user_ns ns->memfd_noexec_scope =3D pidns_memfd_noexec_scope(parent_pid_ns); #endif =20 + ns_tree_add(ns); return ns; =20 out_free_inum: @@ -147,6 +149,7 @@ static void delayed_free_pidns(struct rcu_head *p) =20 static void destroy_pid_namespace(struct pid_namespace *ns) { + ns_tree_remove(ns); unregister_pidns_sysctls(ns); =20 ns_free_inum(&ns->ns); @@ -473,6 +476,7 @@ static __init int pid_namespaces_init(void) #endif =20 register_pid_ns_sysctl_table_vm(); + ns_tree_add(&init_pid_ns); return 0; } =20 --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 1ECDC32C331; Wed, 10 Sep 2025 14:39:17 +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=1757515158; cv=none; b=G4oosctqlkedquLfai/C48i96CMyJFjIM8nH6zAKFFonjMYHtg8quCn1UyAbMw1KGwsYHj9h/TEa8AuEzuFBHQ7mXo92ssL8dqM2hMKkAucnCCx+ytNE/5Mbk6hOCTG5h4gY2bKxfIIB+sdtgAnO/PQ3Y7kC7CIC69bombJrE3Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515158; c=relaxed/simple; bh=zqQ6rgi7O/wHq5neMUB7hh99707I6vBoC949QtDxqUc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XBoJ00qNqYgyk3Wk9XQP3Ie2zYctpyOxTjFUR0iG1kZF0aOfi15+Ai7IOo1pulDzsJtCXg/2jLZoD5cJbOkzqXSD97PLlSF7lByI0m4maYl78r7KFYk2JXKgZ4uR/DYUMLMi7IT7rvMPB6bxp6DqLXPuWYlT+dNvFg0hSzGK9IQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P/NiZzhF; 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="P/NiZzhF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2BF6CC4CEF8; Wed, 10 Sep 2025 14:39:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515157; bh=zqQ6rgi7O/wHq5neMUB7hh99707I6vBoC949QtDxqUc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=P/NiZzhFl25Mf35HvvOae3cfDKbIiF66wLTVM+O6VjkuzC4U7wxS3PwmtauvflJob hGG1IODBTWvFzZT/3hf7OZoOZnz+W3UXRNyx1B31mf4Mbnk6qHhq/9OptIzQTIftH7 nJrrrmIosc3XB1AKMLMl6qQdBXG5BkNwg1XH1gkuHc3CykzLR3gyfbnU9S9r9Y2lqQ Y59vZ3C2rcLBBv9uOIKTILx91gOjd/uo5oovceO2M5t00EC8ZoPL3Q/mLEe3Gbp4BJ Ea4+nMWnoz94nT/ikwRSdViLj4xXcV/N+TYAI2evLeqHlsCN1tnE1iMXapYQ0TbRNZ c5WSoQBRqeabg== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:07 +0200 Subject: [PATCH 22/32] time: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-22-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=3233; i=brauner@kernel.org; h=from:subject:message-id; bh=zqQ6rgi7O/wHq5neMUB7hh99707I6vBoC949QtDxqUc=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OUUDd1psjh5jsGCtbNjzjmGfFXWvW+WlyHdtEs/t FY17Cp/RykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwEQ+CDL8d+veZ+Pp/Z57Tbem 8hYZ64+8P/bvDDt79MksPpab3vskYxn+e5/xfDdh0eSDgqt0mOYYsmt9Z14zX5Wt04EjpqR6jeg PBgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. Signed-off-by: Christian Brauner Reviewed-by: Thomas Gleixner --- include/linux/time_namespace.h | 5 +++++ init/main.c | 2 ++ kernel/time/namespace.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h index bb2c52f4fc94..7f6af7a9771e 100644 --- a/include/linux/time_namespace.h +++ b/include/linux/time_namespace.h @@ -33,6 +33,7 @@ struct time_namespace { extern struct time_namespace init_time_ns; =20 #ifdef CONFIG_TIME_NS +void __init time_ns_init(void); extern int vdso_join_timens(struct task_struct *task, struct time_namespace *ns); extern void timens_commit(struct task_struct *tsk, struct time_namespace *= ns); @@ -108,6 +109,10 @@ static inline ktime_t timens_ktime_to_host(clockid_t c= lockid, ktime_t tim) } =20 #else +static inline void __init time_ns_init(void) +{ +} + static inline int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) { diff --git a/init/main.c b/init/main.c index 0ee0ee7b7c2c..e7d2c57c65a7 100644 --- a/init/main.c +++ b/init/main.c @@ -103,6 +103,7 @@ #include #include #include +#include #include =20 #include @@ -1072,6 +1073,7 @@ void start_kernel(void) fork_init(); proc_caches_init(); uts_ns_init(); + time_ns_init(); key_init(); security_init(); dbg_late_init(); diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 80b3d2ce2fb6..408f60d0a3b6 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -88,7 +89,7 @@ static struct time_namespace *clone_time_ns(struct user_n= amespace *user_ns, goto fail; =20 err =3D -ENOMEM; - ns =3D kmalloc(sizeof(*ns), GFP_KERNEL_ACCOUNT); + ns =3D kzalloc(sizeof(*ns), GFP_KERNEL_ACCOUNT); if (!ns) goto fail_dec; =20 @@ -104,6 +105,7 @@ static struct time_namespace *clone_time_ns(struct user= _namespace *user_ns, ns->user_ns =3D get_user_ns(user_ns); ns->offsets =3D old_ns->offsets; ns->frozen_offsets =3D false; + ns_tree_add(ns); return ns; =20 fail_free_page: @@ -250,11 +252,13 @@ static void timens_set_vvar_page(struct task_struct *= task, =20 void free_time_ns(struct time_namespace *ns) { + ns_tree_remove(ns); dec_time_namespaces(ns->ucounts); put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); __free_page(ns->vvar_page); - kfree(ns); + /* Concurrent nstree traversal depends on a grace period. */ + kfree_rcu(ns, ns.ns_rcu); } =20 static struct time_namespace *to_time_ns(struct ns_common *ns) @@ -487,3 +491,8 @@ struct time_namespace init_time_ns =3D { .ns.ops =3D &timens_operations, .frozen_offsets =3D true, }; + +void __init time_ns_init(void) +{ + ns_tree_add(&init_time_ns); +} --=20 2.47.3 From nobody Wed Sep 10 23:39:17 2025 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 18CCD3375C2; Wed, 10 Sep 2025 14:39:23 +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=1757515164; cv=none; b=Cr0GhzwGQqmv023OIS7gCQyr/OFKdtXm8/FPCPHpz6tsSiB/50hr4YMfJaOQXrWeeL6Kg8YQSOu7no2tIeVm7oh6f8UIC12QMlEKeSpSkMzerOMoN7PWUFsoMg3ZAOkQYhVWZ1nHgyo0JiDWHvRiyt/A6UJ7y5UBeC1fCnsUTn4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515164; c=relaxed/simple; bh=+TCT1A2PXWX9oafBWWfg0Q4e6cJwE6zfwnH7FmipbWw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=adwlvMbNh7szkvxzvYbTyaA5qAksdFmUXWcWsS9XY7K9aoEvB2s1G5gMlZP14V8+rjtmQOdtJKwPI1oAdj6i81x2cNZMrSdCaGrN7Lh0BqMSJVjjscY5BHgrvvPRRMeRD8SbpgpugCuzBgwxGkzJ7Q9jPdb1ZCn5BVEghlH9TGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kFS4cfCo; 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="kFS4cfCo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 157E7C4CEF9; Wed, 10 Sep 2025 14:39:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515163; bh=+TCT1A2PXWX9oafBWWfg0Q4e6cJwE6zfwnH7FmipbWw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kFS4cfCotJxoY26zSFArrXF+MNIMxAQaiiE5m9sw/4RzgIqxe52wdB3aTBbJWFJ3N Yp+X/rKAT4YMMCRAKJGfxmLCk1wlNmpLZF8XtT66gomAMz8GXC0x9HpxGdrld6OHuj X7hki8hDcxCKeXDiCgHhao6Fx9y8NZQbwnczOMBRsoxYSagaQQq3DgCsoyWJersyR0 NCTB5TFTRpxyfv22j2alGnpZ4J1RyaUoROUoDX2SpEP+Y8BNpOORAe023mapuQJ9a4 JfUD1hD9NHRJL6vfJ7eceG9CJV7NaJBCFb2wZTn4oliqBfiBiTWmjRvwT0DIeBcH9S ojM/IgV2FnNMQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:08 +0200 Subject: [PATCH 23/32] userns: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-23-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1871; i=brauner@kernel.org; h=from:subject:message-id; bh=+TCT1A2PXWX9oafBWWfg0Q4e6cJwE6zfwnH7FmipbWw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OX0e/h4yyanU4d/frgY96fu4xeWAKfrbst6esKFZ K7MmHs5oqOUhUGMi0FWTJHFod0kXG45T8Vmo0wNmDmsTCBDGLg4BWAiBzcw/M9edPK/+sm/y2/K J1scCze4f/jf8cwQ840MTzZ32SdraTxi+O88ybOk+EbSi90Jc9ayHLLS+Sp24oH5juyTu+wSDdO SvNkB X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. Signed-off-by: Christian Brauner --- kernel/user_namespace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 98f4fe84d039..ade5b6806c5c 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -21,6 +21,7 @@ #include #include #include +#include =20 static struct kmem_cache *user_ns_cachep __ro_after_init; static DEFINE_MUTEX(userns_state_mutex); @@ -158,6 +159,7 @@ int create_user_ns(struct cred *new) goto fail_keyring; =20 set_cred_user_ns(new, ns); + ns_tree_add(ns); return 0; fail_keyring: #ifdef CONFIG_PERSISTENT_KEYRINGS @@ -200,6 +202,7 @@ static void free_user_ns(struct work_struct *work) do { struct ucounts *ucounts =3D ns->ucounts; parent =3D ns->parent; + ns_tree_remove(ns); if (ns->gid_map.nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) { kfree(ns->gid_map.forward); kfree(ns->gid_map.reverse); @@ -218,7 +221,8 @@ static void free_user_ns(struct work_struct *work) retire_userns_sysctls(ns); key_free_user_ns(ns); ns_free_inum(&ns->ns); - kmem_cache_free(user_ns_cachep, ns); + /* Concurrent nstree traversal depends on a grace period. */ + kfree_rcu(ns, ns.ns_rcu); dec_user_namespaces(ucounts); ns =3D parent; } while (refcount_dec_and_test(&parent->ns.count)); @@ -1412,6 +1416,7 @@ const struct proc_ns_operations userns_operations =3D= { static __init int user_namespaces_init(void) { user_ns_cachep =3D KMEM_CACHE(user_namespace, SLAB_PANIC | SLAB_ACCOUNT); + ns_tree_add(&init_user_ns); return 0; } subsys_initcall(user_namespaces_init); --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 22C3932C33B; Wed, 10 Sep 2025 14:39:29 +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=1757515170; cv=none; b=UzkpgAtrKx72dxPecmeFc+7ZSHxQv+Mr9SY0AGl1pdpk5EjuSeShkjsWrxQURB/euU2O5obOdhiUzcYH26CUw9O2g5ugvBuhsi3t7kXp/2ve/SONM2MPOGnDE12p7uZmPUDAqPX/sy05vz965Zkbo1deXurJA1NNr/SrytzHBik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515170; c=relaxed/simple; bh=P3IhXUPNps89Uph+zReDw5Ax8vIvkOOMRZK7+M5sDUk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BFGYlHGQ+cvct3/R+1rWWX6HCwnqzkorrYPHUSIUG2UdjV8xLOafzsLMsET9if2OhmxN+y00ehm5Je4GP5XYN3iHrbtHNX3kKe/aQ/cg737rLN3B4hFfz7oAIt5xyClJgWXv8Ak0jZoHwxjEYnEuSXzvhYzmEzjxQ0Q9tjT51Rc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BNpamWZu; 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="BNpamWZu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2125AC4CEEB; Wed, 10 Sep 2025 14:39:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515169; bh=P3IhXUPNps89Uph+zReDw5Ax8vIvkOOMRZK7+M5sDUk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BNpamWZu3dbeqglrQf1JNLGdbWHgewpInbIniGQuH9tmBft7dNqMLJ1A99X9o1Rc/ verH5pMX3btqjmLVJ2lXhp6c0ndO0KwiSRXq+/3Ywv8MO/hZSmrHA44Dptuh8K/XJm abkeP6t4KovU7hvXq1DqvI5q2t3kWAw1ekqXdRSunMeMGw6AzVnEYRG54OZP2Q3jjt 41Ypd1tfF8Y+rQWwKGNpAQv37pI9tIe/cXDv5SWiKsqcndNbR3F4Q3Oqf/dHcP9uKu IUu+ml0+mGzDyZF1TKMRSr7OK0gVGZwAvEq4XFTMUv31ey8rD7zdC7mV5JyCtd7qgl M5m6xW9y4yOlg== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:09 +0200 Subject: [PATCH 24/32] uts: support iterator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-24-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1533; i=brauner@kernel.org; h=from:subject:message-id; bh=P3IhXUPNps89Uph+zReDw5Ax8vIvkOOMRZK7+M5sDUk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OWM+JV0QFFvN0P7nLgZWmtOTuu8ySX7/53Z/czC0 MJ/VrtKO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACYS4M3I0FtivvSHmPUnzqsf Tt05c7Zb3a12Q/WOp2JSH7cslmOzM2X4n2el0y/bfiaCOSDdtfXxjhzVlMC1e3z2mdv7Ttj7dsM aJgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Support the generic namespace iterator and lookup infrastructure to support file handles for namespaces. Signed-off-by: Christian Brauner --- kernel/utsname.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/utsname.c b/kernel/utsname.c index 02037010b378..64155417ae0c 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -13,6 +13,7 @@ #include #include #include +#include #include =20 static struct kmem_cache *uts_ns_cache __ro_after_init; @@ -58,6 +59,7 @@ static struct uts_namespace *clone_uts_ns(struct user_nam= espace *user_ns, memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); ns->user_ns =3D get_user_ns(user_ns); up_read(&uts_sem); + ns_tree_add(ns); return ns; =20 fail_free: @@ -93,10 +95,12 @@ struct uts_namespace *copy_utsname(unsigned long flags, =20 void free_uts_ns(struct uts_namespace *ns) { + ns_tree_remove(ns); dec_uts_namespaces(ns->ucounts); put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); - kmem_cache_free(uts_ns_cache, ns); + /* Concurrent nstree traversal depends on a grace period. */ + kfree_rcu(ns, ns.ns_rcu); } =20 static inline struct uts_namespace *to_uts_ns(struct ns_common *ns) @@ -162,4 +166,5 @@ void __init uts_ns_init(void) offsetof(struct uts_namespace, name), sizeof_field(struct uts_namespace, name), NULL); + ns_tree_add(&init_uts_ns); } --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 50D7632C312; Wed, 10 Sep 2025 14:39: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=1757515176; cv=none; b=FbX9yBOq05CcIT25tO+o2ZtZJELaFXJOczMZroDRgBSuLqXSd4dBEalPgMK+LREeiODj0J4CaTX3djv6MmC3PRTxH9WCb+2fRVYZtgDaxj32Y6SoxsPqDxEvvsaQuB32To0vJmkY6v62gkBT7KtBVL1muArjTVgSOFY2Kt0uXrs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515176; c=relaxed/simple; bh=IZBqhhmgsdKD2MSFlaiE8lz6qiN3IyHlYbx4M51Kx84=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qtfiWe0qdA70j+qA33xXjmpRgrzNCp/OarKXAIegHWowkoK9EGfXBdfFUOxALQDEyYJRsJ6F4PFba1ZxbDYQKmuhu9aDCcOnLyIIAxvqDCbYupzREJEM+HPkgpAvjuWBb5xeuwdQnQCV5LS9VUwJO42LwGYnmR2kKmd3xBcn3PM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XwjpvgeA; 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="XwjpvgeA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2AED0C4CEF8; Wed, 10 Sep 2025 14:39:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515175; bh=IZBqhhmgsdKD2MSFlaiE8lz6qiN3IyHlYbx4M51Kx84=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XwjpvgeAvKerYcTwQ3qKUxDm+uYFGTmQxfpAB/lYCgi9LfyVmLsqRWlurjlP+8xp8 AoqSLl9FOA2HECcba5PRE5GTes1dutL15LxoIT4UUbf11A9Z+QweEkww6047gjyofp 8KGL7p8KfCj7eJj4QnECbvNg4up/suDKaBwRewRwj5jAjNm0+xsJ0Orl8+DPlrOS/Y DTdBJOu5Hv7lFMmrN+1qy6mqBacuWLy0wR72QxEU3hgmf9PphOvIPFIVKwTXG5hLPy v0IItvTeg3pF69fe8NuMpu6syrRaR2uEZJJy/d0SSVFLfpziEJ6bjxoyQkjapG56ek PJhlw30xXJThA== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:10 +0200 Subject: [PATCH 25/32] ns: add to__ns() to respective headers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-25-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=8276; i=brauner@kernel.org; h=from:subject:message-id; bh=IZBqhhmgsdKD2MSFlaiE8lz6qiN3IyHlYbx4M51Kx84=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OU8r9/wYd4zq+/fu0TbZ6ceaW8K/925OeJtVuejb aqMx3JOdZSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEyk+xDDX1G92juz9Crfdncm Muo95+ePWLWVsaV9QRbPz12XFF0zrzH84fjtNckopN3wYvvfmF+3PPIPvW7b+EKl70Cryb3iA6F crAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Every namespace type has a container_of(ns, , ns) static inline function that is currently not exposed in the header. So we have a bunch of places that open-code it via container_of(). Move it to the headers so we can use it directly. Signed-off-by: Christian Brauner Reviewed-by: Aleksa Sarai --- include/linux/cgroup.h | 5 +++++ include/linux/ipc_namespace.h | 5 +++++ include/linux/pid_namespace.h | 5 +++++ include/linux/time_namespace.h | 4 ++++ include/linux/user_namespace.h | 5 +++++ include/linux/utsname.h | 5 +++++ include/net/net_namespace.h | 5 +++++ ipc/namespace.c | 5 ----- kernel/cgroup/namespace.c | 5 ----- kernel/pid_namespace.c | 5 ----- kernel/time/namespace.c | 5 ----- kernel/user_namespace.c | 5 ----- kernel/utsname.c | 5 ----- net/core/net_namespace.c | 5 ----- 14 files changed, 34 insertions(+), 35 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index b18fb5fcb38e..9ca25346f7cb 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -794,6 +794,11 @@ extern struct cgroup_namespace init_cgroup_ns; =20 #ifdef CONFIG_CGROUPS =20 +static inline struct cgroup_namespace *to_cg_ns(struct ns_common *ns) +{ + return container_of(ns, struct cgroup_namespace, ns); +} + void free_cgroup_ns(struct cgroup_namespace *ns); =20 struct cgroup_namespace *copy_cgroup_ns(unsigned long flags, diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index e8240cf2611a..924e4754374f 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h @@ -129,6 +129,11 @@ static inline int mq_init_ns(struct ipc_namespace *ns)= { return 0; } #endif =20 #if defined(CONFIG_IPC_NS) +static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns) +{ + return container_of(ns, struct ipc_namespace, ns); +} + extern struct ipc_namespace *copy_ipcs(unsigned long flags, struct user_namespace *user_ns, struct ipc_namespace *ns); =20 diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 7c67a5811199..ba0efc8c8596 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -54,6 +54,11 @@ extern struct pid_namespace init_pid_ns; #define PIDNS_ADDING (1U << 31) =20 #ifdef CONFIG_PID_NS +static inline struct pid_namespace *to_pid_ns(struct ns_common *ns) +{ + return container_of(ns, struct pid_namespace, ns); +} + static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) { if (ns !=3D &init_pid_ns) diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h index 7f6af7a9771e..a47a4ce4183e 100644 --- a/include/linux/time_namespace.h +++ b/include/linux/time_namespace.h @@ -33,6 +33,10 @@ struct time_namespace { extern struct time_namespace init_time_ns; =20 #ifdef CONFIG_TIME_NS +static inline struct time_namespace *to_time_ns(struct ns_common *ns) +{ + return container_of(ns, struct time_namespace, ns); +} void __init time_ns_init(void); extern int vdso_join_timens(struct task_struct *task, struct time_namespace *ns); diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index a0bb6d012137..a09056ad090e 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -168,6 +168,11 @@ static inline void set_userns_rlimit_max(struct user_n= amespace *ns, =20 #ifdef CONFIG_USER_NS =20 +static inline struct user_namespace *to_user_ns(struct ns_common *ns) +{ + return container_of(ns, struct user_namespace, ns); +} + static inline struct user_namespace *get_user_ns(struct user_namespace *ns) { if (ns) diff --git a/include/linux/utsname.h b/include/linux/utsname.h index bf7613ba412b..5d34c4f0f945 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h @@ -30,6 +30,11 @@ struct uts_namespace { extern struct uts_namespace init_uts_ns; =20 #ifdef CONFIG_UTS_NS +static inline struct uts_namespace *to_uts_ns(struct ns_common *ns) +{ + return container_of(ns, struct uts_namespace, ns); +} + static inline void get_uts_ns(struct uts_namespace *ns) { refcount_inc(&ns->ns.count); diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 42075748dff1..b9c5f6c7ee1e 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -263,6 +263,11 @@ void ipx_unregister_sysctl(void); #ifdef CONFIG_NET_NS void __put_net(struct net *net); =20 +static inline struct net *to_net_ns(struct ns_common *ns) +{ + return container_of(ns, struct net, ns); +} + /* Try using get_net_track() instead */ static inline struct net *get_net(struct net *net) { diff --git a/ipc/namespace.c b/ipc/namespace.c index 9f923c1a1eb3..89588819956b 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -209,11 +209,6 @@ void put_ipc_ns(struct ipc_namespace *ns) } } =20 -static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns) -{ - return container_of(ns, struct ipc_namespace, ns); -} - static struct ns_common *ipcns_get(struct task_struct *task) { struct ipc_namespace *ns =3D NULL; diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c index fc12c416dfeb..5a327914b565 100644 --- a/kernel/cgroup/namespace.c +++ b/kernel/cgroup/namespace.c @@ -89,11 +89,6 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long fl= ags, return new_ns; } =20 -static inline struct cgroup_namespace *to_cg_ns(struct ns_common *ns) -{ - return container_of(ns, struct cgroup_namespace, ns); -} - static int cgroupns_install(struct nsset *nsset, struct ns_common *ns) { struct nsproxy *nsproxy =3D nsset->nsproxy; diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 228ae20299f9..9b327420309e 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -345,11 +345,6 @@ int reboot_pid_ns(struct pid_namespace *pid_ns, int cm= d) return 0; } =20 -static inline struct pid_namespace *to_pid_ns(struct ns_common *ns) -{ - return container_of(ns, struct pid_namespace, ns); -} - static struct ns_common *pidns_get(struct task_struct *task) { struct pid_namespace *ns; diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 408f60d0a3b6..20b65f90549e 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -261,11 +261,6 @@ void free_time_ns(struct time_namespace *ns) kfree_rcu(ns, ns.ns_rcu); } =20 -static struct time_namespace *to_time_ns(struct ns_common *ns) -{ - return container_of(ns, struct time_namespace, ns); -} - static struct ns_common *timens_get(struct task_struct *task) { struct time_namespace *ns =3D NULL; diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index ade5b6806c5c..cfb0e28f2779 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -1325,11 +1325,6 @@ bool current_in_userns(const struct user_namespace *= target_ns) } EXPORT_SYMBOL(current_in_userns); =20 -static inline struct user_namespace *to_user_ns(struct ns_common *ns) -{ - return container_of(ns, struct user_namespace, ns); -} - static struct ns_common *userns_get(struct task_struct *task) { struct user_namespace *user_ns; diff --git a/kernel/utsname.c b/kernel/utsname.c index 64155417ae0c..a682830742d3 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -103,11 +103,6 @@ void free_uts_ns(struct uts_namespace *ns) kfree_rcu(ns, ns.ns_rcu); } =20 -static inline struct uts_namespace *to_uts_ns(struct ns_common *ns) -{ - return container_of(ns, struct uts_namespace, ns); -} - static struct ns_common *utsns_get(struct task_struct *task) { struct uts_namespace *ns =3D NULL; diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b85e303400be..ca9b06f3925f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -1539,11 +1539,6 @@ static struct ns_common *netns_get(struct task_struc= t *task) return net ? &net->ns : NULL; } =20 -static inline struct net *to_net_ns(struct ns_common *ns) -{ - return container_of(ns, struct net, ns); -} - static void netns_put(struct ns_common *ns) { put_net(to_net_ns(ns)); --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 D7AD233769E; Wed, 10 Sep 2025 14:39:41 +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=1757515182; cv=none; b=Oz240tzCsA6yQOlvJIT+/hGIXCR6Ep8YZkoDNaa2OXzS3109+8KDnJ/mbewTsuUwUcB7kWIFkjLK17Mr8nZnXO55ym6xsPMcFiqOI0W3zo82qiJEA1WB3kbMzP3PZiJuzWwngLYDUed2weKO5mND8YTyiM+Cdt3SN/GKk317WK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515182; c=relaxed/simple; bh=V2knpP68ov2ShGssBrReM+o3kSt82DUPUH0cG76sD7U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LYRSyYMTKGYivarxn7MgJ1Eb/EcFPKgUBaopD6MQVAr6o6nMrxFLNn4fFE44ba0ZFgTpgi2v7xYd7ygmwugBnJfmgyrVZNwmv5Y4ryhcyQb0JQANHKee5pxkLLSdSfFS9v19RlYqhOGE2dpFeH3eyaSnaBrtRcTCuAKDJ7aaeKw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pink4nL/; 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="Pink4nL/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 382D1C4CEEB; Wed, 10 Sep 2025 14:39:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515181; bh=V2knpP68ov2ShGssBrReM+o3kSt82DUPUH0cG76sD7U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Pink4nL/AOO5/6CZ0au4nS9W1zntK1GrKZuLW+/1kJG2M6ji5trlTqaRBD32aQ7Qx 4gdLqs05aoIMOANtEtjQaMdXX8JofONBmfr4c9dewaKgVs7q1xCOmA0N8g9c8kXfhs +3tBDWJYMSDiRp5q4nWue5wQmEqHlW94MALNhFsUznLoqSC2z/DY568jYqh7O4jKP+ Qdpgf3QSl8wjEsSLx+BvjP18uyx11fqgTly7qH4vJIJ78CpshnqtExUKCqygKYLI/N BiXGR8qK4Zke7iedLkgI4WOc849vupZZfLfVJ7hBJKw6KZ3Q8EW2uuBLrscVxYOlrr 6J/aS2K/Z1AIA== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:11 +0200 Subject: [PATCH 26/32] nsfs: add current_in_namespace() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-26-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1554; i=brauner@kernel.org; h=from:subject:message-id; bh=V2knpP68ov2ShGssBrReM+o3kSt82DUPUH0cG76sD7U=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OV89GIKW4OOLkvS6/JpV8qjrklNmNks9fnFRwOty TXb/nRLdpSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEwk1IGRYaNqjWjkdgdB83US mwIYE1853eOcyfWURZ5lZ8jmju1xVQz/lNa+VtmnEb/V+qqvYVn5wu97ZzNNL1rZn6dybp/cJXY hVgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a helper to easily check whether a given namespace is the caller's current namespace. This is currently open-coded in a lot of places. Simply switch on the type and compare the results. Signed-off-by: Christian Brauner Reviewed-by: Aleksa Sarai --- include/linux/nsfs.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/linux/nsfs.h b/include/linux/nsfs.h index fb84aa538091..e5a5fa83d36b 100644 --- a/include/linux/nsfs.h +++ b/include/linux/nsfs.h @@ -5,6 +5,8 @@ #define _LINUX_NSFS_H =20 #include +#include +#include =20 struct path; struct task_struct; @@ -22,5 +24,17 @@ int ns_get_name(char *buf, size_t size, struct task_stru= ct *task, const struct proc_ns_operations *ns_ops); void nsfs_init(void); =20 -#endif /* _LINUX_NSFS_H */ +#define __current_namespace_from_type(__ns) \ + _Generic((__ns), \ + struct cgroup_namespace *: current->nsproxy->cgroup_ns, \ + struct ipc_namespace *: current->nsproxy->ipc_ns, \ + struct net *: current->nsproxy->net_ns, \ + struct pid_namespace *: task_active_pid_ns(current), \ + struct mnt_namespace *: current->nsproxy->mnt_ns, \ + struct time_namespace *: current->nsproxy->time_ns, \ + struct user_namespace *: current_user_ns(), \ + struct uts_namespace *: current->nsproxy->uts_ns) + +#define current_in_namespace(__ns) (__current_namespace_from_type(__ns) = =3D=3D __ns) =20 +#endif /* _LINUX_NSFS_H */ --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 C85823376B7; Wed, 10 Sep 2025 14:39:47 +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=1757515187; cv=none; b=sJXGeLouICKhR1lKr2WGPc1encW3ZFDjbndQX3f50bRW6Zvtpt7QtcaU23ZYPGVLs33k0v35jGKEl7ypIOAaEPx1vxr2tT7a557I5/JY36hknRqxUaCKa6MM95udRBTVUKiN8KVB6I/sjJw900bwl7PJGLpnXDgl9vjQiNqoguk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515187; c=relaxed/simple; bh=93zobprarsfhaK9wvmZuL2ifa/e6eX+56DGLdNBvdEs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qpBHDIrxH97n7pCo5zk2LlBtj76EC8ou0FaPYAhkJnqHkxucpsgh5QBFW5INMh3DlKNRu3BP6KkujCOWdB7RrOCmQYyOkKQzO38UivyDcO2aosYyVvp53L9NtWr1gBdoDJCiisfxjbHtuWU6+HrzQPE6ZcmNl0HRlTKqd+ocG9s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DlBot1gJ; 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="DlBot1gJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 32055C4CEEB; Wed, 10 Sep 2025 14:39:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515187; bh=93zobprarsfhaK9wvmZuL2ifa/e6eX+56DGLdNBvdEs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=DlBot1gJxFjjAKDUQ/PtIVM1jO+3PybmmPsK1Ti+faY27DvW+B1KoimKXXp8we3KY WXaYTx+Oxd4xjYP9DM0WOsp/tT1KhN3PPBWh4QB7N3ECdMAV2WGjzWPu3EYDcEd4wD Rk0+kkOz1LwQUFG2WeOgB9FmfYFnThIrMPOcgDcIAsVFubTrt6OShkN6f9nvTYqdxU 7kh+vr6nefyQQem6l7fktJVW1JJsca6HrB39XCjtJXgSIHGRVPOkUi7GjwRh66C3tt odQvngaDW+1R2h8EGmbXWZ/jI0TVQrpsI2ST0RP8UCTf0QfWiDDDfqGCwZFFH2RHKO XUn9Wy4SqSOrQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:12 +0200 Subject: [PATCH 27/32] nsfs: support file handles Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-27-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=6320; i=brauner@kernel.org; h=from:subject:message-id; bh=93zobprarsfhaK9wvmZuL2ifa/e6eX+56DGLdNBvdEs=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OX8dFdnovh6C+d/3LyHF8mbq0/ZtnjN6zuP2/e2l Xmz/myw6ShlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZiI7DRGht/R22f4Bu2OUuba eTq3P1bgX5Wa7u+fNi9+nr/uGnxphRvD/1oO3hynDbYzw58IFnAx8vDuVbpaUrp6Dd8s/tO/jZS E2AA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 A while ago we added support for file handles to pidfs so pidfds can be encoded and decoded as file handles. Userspace has adopted this quickly and it's proven very useful. Pidfd file handles are exhaustive meaning they don't require a handle on another pidfd to pass to open_by_handle_at() so it can derive the filesystem to decode in. Implement the exhaustive file handles for namespaces as well. Signed-off-by: Christian Brauner Reviewed-by: Amir Goldstein --- fs/nsfs.c | 176 +++++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/exportfs.h | 6 ++ 2 files changed, 182 insertions(+) diff --git a/fs/nsfs.c b/fs/nsfs.c index 6f8008177133..a1585a2f4f03 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -13,6 +13,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include =20 #include "mount.h" #include "internal.h" @@ -417,12 +423,182 @@ static const struct stashed_operations nsfs_stashed_= ops =3D { .put_data =3D nsfs_put_data, }; =20 +struct nsfs_fid { + u64 ns_id; + u32 ns_type; + u32 ns_inum; +} __attribute__ ((packed)); + +#define NSFS_FID_SIZE (sizeof(struct nsfs_fid) / sizeof(u32)) + +static int nsfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, + struct inode *parent) +{ + struct nsfs_fid *fid =3D (struct nsfs_fid *)fh; + struct ns_common *ns =3D inode->i_private; + int len =3D *max_len; + + /* + * TODO: + * For hierarchical namespaces we should start to encode the + * parent namespace. Then userspace can walk a namespace + * hierarchy purely based on file handles. + */ + if (parent) + return FILEID_INVALID; + + if (len < NSFS_FID_SIZE) { + *max_len =3D NSFS_FID_SIZE; + return FILEID_INVALID; + } + + len =3D NSFS_FID_SIZE; + + fid->ns_id =3D ns->ns_id; + fid->ns_type =3D ns->ops->type; + fid->ns_inum =3D inode->i_ino; + *max_len =3D len; + return FILEID_NSFS; +} + +static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid= *fh, + int fh_len, int fh_type) +{ + struct path path __free(path_put) =3D {}; + struct nsfs_fid *fid =3D (struct nsfs_fid *)fh; + struct user_namespace *owning_ns =3D NULL; + struct ns_common *ns; + int ret; + + if (fh_len < NSFS_FID_SIZE) + return NULL; + + switch (fh_type) { + case FILEID_NSFS: + break; + default: + return NULL; + } + + scoped_guard(rcu) { + ns =3D ns_tree_lookup_rcu(fid->ns_id, fid->ns_type); + if (!ns) + return NULL; + + VFS_WARN_ON_ONCE(ns->ns_id !=3D fid->ns_id); + VFS_WARN_ON_ONCE(ns->ops->type !=3D fid->ns_type); + VFS_WARN_ON_ONCE(ns->inum !=3D fid->ns_inum); + + if (!refcount_inc_not_zero(&ns->count)) + return NULL; + } + + switch (ns->ops->type) { +#ifdef CONFIG_CGROUPS + case CLONE_NEWCGROUP: + if (!current_in_namespace(to_cg_ns(ns))) + owning_ns =3D to_cg_ns(ns)->user_ns; + break; +#endif +#ifdef CONFIG_IPC_NS + case CLONE_NEWIPC: + if (!current_in_namespace(to_ipc_ns(ns))) + owning_ns =3D to_ipc_ns(ns)->user_ns; + break; +#endif + case CLONE_NEWNS: + if (!current_in_namespace(to_mnt_ns(ns))) + owning_ns =3D to_mnt_ns(ns)->user_ns; + break; +#ifdef CONFIG_NET_NS + case CLONE_NEWNET: + if (!current_in_namespace(to_net_ns(ns))) + owning_ns =3D to_net_ns(ns)->user_ns; + break; +#endif +#ifdef CONFIG_PID_NS + case CLONE_NEWPID: + if (!current_in_namespace(to_pid_ns(ns))) { + owning_ns =3D to_pid_ns(ns)->user_ns; + } else if (!READ_ONCE(to_pid_ns(ns)->child_reaper)) { + ns->ops->put(ns); + return ERR_PTR(-EPERM); + } + break; +#endif +#ifdef CONFIG_TIME_NS + case CLONE_NEWTIME: + if (!current_in_namespace(to_time_ns(ns))) + owning_ns =3D to_time_ns(ns)->user_ns; + break; +#endif +#ifdef CONFIG_USER_NS + case CLONE_NEWUSER: + if (!current_in_namespace(to_user_ns(ns))) + owning_ns =3D to_user_ns(ns); + break; +#endif +#ifdef CONFIG_UTS_NS + case CLONE_NEWUTS: + if (!current_in_namespace(to_uts_ns(ns))) + owning_ns =3D to_uts_ns(ns)->user_ns; + break; +#endif + default: + return ERR_PTR(-EOPNOTSUPP); + } + + if (owning_ns && !ns_capable(owning_ns, CAP_SYS_ADMIN)) { + ns->ops->put(ns); + return ERR_PTR(-EPERM); + } + + /* path_from_stashed() unconditionally consumes the reference. */ + ret =3D path_from_stashed(&ns->stashed, nsfs_mnt, ns, &path); + if (ret) + return ERR_PTR(ret); + + return no_free_ptr(path.dentry); +} + +/* + * Make sure that we reject any nonsensical flags that users pass via + * open_by_handle_at(). + */ +#define VALID_FILE_HANDLE_OPEN_FLAGS \ + (O_RDONLY | O_WRONLY | O_RDWR | O_NONBLOCK | O_CLOEXEC | O_EXCL) + +static int nsfs_export_permission(struct handle_to_path_ctx *ctx, + unsigned int oflags) +{ + if (oflags & ~(VALID_FILE_HANDLE_OPEN_FLAGS | O_LARGEFILE)) + return -EINVAL; + + /* nsfs_fh_to_dentry() is performs further permission checks. */ + return 0; +} + +static struct file *nsfs_export_open(struct path *path, unsigned int oflag= s) +{ + /* Clear O_LARGEFILE as open_by_handle_at() forces it. */ + oflags &=3D ~O_LARGEFILE; + return file_open_root(path, "", oflags, 0); +} + +static const struct export_operations nsfs_export_operations =3D { + .encode_fh =3D nsfs_encode_fh, + .fh_to_dentry =3D nsfs_fh_to_dentry, + .open =3D nsfs_export_open, + .permission =3D nsfs_export_permission, +}; + static int nsfs_init_fs_context(struct fs_context *fc) { struct pseudo_fs_context *ctx =3D init_pseudo(fc, NSFS_MAGIC); if (!ctx) return -ENOMEM; ctx->ops =3D &nsfs_ops; + ctx->eops =3D &nsfs_export_operations; ctx->dops =3D &ns_dentry_operations; fc->s_fs_info =3D (void *)&nsfs_stashed_ops; return 0; diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index cfb0dd1ea49c..3aac58a520c7 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -122,6 +122,12 @@ enum fid_type { FILEID_BCACHEFS_WITHOUT_PARENT =3D 0xb1, FILEID_BCACHEFS_WITH_PARENT =3D 0xb2, =20 + /* + * + * 64 bit namespace identifier, 32 bit namespace type, 32 bit inode numbe= r. + */ + FILEID_NSFS =3D 0xf1, + /* * 64 bit unique kernfs id */ --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 E0507371EAF; Wed, 10 Sep 2025 14:39:53 +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=1757515194; cv=none; b=eUDLAHLF9A0jApDxOPxrxkqDM4kgDA6lV4J8GLn/cnSy/1utFShbaIhewSh10oyvqsM8PfbGlm+jjv1fPwKF41mnt7jRnq/Mf7kdiAX4FNWlO062cj/ol1nFWadLkzM2XXjRprw10YLQzy4UJ0iShNZ79jt01YP3YM9vNv61b1Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515194; c=relaxed/simple; bh=jLmeRXfM/fHQlSZnDayQte5byFb73+eVfvcpuEjbG5w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Cy+Al7BY+O0a71OeUgsYRJfFhb2Exbz+mYcJvtIf158UkBKxFUBjf0SSgj0GT3imJB2giInZHuVh3sVYF4RwnSlnvuGJtudGSYjPSNi8KFhS7bqi5pcMFV/JyZA/IgNB7zujCk+dILamY6JAJema7WpO7K7hAw70SyQMU7ptZsk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eW6j41ii; 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="eW6j41ii" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30CDDC4CEF0; Wed, 10 Sep 2025 14:39:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515193; bh=jLmeRXfM/fHQlSZnDayQte5byFb73+eVfvcpuEjbG5w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eW6j41iihMu0DWvGQM6MkIx/Erya2gHx31P+WN7OskP0+9E3wtaTWiIC3eOIHMyIL ToxQWdCf4Oy2NX+xEqTohsl63js51jUQBtrrtNlRPW+JIPJPD9gHnvfPf2R/ts2pjf fRz0gPaZ8M3kDxJqO4lvtm972RGq0Jgs3d3N3W5+seGMPDrK1u9xH8TxgmTCIZZApA c81tmHMTf6rjxrt5n7pO3z7lq4Y5hxTFNChjI2OeKcKl1GHOy8NGJVHRNPntDatMSP 3moJB0j8OnNDp19FsBuUyOHwCjzQd7DVpsZ+cnxgBhmqu222XqoT5cNLpoiSkDkvT7 JIBSuEf275yNw== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:13 +0200 Subject: [PATCH 28/32] nsfs: support exhaustive file handles Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-28-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=2718; i=brauner@kernel.org; h=from:subject:message-id; bh=jLmeRXfM/fHQlSZnDayQte5byFb73+eVfvcpuEjbG5w=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OXMDuYW3la+4f+8mSb61edMgqQ4mQ/mJxyrFV59z /I2l/qNjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIk8aWb4X7uwpkpm8pwNcy1n irVznf58Vinr4K+u3zt/uB3IPVjvVcDwv+oKk4dOyumcS5KtgkZX+yOaOxOLvZ9Mvbf6yt0DXL9 mcAMA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Pidfd file handles are exhaustive meaning they don't require a handle on another pidfd to pass to open_by_handle_at() so it can derive the filesystem to decode in. Instead it can be derived from the file handle itself. The same is possible for namespace file handles. Signed-off-by: Christian Brauner Reviewed-by: Amir Goldstein --- fs/fhandle.c | 6 ++++++ fs/internal.h | 1 + fs/nsfs.c | 10 ++++++++++ include/uapi/linux/fcntl.h | 1 + 4 files changed, 18 insertions(+) diff --git a/fs/fhandle.c b/fs/fhandle.c index 7c236f64cdea..f18c855bb0c2 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "internal.h" #include "mount.h" =20 @@ -189,6 +190,11 @@ static int get_path_anchor(int fd, struct path *root) return 0; } =20 + if (fd =3D=3D FD_NSFS_ROOT) { + nsfs_get_root(root); + return 0; + } + return -EBADF; } =20 diff --git a/fs/internal.h b/fs/internal.h index 38e8aab27bbd..a33d18ee5b74 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -355,3 +355,4 @@ int anon_inode_getattr(struct mnt_idmap *idmap, const s= truct path *path, int anon_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr); void pidfs_get_root(struct path *path); +void nsfs_get_root(struct path *path); diff --git a/fs/nsfs.c b/fs/nsfs.c index a1585a2f4f03..3c6fcf652633 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -25,6 +25,14 @@ =20 static struct vfsmount *nsfs_mnt; =20 +static struct path nsfs_root_path =3D {}; + +void nsfs_get_root(struct path *path) +{ + *path =3D nsfs_root_path; + path_get(path); +} + static long ns_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); static const struct file_operations ns_file_operations =3D { @@ -616,4 +624,6 @@ void __init nsfs_init(void) if (IS_ERR(nsfs_mnt)) panic("can't set nsfs up\n"); nsfs_mnt->mnt_sb->s_flags &=3D ~SB_NOUSER; + nsfs_root_path.mnt =3D nsfs_mnt; + nsfs_root_path.dentry =3D nsfs_mnt->mnt_root; } diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index f291ab4f94eb..3741ea1b73d8 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -111,6 +111,7 @@ #define PIDFD_SELF_THREAD_GROUP -10001 /* Current thread group leader. */ =20 #define FD_PIDFS_ROOT -10002 /* Root of the pidfs filesystem */ +#define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */ #define FD_INVALID -10009 /* Invalid file descriptor: -10000 - EBADF =3D= -10009 */ =20 /* Generic flags for the *at(2) family of syscalls. */ --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 29E03338F59; Wed, 10 Sep 2025 14:39:59 +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=1757515200; cv=none; b=OWjewkKPBJ+yyVJ2Sg4/9eGZO40uJGOsMVbVO4nVLrHJ276nRwILeQJ+ThOvuw9IIcaFWB12GOgPDUiwq1c4uY0eYvi6lakqS5v+Uvns6ofvJ1ukvIL4aWuM2FZ72nu4lg7DTuTpYGsZaGkhyNDVmENy8s/JqWOb0HEYZAtYvgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515200; c=relaxed/simple; bh=/bhxoRXWkhRdK1c5aNMl+246ELQ0nVNgj4h3FoKhvM4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nUYPvg18k2ebSJc16EEKJLdfNIIORfNkueJOgMpW36xF9vn4Q0Hgte04NsOXaen/cFwQalCejnMSp16CTkBddMXd7VZ6jHdjIIyGMsIJnnhbglLF/UIkfMVBJzI2tP5UGRBO3l/3hd1TN93Ey/06VaEC92ynvrQpeWMW3GoBWbA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ll+kEwF1; 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="ll+kEwF1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3F552C4CEFF; Wed, 10 Sep 2025 14:39:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515199; bh=/bhxoRXWkhRdK1c5aNMl+246ELQ0nVNgj4h3FoKhvM4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ll+kEwF1z1oBF5f3RoZ+kVTXqp6+SRoBn0tEjX/tnlZM7CM7bEyXjuBcYDlHFBKIG GuEdzNJFIng8675w1L88MhiZaaaOnX02CCzoz2OQrkukZ3S424U2avchDuF7EfGe4E TF8tpESldvbJYERE7DCmHjaBzebU1Ejoia9sFLPa1cjaQ8urtEx9ylPKHj1aPOCt0u zMfmPZfsQmIKnLagRsz2Xh5iefpCeyDiTQCNvhwHZrn9JzsKZEShyerp+DHEYFR/SW jk7b2DxZ7Qm2fLSWQSCgkX/a9n5doU8ts2EIzdTABZCcLZL+esh6lKNiPrPZDhcPcg rmq3c8jCO9vcQ== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:14 +0200 Subject: [PATCH 29/32] nsfs: add missing id retrieval support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-29-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=4132; i=brauner@kernel.org; h=from:subject:message-id; bh=/bhxoRXWkhRdK1c5aNMl+246ELQ0nVNgj4h3FoKhvM4=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OVkZRC7/qTS9vu6nrKH17l2rfwfyX3I8PVHaZ+HF pu2zNKI7ChlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhIxk1GhutynhNmPXY5mTQ3 +XV2/eMbcx3qdfdnHVpccel2YuWjpUaMDCdi1Ccq3n7h9+Df7YCfv7Ie21cczVrFN9v41brcS6f mmPIDAA== X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The mount namespace has supported id retrieval for a while already. Add support for the other types as well. Signed-off-by: Christian Brauner --- fs/nsfs.c | 74 +++++++++++++++++++++++++++++++++++++++----= ---- include/uapi/linux/nsfs.h | 12 ++++++-- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/fs/nsfs.c b/fs/nsfs.c index 3c6fcf652633..527480e67fd1 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -173,6 +173,13 @@ static bool nsfs_ioctl_valid(unsigned int cmd) case NS_GET_NSTYPE: case NS_GET_OWNER_UID: case NS_GET_MNTNS_ID: + case NS_GET_NETNS_ID: + case NS_GET_CGROUPNS_ID: + case NS_GET_IPCNS_ID: + case NS_GET_UTSNS_ID: + case NS_GET_PIDNS_ID: + case NS_GET_TIMENS_ID: + case NS_GET_USERNS_ID: case NS_GET_PID_FROM_PIDNS: case NS_GET_TGID_FROM_PIDNS: case NS_GET_PID_IN_PIDNS: @@ -226,18 +233,6 @@ static long ns_ioctl(struct file *filp, unsigned int i= octl, argp =3D (uid_t __user *) arg; uid =3D from_kuid_munged(current_user_ns(), user_ns->owner); return put_user(uid, argp); - case NS_GET_MNTNS_ID: { - __u64 __user *idp; - __u64 id; - - if (ns->ops->type !=3D CLONE_NEWNS) - return -EINVAL; - - mnt_ns =3D container_of(ns, struct mnt_namespace, ns); - idp =3D (__u64 __user *)arg; - id =3D mnt_ns->ns.ns_id; - return put_user(id, idp); - } case NS_GET_PID_FROM_PIDNS: fallthrough; case NS_GET_TGID_FROM_PIDNS: @@ -283,6 +278,61 @@ static long ns_ioctl(struct file *filp, unsigned int i= octl, ret =3D -ESRCH; return ret; } + case NS_GET_MNTNS_ID: + fallthrough; + case NS_GET_NETNS_ID: + fallthrough; + case NS_GET_CGROUPNS_ID: + fallthrough; + case NS_GET_IPCNS_ID: + fallthrough; + case NS_GET_UTSNS_ID: + fallthrough; + case NS_GET_PIDNS_ID: + fallthrough; + case NS_GET_TIMENS_ID: + fallthrough; + case NS_GET_USERNS_ID: { + __u64 __user *idp; + __u64 id; + int expected_type; + + switch (ioctl) { + case NS_GET_MNTNS_ID: + expected_type =3D CLONE_NEWNS; + break; + case NS_GET_NETNS_ID: + expected_type =3D CLONE_NEWNET; + break; + case NS_GET_CGROUPNS_ID: + expected_type =3D CLONE_NEWCGROUP; + break; + case NS_GET_IPCNS_ID: + expected_type =3D CLONE_NEWIPC; + break; + case NS_GET_UTSNS_ID: + expected_type =3D CLONE_NEWUTS; + break; + case NS_GET_PIDNS_ID: + expected_type =3D CLONE_NEWPID; + break; + case NS_GET_TIMENS_ID: + expected_type =3D CLONE_NEWTIME; + break; + case NS_GET_USERNS_ID: + expected_type =3D CLONE_NEWUSER; + break; + default: + return -EINVAL; + } + + if (ns->ops->type !=3D expected_type) + return -EINVAL; + + idp =3D (__u64 __user *)arg; + id =3D ns->ns_id; + return put_user(id, idp); + } } =20 /* extensible ioctls */ diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h index 97d8d80d139f..f7c21840cc09 100644 --- a/include/uapi/linux/nsfs.h +++ b/include/uapi/linux/nsfs.h @@ -16,8 +16,6 @@ #define NS_GET_NSTYPE _IO(NSIO, 0x3) /* Get owner UID (in the caller's user namespace) for a user namespace */ #define NS_GET_OWNER_UID _IO(NSIO, 0x4) -/* Get the id for a mount namespace */ -#define NS_GET_MNTNS_ID _IOR(NSIO, 0x5, __u64) /* Translate pid from target pid namespace into the caller's pid namespace= . */ #define NS_GET_PID_FROM_PIDNS _IOR(NSIO, 0x6, int) /* Return thread-group leader id of pid in the callers pid namespace. */ @@ -42,6 +40,16 @@ struct mnt_ns_info { /* Get previous namespace. */ #define NS_MNT_GET_PREV _IOR(NSIO, 12, struct mnt_ns_info) =20 +/* Retrieve namespace identifiers. */ +#define NS_GET_MNTNS_ID _IOR(NSIO, 5, __u64) +#define NS_GET_NETNS_ID _IOR(NSIO, 13, __u64) +#define NS_GET_CGROUPNS_ID _IOR(NSIO, 14, __u64) +#define NS_GET_IPCNS_ID _IOR(NSIO, 15, __u64) +#define NS_GET_UTSNS_ID _IOR(NSIO, 16, __u64) +#define NS_GET_PIDNS_ID _IOR(NSIO, 17, __u64) +#define NS_GET_TIMENS_ID _IOR(NSIO, 18, __u64) +#define NS_GET_USERNS_ID _IOR(NSIO, 19, __u64) + enum init_ns_ino { IPC_NS_INIT_INO =3D 0xEFFFFFFFU, UTS_NS_INIT_INO =3D 0xEFFFFFFEU, --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 D5ECE33A00F; Wed, 10 Sep 2025 14:40:05 +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=1757515206; cv=none; b=drIF5IbQseZCe7I7ozsgYdUh1QBtH8vbZnfMJrC94Ka76rAQEMRrXOMNixl3uqioLPMgZOCaRimBl4EjAUkjn4stAvPX+R2DJT+VWlSp/wBIuR6SUOVsAHo6ymlsK8/734enu9I+n553QSkXNTVd8u2C4ixbzOT+UHH7tSMsf4Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515206; c=relaxed/simple; bh=gbS2ymyvQLhpBSZHty4/HJL9CBgNRefAr9z2qgMgDus=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qqHRpWv2Hin7PSIsaTbQyHl7hy++UvjfBUd2tt7UYS8O0V4lNtIwLOXLCiRpHXSQFOtLJLY2T0lsvnNHIoldMwsoPXWibTN0hQutPgcBECOxP2x6VryHxa+hhR+GzDChLNxrV8atNdbFX+7eSC2MRh4wYy5neZLT+lDnLKHDo7A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WrHoFTzX; 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="WrHoFTzX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 385A6C4CEF8; Wed, 10 Sep 2025 14:40:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515205; bh=gbS2ymyvQLhpBSZHty4/HJL9CBgNRefAr9z2qgMgDus=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WrHoFTzXH0e/Em4vInRV5aEDw73hGv+cCIsKqhe0lF+mhsJ0Qm2gVpbz/DxaSczcd WkYIHhLlWZoUFSg1thfftu9+vqe9+GlOjeQ9S75FJQ6a1gyn3GNEE9BRAWWye/5cM9 SEC+I7Fp5m8CBBK+iKkVZIMljXpOQvn7GyZRrswtEw8zLJdwA2XpQZlOAIP5TYAcC+ +2vxSBPgP/5sP17Zg3JGYtERYdjjm51t/XguHlXBUreFu0gmNyfI/KW10OYhK2c/5E MAIzLqjFLSI55Lk0FDlvshDncouVGrAoumlcAiQApmEqxJpvtiKC4sHdl8L/eKQKRp WrcGgBSdb6KdA== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:15 +0200 Subject: [PATCH 30/32] tools: update nsfs.h uapi header Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-30-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=1883; i=brauner@kernel.org; h=from:subject:message-id; bh=gbS2ymyvQLhpBSZHty4/HJL9CBgNRefAr9z2qgMgDus=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OX0c/qo4Lq6fO6Tr8baU7fk3My6d9zE9vQ5pgWez KdFV1WEd5SyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEzEcxLD/xTzq+0O1Xfnb133 jnXhw1VdL5z6tQ3+c6Xfm/E4/MLhwt2MDH9vXVt6KPh6mrFdlG2I+y75Jk3DzekrGRZ/453GXPj MgxUA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Update the nsfs.h tools header to the uapi/nsfs.h header so we can rely on it in the selftests. Signed-off-by: Christian Brauner --- tools/include/uapi/linux/nsfs.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tools/include/uapi/linux/nsfs.h b/tools/include/uapi/linux/nsf= s.h index 34127653fd00..f7c21840cc09 100644 --- a/tools/include/uapi/linux/nsfs.h +++ b/tools/include/uapi/linux/nsfs.h @@ -16,8 +16,6 @@ #define NS_GET_NSTYPE _IO(NSIO, 0x3) /* Get owner UID (in the caller's user namespace) for a user namespace */ #define NS_GET_OWNER_UID _IO(NSIO, 0x4) -/* Get the id for a mount namespace */ -#define NS_GET_MNTNS_ID _IOR(NSIO, 0x5, __u64) /* Translate pid from target pid namespace into the caller's pid namespace= . */ #define NS_GET_PID_FROM_PIDNS _IOR(NSIO, 0x6, int) /* Return thread-group leader id of pid in the callers pid namespace. */ @@ -42,4 +40,25 @@ struct mnt_ns_info { /* Get previous namespace. */ #define NS_MNT_GET_PREV _IOR(NSIO, 12, struct mnt_ns_info) =20 +/* Retrieve namespace identifiers. */ +#define NS_GET_MNTNS_ID _IOR(NSIO, 5, __u64) +#define NS_GET_NETNS_ID _IOR(NSIO, 13, __u64) +#define NS_GET_CGROUPNS_ID _IOR(NSIO, 14, __u64) +#define NS_GET_IPCNS_ID _IOR(NSIO, 15, __u64) +#define NS_GET_UTSNS_ID _IOR(NSIO, 16, __u64) +#define NS_GET_PIDNS_ID _IOR(NSIO, 17, __u64) +#define NS_GET_TIMENS_ID _IOR(NSIO, 18, __u64) +#define NS_GET_USERNS_ID _IOR(NSIO, 19, __u64) + +enum init_ns_ino { + IPC_NS_INIT_INO =3D 0xEFFFFFFFU, + UTS_NS_INIT_INO =3D 0xEFFFFFFEU, + USER_NS_INIT_INO =3D 0xEFFFFFFDU, + PID_NS_INIT_INO =3D 0xEFFFFFFCU, + CGROUP_NS_INIT_INO =3D 0xEFFFFFFBU, + TIME_NS_INIT_INO =3D 0xEFFFFFFAU, + NET_NS_INIT_INO =3D 0xEFFFFFF9U, + MNT_NS_INIT_INO =3D 0xEFFFFFF8U, +}; + #endif /* __LINUX_NSFS_H */ --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 38760338F27; Wed, 10 Sep 2025 14:40:11 +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=1757515212; cv=none; b=n8Et28ML9xpCinlzZRdfv8y7fQLZhrR4J+dabFtL1uom4rLKBjcwKXlnbDwJwJ5FAP0tSlnfeH9T/D9UackHxUkJ/t8I/odyv0Vx1H94D1+uvHwvsHBEFRIjz8+7EwlcGanN9DqyXmSxgaIfR29sPZnA8iVb3NdGpVN+u5pOjQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515212; c=relaxed/simple; bh=Co7I2Z+LZzv8R4N0t4c4Y6gt2rHVb3Jja/U+OS0lMy4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hIOn0tKRB2H9lJipeiHLd6o9eyNDGJHbvlZuKY/fdy/oCh0MW80AVYDIP6+kD101qpy9i6nlQ1T6ZOOpimk2V19kJGE+a7NTtAIVLZMOTT59+ouLCFMSS0idPMok5zC2KerYCx5FyAHyE3/5O4Y9KmL5M+zw6H19XT4RACp6Mww= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZSHelylM; 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="ZSHelylM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 350BAC4CEF0; Wed, 10 Sep 2025 14:40:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515211; bh=Co7I2Z+LZzv8R4N0t4c4Y6gt2rHVb3Jja/U+OS0lMy4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZSHelylM+mf8ZWc58zUYPKNPKnCFKqqgSFXxjfoBkShUmc4FDD7c7OpzteDvkZQhZ xxXwxqPMBXOSHaYjsPWfzYxDfrGUF47MX5s9j2tBi6ZXZV8D9Mb+4QfHivquqt8PbS ZE9NBPL/UKUQJs8JQOjs3GvW7pAcrVuPeNtHedk78LlxoftPhvIFGp9U4bhVfs+5Ij NimUJlZn/Sl5vrVBuTnU6/qToOkkzxXgdzcwxuUfYliZ1BO7//a20PPP3tx9YZZxy/ F6hnSd7A8X//SwXqgch/oI+cW2YMuDvDvOw4zfWAUOjtZ9fovhPe6/8qxCUKppcvrR du9MSoNIe5E3Q== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:16 +0200 Subject: [PATCH 31/32] selftests/namespaces: add identifier selftests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-31-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=26500; i=brauner@kernel.org; h=from:subject:message-id; bh=Co7I2Z+LZzv8R4N0t4c4Y6gt2rHVb3Jja/U+OS0lMy4=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWQc7OU8vV+Q0ffLn6ZbV465Hq5esEeo87Px9+Nq/5+dy +GMtDjR2lHKwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjCRTT2MDG+u1RnNzNiWoRQm LHCc4cnKuiurfv3M2Cqpfebm6u8tolkM/xQPBr65trJL4rVfl8PnA1fXRsokx+r2qijI7pj1r4L xPC8A X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a bunch of selftests for the identifier retrieval ioctls. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/.gitignore | 1 + tools/testing/selftests/namespaces/Makefile | 7 + tools/testing/selftests/namespaces/config | 7 + tools/testing/selftests/namespaces/nsid_test.c | 986 +++++++++++++++++++++= ++++ 4 files changed, 1001 insertions(+) diff --git a/tools/testing/selftests/namespaces/.gitignore b/tools/testing/= selftests/namespaces/.gitignore new file mode 100644 index 000000000000..c1e8d634dd21 --- /dev/null +++ b/tools/testing/selftests/namespaces/.gitignore @@ -0,0 +1 @@ +nsid_test diff --git a/tools/testing/selftests/namespaces/Makefile b/tools/testing/se= lftests/namespaces/Makefile new file mode 100644 index 000000000000..9280c703533e --- /dev/null +++ b/tools/testing/selftests/namespaces/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +CFLAGS +=3D -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) + +TEST_GEN_PROGS :=3D nsid_test + +include ../lib.mk + diff --git a/tools/testing/selftests/namespaces/config b/tools/testing/self= tests/namespaces/config new file mode 100644 index 000000000000..d09836260262 --- /dev/null +++ b/tools/testing/selftests/namespaces/config @@ -0,0 +1,7 @@ +CONFIG_UTS_NS=3Dy +CONFIG_TIME_NS=3Dy +CONFIG_IPC_NS=3Dy +CONFIG_USER_NS=3Dy +CONFIG_PID_NS=3Dy +CONFIG_NET_NS=3Dy +CONFIG_CGROUPS=3Dy diff --git a/tools/testing/selftests/namespaces/nsid_test.c b/tools/testing= /selftests/namespaces/nsid_test.c new file mode 100644 index 000000000000..280dde9b71dc --- /dev/null +++ b/tools/testing/selftests/namespaces/nsid_test.c @@ -0,0 +1,986 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../kselftest_harness.h" + +TEST(nsid_mntns_basic) +{ + __u64 mnt_ns_id =3D 0; + int fd_mntns; + int ret; + + /* Open the current mount namespace */ + fd_mntns =3D open("/proc/self/ns/mnt", O_RDONLY); + ASSERT_GE(fd_mntns, 0); + + /* Get the mount namespace ID */ + ret =3D ioctl(fd_mntns, NS_GET_MNTNS_ID, &mnt_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(mnt_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 mnt_ns_id2 =3D 0; + ret =3D ioctl(fd_mntns, NS_GET_MNTNS_ID, &mnt_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(mnt_ns_id, mnt_ns_id2); + + close(fd_mntns); +} + +TEST(nsid_mntns_separate) +{ + __u64 parent_mnt_ns_id =3D 0; + __u64 child_mnt_ns_id =3D 0; + int fd_parent_mntns, fd_child_mntns; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's mount namespace ID */ + fd_parent_mntns =3D open("/proc/self/ns/mnt", O_RDONLY); + ASSERT_GE(fd_parent_mntns, 0); + ret =3D ioctl(fd_parent_mntns, NS_GET_MNTNS_ID, &parent_mnt_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_mnt_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new mount namespace */ + ret =3D unshare(CLONE_NEWNS); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Signal success */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + + /* Keep namespace alive */ + pause(); + _exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + close(pipefd[0]); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_mntns); + SKIP(return, "No permission to create mount namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + /* Open child's mount namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid); + fd_child_mntns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_mntns, 0); + + /* Get child's mount namespace ID */ + ret =3D ioctl(fd_child_mntns, NS_GET_MNTNS_ID, &child_mnt_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_mnt_ns_id, 0); + + /* Parent and child should have different mount namespace IDs */ + ASSERT_NE(parent_mnt_ns_id, child_mnt_ns_id); + + close(fd_parent_mntns); + close(fd_child_mntns); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_cgroupns_basic) +{ + __u64 cgroup_ns_id =3D 0; + int fd_cgroupns; + int ret; + + /* Open the current cgroup namespace */ + fd_cgroupns =3D open("/proc/self/ns/cgroup", O_RDONLY); + ASSERT_GE(fd_cgroupns, 0); + + /* Get the cgroup namespace ID */ + ret =3D ioctl(fd_cgroupns, NS_GET_CGROUPNS_ID, &cgroup_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(cgroup_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 cgroup_ns_id2 =3D 0; + ret =3D ioctl(fd_cgroupns, NS_GET_CGROUPNS_ID, &cgroup_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(cgroup_ns_id, cgroup_ns_id2); + + close(fd_cgroupns); +} + +TEST(nsid_cgroupns_separate) +{ + __u64 parent_cgroup_ns_id =3D 0; + __u64 child_cgroup_ns_id =3D 0; + int fd_parent_cgroupns, fd_child_cgroupns; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's cgroup namespace ID */ + fd_parent_cgroupns =3D open("/proc/self/ns/cgroup", O_RDONLY); + ASSERT_GE(fd_parent_cgroupns, 0); + ret =3D ioctl(fd_parent_cgroupns, NS_GET_CGROUPNS_ID, &parent_cgroup_ns_i= d); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_cgroup_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new cgroup namespace */ + ret =3D unshare(CLONE_NEWCGROUP); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Signal success */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + + /* Keep namespace alive */ + pause(); + _exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + close(pipefd[0]); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_cgroupns); + SKIP(return, "No permission to create cgroup namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + /* Open child's cgroup namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/cgroup", pid); + fd_child_cgroupns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_cgroupns, 0); + + /* Get child's cgroup namespace ID */ + ret =3D ioctl(fd_child_cgroupns, NS_GET_CGROUPNS_ID, &child_cgroup_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_cgroup_ns_id, 0); + + /* Parent and child should have different cgroup namespace IDs */ + ASSERT_NE(parent_cgroup_ns_id, child_cgroup_ns_id); + + close(fd_parent_cgroupns); + close(fd_child_cgroupns); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_ipcns_basic) +{ + __u64 ipc_ns_id =3D 0; + int fd_ipcns; + int ret; + + /* Open the current IPC namespace */ + fd_ipcns =3D open("/proc/self/ns/ipc", O_RDONLY); + ASSERT_GE(fd_ipcns, 0); + + /* Get the IPC namespace ID */ + ret =3D ioctl(fd_ipcns, NS_GET_IPCNS_ID, &ipc_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(ipc_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 ipc_ns_id2 =3D 0; + ret =3D ioctl(fd_ipcns, NS_GET_IPCNS_ID, &ipc_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(ipc_ns_id, ipc_ns_id2); + + close(fd_ipcns); +} + +TEST(nsid_ipcns_separate) +{ + __u64 parent_ipc_ns_id =3D 0; + __u64 child_ipc_ns_id =3D 0; + int fd_parent_ipcns, fd_child_ipcns; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's IPC namespace ID */ + fd_parent_ipcns =3D open("/proc/self/ns/ipc", O_RDONLY); + ASSERT_GE(fd_parent_ipcns, 0); + ret =3D ioctl(fd_parent_ipcns, NS_GET_IPCNS_ID, &parent_ipc_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_ipc_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new IPC namespace */ + ret =3D unshare(CLONE_NEWIPC); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Signal success */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + + /* Keep namespace alive */ + pause(); + _exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + close(pipefd[0]); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_ipcns); + SKIP(return, "No permission to create IPC namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + /* Open child's IPC namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/ipc", pid); + fd_child_ipcns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_ipcns, 0); + + /* Get child's IPC namespace ID */ + ret =3D ioctl(fd_child_ipcns, NS_GET_IPCNS_ID, &child_ipc_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_ipc_ns_id, 0); + + /* Parent and child should have different IPC namespace IDs */ + ASSERT_NE(parent_ipc_ns_id, child_ipc_ns_id); + + close(fd_parent_ipcns); + close(fd_child_ipcns); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_utsns_basic) +{ + __u64 uts_ns_id =3D 0; + int fd_utsns; + int ret; + + /* Open the current UTS namespace */ + fd_utsns =3D open("/proc/self/ns/uts", O_RDONLY); + ASSERT_GE(fd_utsns, 0); + + /* Get the UTS namespace ID */ + ret =3D ioctl(fd_utsns, NS_GET_UTSNS_ID, &uts_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(uts_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 uts_ns_id2 =3D 0; + ret =3D ioctl(fd_utsns, NS_GET_UTSNS_ID, &uts_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(uts_ns_id, uts_ns_id2); + + close(fd_utsns); +} + +TEST(nsid_utsns_separate) +{ + __u64 parent_uts_ns_id =3D 0; + __u64 child_uts_ns_id =3D 0; + int fd_parent_utsns, fd_child_utsns; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's UTS namespace ID */ + fd_parent_utsns =3D open("/proc/self/ns/uts", O_RDONLY); + ASSERT_GE(fd_parent_utsns, 0); + ret =3D ioctl(fd_parent_utsns, NS_GET_UTSNS_ID, &parent_uts_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_uts_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new UTS namespace */ + ret =3D unshare(CLONE_NEWUTS); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Signal success */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + + /* Keep namespace alive */ + pause(); + _exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + close(pipefd[0]); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_utsns); + SKIP(return, "No permission to create UTS namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + /* Open child's UTS namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/uts", pid); + fd_child_utsns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_utsns, 0); + + /* Get child's UTS namespace ID */ + ret =3D ioctl(fd_child_utsns, NS_GET_UTSNS_ID, &child_uts_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_uts_ns_id, 0); + + /* Parent and child should have different UTS namespace IDs */ + ASSERT_NE(parent_uts_ns_id, child_uts_ns_id); + + close(fd_parent_utsns); + close(fd_child_utsns); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_userns_basic) +{ + __u64 user_ns_id =3D 0; + int fd_userns; + int ret; + + /* Open the current user namespace */ + fd_userns =3D open("/proc/self/ns/user", O_RDONLY); + ASSERT_GE(fd_userns, 0); + + /* Get the user namespace ID */ + ret =3D ioctl(fd_userns, NS_GET_USERNS_ID, &user_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(user_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 user_ns_id2 =3D 0; + ret =3D ioctl(fd_userns, NS_GET_USERNS_ID, &user_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(user_ns_id, user_ns_id2); + + close(fd_userns); +} + +TEST(nsid_userns_separate) +{ + __u64 parent_user_ns_id =3D 0; + __u64 child_user_ns_id =3D 0; + int fd_parent_userns, fd_child_userns; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's user namespace ID */ + fd_parent_userns =3D open("/proc/self/ns/user", O_RDONLY); + ASSERT_GE(fd_parent_userns, 0); + ret =3D ioctl(fd_parent_userns, NS_GET_USERNS_ID, &parent_user_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_user_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new user namespace */ + ret =3D unshare(CLONE_NEWUSER); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Signal success */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + + /* Keep namespace alive */ + pause(); + _exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + close(pipefd[0]); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_userns); + SKIP(return, "No permission to create user namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + /* Open child's user namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/user", pid); + fd_child_userns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_userns, 0); + + /* Get child's user namespace ID */ + ret =3D ioctl(fd_child_userns, NS_GET_USERNS_ID, &child_user_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_user_ns_id, 0); + + /* Parent and child should have different user namespace IDs */ + ASSERT_NE(parent_user_ns_id, child_user_ns_id); + + close(fd_parent_userns); + close(fd_child_userns); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_timens_basic) +{ + __u64 time_ns_id =3D 0; + int fd_timens; + int ret; + + /* Open the current time namespace */ + fd_timens =3D open("/proc/self/ns/time", O_RDONLY); + if (fd_timens < 0) { + SKIP(return, "Time namespaces not supported"); + } + + /* Get the time namespace ID */ + ret =3D ioctl(fd_timens, NS_GET_TIMENS_ID, &time_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(time_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 time_ns_id2 =3D 0; + ret =3D ioctl(fd_timens, NS_GET_TIMENS_ID, &time_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(time_ns_id, time_ns_id2); + + close(fd_timens); +} + +TEST(nsid_timens_separate) +{ + __u64 parent_time_ns_id =3D 0; + __u64 child_time_ns_id =3D 0; + int fd_parent_timens, fd_child_timens; + int ret; + pid_t pid; + int pipefd[2]; + + /* Open the current time namespace */ + fd_parent_timens =3D open("/proc/self/ns/time", O_RDONLY); + if (fd_parent_timens < 0) { + SKIP(return, "Time namespaces not supported"); + } + + /* Get parent's time namespace ID */ + ret =3D ioctl(fd_parent_timens, NS_GET_TIMENS_ID, &parent_time_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_time_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new time namespace */ + ret =3D unshare(CLONE_NEWTIME); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES || errno =3D=3D EINVAL) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Fork a grandchild to actually enter the new namespace */ + pid_t grandchild =3D fork(); + if (grandchild =3D=3D 0) { + /* Grandchild is in the new namespace */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + pause(); + _exit(0); + } else if (grandchild > 0) { + /* Child writes grandchild PID and waits */ + write(pipefd[1], "Y", 1); + write(pipefd[1], &grandchild, sizeof(grandchild)); + close(pipefd[1]); + pause(); /* Keep the parent alive to maintain the grandchild */ + _exit(0); + } else { + _exit(1); + } + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_timens); + close(pipefd[0]); + SKIP(return, "Cannot create time namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + pid_t grandchild_pid; + ASSERT_EQ(read(pipefd[0], &grandchild_pid, sizeof(grandchild_pid)), sizeo= f(grandchild_pid)); + close(pipefd[0]); + + /* Open grandchild's time namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/time", grandchild_pid); + fd_child_timens =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_timens, 0); + + /* Get child's time namespace ID */ + ret =3D ioctl(fd_child_timens, NS_GET_TIMENS_ID, &child_time_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_time_ns_id, 0); + + /* Parent and child should have different time namespace IDs */ + ASSERT_NE(parent_time_ns_id, child_time_ns_id); + + close(fd_parent_timens); + close(fd_child_timens); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_pidns_basic) +{ + __u64 pid_ns_id =3D 0; + int fd_pidns; + int ret; + + /* Open the current PID namespace */ + fd_pidns =3D open("/proc/self/ns/pid", O_RDONLY); + ASSERT_GE(fd_pidns, 0); + + /* Get the PID namespace ID */ + ret =3D ioctl(fd_pidns, NS_GET_PIDNS_ID, &pid_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(pid_ns_id, 0); + + /* Verify we can get the same ID again */ + __u64 pid_ns_id2 =3D 0; + ret =3D ioctl(fd_pidns, NS_GET_PIDNS_ID, &pid_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(pid_ns_id, pid_ns_id2); + + close(fd_pidns); +} + +TEST(nsid_pidns_separate) +{ + __u64 parent_pid_ns_id =3D 0; + __u64 child_pid_ns_id =3D 0; + int fd_parent_pidns, fd_child_pidns; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's PID namespace ID */ + fd_parent_pidns =3D open("/proc/self/ns/pid", O_RDONLY); + ASSERT_GE(fd_parent_pidns, 0); + ret =3D ioctl(fd_parent_pidns, NS_GET_PIDNS_ID, &parent_pid_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_pid_ns_id, 0); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new PID namespace */ + ret =3D unshare(CLONE_NEWPID); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Fork a grandchild to actually enter the new namespace */ + pid_t grandchild =3D fork(); + if (grandchild =3D=3D 0) { + /* Grandchild is in the new namespace */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + pause(); + _exit(0); + } else if (grandchild > 0) { + /* Child writes grandchild PID and waits */ + write(pipefd[1], "Y", 1); + write(pipefd[1], &grandchild, sizeof(grandchild)); + close(pipefd[1]); + pause(); /* Keep the parent alive to maintain the grandchild */ + _exit(0); + } else { + _exit(1); + } + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_pidns); + close(pipefd[0]); + SKIP(return, "No permission to create PID namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + pid_t grandchild_pid; + ASSERT_EQ(read(pipefd[0], &grandchild_pid, sizeof(grandchild_pid)), sizeo= f(grandchild_pid)); + close(pipefd[0]); + + /* Open grandchild's PID namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/pid", grandchild_pid); + fd_child_pidns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_pidns, 0); + + /* Get child's PID namespace ID */ + ret =3D ioctl(fd_child_pidns, NS_GET_PIDNS_ID, &child_pid_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_pid_ns_id, 0); + + /* Parent and child should have different PID namespace IDs */ + ASSERT_NE(parent_pid_ns_id, child_pid_ns_id); + + close(fd_parent_pidns); + close(fd_child_pidns); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST(nsid_netns_basic) +{ + __u64 net_ns_id =3D 0; + __u64 netns_cookie =3D 0; + int fd_netns; + int sock; + socklen_t optlen; + int ret; + + /* Open the current network namespace */ + fd_netns =3D open("/proc/self/ns/net", O_RDONLY); + ASSERT_GE(fd_netns, 0); + + /* Get the network namespace ID via ioctl */ + ret =3D ioctl(fd_netns, NS_GET_NETNS_ID, &net_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(net_ns_id, 0); + + /* Create a socket to get the SO_NETNS_COOKIE */ + sock =3D socket(AF_UNIX, SOCK_STREAM, 0); + ASSERT_GE(sock, 0); + + /* Get the network namespace cookie via socket option */ + optlen =3D sizeof(netns_cookie); + ret =3D getsockopt(sock, SOL_SOCKET, SO_NETNS_COOKIE, &netns_cookie, &opt= len); + ASSERT_EQ(ret, 0); + ASSERT_EQ(optlen, sizeof(netns_cookie)); + + /* The namespace ID and cookie should be identical */ + ASSERT_EQ(net_ns_id, netns_cookie); + + /* Verify we can get the same ID again */ + __u64 net_ns_id2 =3D 0; + ret =3D ioctl(fd_netns, NS_GET_NETNS_ID, &net_ns_id2); + ASSERT_EQ(ret, 0); + ASSERT_EQ(net_ns_id, net_ns_id2); + + close(sock); + close(fd_netns); +} + +TEST(nsid_netns_separate) +{ + __u64 parent_net_ns_id =3D 0; + __u64 parent_netns_cookie =3D 0; + __u64 child_net_ns_id =3D 0; + __u64 child_netns_cookie =3D 0; + int fd_parent_netns, fd_child_netns; + int parent_sock, child_sock; + socklen_t optlen; + int ret; + pid_t pid; + int pipefd[2]; + + /* Get parent's network namespace ID */ + fd_parent_netns =3D open("/proc/self/ns/net", O_RDONLY); + ASSERT_GE(fd_parent_netns, 0); + ret =3D ioctl(fd_parent_netns, NS_GET_NETNS_ID, &parent_net_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(parent_net_ns_id, 0); + + /* Get parent's network namespace cookie */ + parent_sock =3D socket(AF_UNIX, SOCK_STREAM, 0); + ASSERT_GE(parent_sock, 0); + optlen =3D sizeof(parent_netns_cookie); + ret =3D getsockopt(parent_sock, SOL_SOCKET, SO_NETNS_COOKIE, &parent_netn= s_cookie, &optlen); + ASSERT_EQ(ret, 0); + + /* Verify parent's ID and cookie match */ + ASSERT_EQ(parent_net_ns_id, parent_netns_cookie); + + /* Create a pipe for synchronization */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Create new network namespace */ + ret =3D unshare(CLONE_NEWNET); + if (ret !=3D 0) { + /* Skip test if we don't have permission */ + if (errno =3D=3D EPERM || errno =3D=3D EACCES) { + write(pipefd[1], "S", 1); /* Signal skip */ + _exit(0); + } + _exit(1); + } + + /* Signal success */ + write(pipefd[1], "Y", 1); + close(pipefd[1]); + + /* Keep namespace alive */ + pause(); + _exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + char buf; + ASSERT_EQ(read(pipefd[0], &buf, 1), 1); + close(pipefd[0]); + + if (buf =3D=3D 'S') { + /* Child couldn't create namespace, skip test */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); + close(fd_parent_netns); + close(parent_sock); + SKIP(return, "No permission to create network namespace"); + } + + ASSERT_EQ(buf, 'Y'); + + /* Open child's network namespace */ + char path[256]; + snprintf(path, sizeof(path), "/proc/%d/ns/net", pid); + fd_child_netns =3D open(path, O_RDONLY); + ASSERT_GE(fd_child_netns, 0); + + /* Get child's network namespace ID */ + ret =3D ioctl(fd_child_netns, NS_GET_NETNS_ID, &child_net_ns_id); + ASSERT_EQ(ret, 0); + ASSERT_NE(child_net_ns_id, 0); + + /* Create socket in child's namespace to get cookie */ + ret =3D setns(fd_child_netns, CLONE_NEWNET); + if (ret =3D=3D 0) { + child_sock =3D socket(AF_UNIX, SOCK_STREAM, 0); + ASSERT_GE(child_sock, 0); + + optlen =3D sizeof(child_netns_cookie); + ret =3D getsockopt(child_sock, SOL_SOCKET, SO_NETNS_COOKIE, &child_netns= _cookie, &optlen); + ASSERT_EQ(ret, 0); + + /* Verify child's ID and cookie match */ + ASSERT_EQ(child_net_ns_id, child_netns_cookie); + + close(child_sock); + + /* Return to parent namespace */ + setns(fd_parent_netns, CLONE_NEWNET); + } + + /* Parent and child should have different network namespace IDs */ + ASSERT_NE(parent_net_ns_id, child_net_ns_id); + if (child_netns_cookie !=3D 0) { + ASSERT_NE(parent_netns_cookie, child_netns_cookie); + } + + close(fd_parent_netns); + close(fd_child_netns); + close(parent_sock); + + /* Clean up child process */ + kill(pid, SIGTERM); + waitpid(pid, NULL, 0); +} + +TEST_HARNESS_MAIN --=20 2.47.3 From nobody Wed Sep 10 23:39:18 2025 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 32760327A26; Wed, 10 Sep 2025 14:40:17 +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=1757515218; cv=none; b=BYDRRCtLvZvJhMaX6TRVjTUofTaZ3mjFnptHyTLL2TqhGdB0gVteizuBzTi16sNPTjcEH748g8qlLRgA2c4xYaydqxI5BMn61UX0vS5NU8fPHn0LlXgWhotRfi2068WDWy304YlkOdxf8Mnxbvl5rGvxki7QU6z2QzzgU8R6JAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757515218; c=relaxed/simple; bh=mjyP74gnmM3iIM41CDhniFKSXnSvWhIDm7WadSUC65o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WIfe9RCvUVp7sMttyQFJYlJs69zqFNO+xp/0yRU0VvljpBJrkQL1gslKCaN8EGHY8U8pX1mMjoFCsQJ33a2NottsZcX9JLX5KueS0Te6NiNmRAZy9v8Jn9fox/nfdHGQxJqmyV/ktqINDg6XyXsR7KHS75cKHjvyplB4tPuPJ8o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dBqAsxD2; 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="dBqAsxD2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52BFBC4CEF9; Wed, 10 Sep 2025 14:40:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757515217; bh=mjyP74gnmM3iIM41CDhniFKSXnSvWhIDm7WadSUC65o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dBqAsxD2bLKkn883b4sXiNzkxOxV5VASpbP7Mp4PBJ5r29n9V7Ukdm8dLXe4Qn/eo Kaf6jU/BmwNCvdNwlz7yB5kEw728GTLFo+tq8D7Wmr6yOQLuEm1TI4XOez79Ulq4s0 cdu6YcWR3cHN5746z/FBle07TF6kCkYBy0QYdCheWPZ6uzqDzJsniV/789C1G9dfbS IOm2bRGBmJ0hLkoRqNqyJ6RdAf+F1pAyPPx6PX62WxzIlWaJIqNw0lcjRMXaUW6r6/ VOQFofXyA7xyNbgn4/dTUGSx/NGuL7cpl9Xk0wema+nfhWjjpKocjpMtoMtN4grgc0 n5p03ymqyTK7g== From: Christian Brauner Date: Wed, 10 Sep 2025 16:37:17 +0200 Subject: [PATCH 32/32] selftests/namespaces: add file handle selftests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250910-work-namespace-v1-32-4dd56e7359d8@kernel.org> References: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> In-Reply-To: <20250910-work-namespace-v1-0-4dd56e7359d8@kernel.org> To: Jan Kara , Amir Goldstein , linux-fsdevel@vger.kernel.org Cc: Josef Bacik , Jeff Layton , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Alexander Viro , Jens Axboe , Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Chuck Lever , linux-nfs@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.14.3-dev-385fa X-Developer-Signature: v=1; a=openpgp-sha256; l=39947; i=brauner@kernel.org; h=from:subject:message-id; bh=mjyP74gnmM3iIM41CDhniFKSXnSvWhIDm7WadSUC65o=; b=kA0DAAoWkcYbwGV43KIByyZiAGjBjQmiO9hhdPWp0F9A5ykEsy4W3qqiIU1jT4jhr1M9hUIZ6 Ih1BAAWCgAdFiEEQIc0Vx6nDHizMmkokcYbwGV43KIFAmjBjQkACgkQkcYbwGV43KK/SwD/Z2ZN dh9ufBNjqS54HvL6OXzn7htjY4LS4PYHa8KSQIcBALsacgZADQ+YMQmvbrn1MwyZR8UPB+D621E fZ2AAevsH X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a bunch of selftests for namespace file handles. Signed-off-by: Christian Brauner Reviewed-by: Amir Goldstein --- tools/testing/selftests/namespaces/.gitignore | 1 + tools/testing/selftests/namespaces/Makefile | 2 +- .../selftests/namespaces/file_handle_test.c | 1410 ++++++++++++++++= ++++ 3 files changed, 1412 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/namespaces/.gitignore b/tools/testing/= selftests/namespaces/.gitignore index c1e8d634dd21..7639dbf58bbf 100644 --- a/tools/testing/selftests/namespaces/.gitignore +++ b/tools/testing/selftests/namespaces/.gitignore @@ -1 +1,2 @@ nsid_test +file_handle_test diff --git a/tools/testing/selftests/namespaces/Makefile b/tools/testing/se= lftests/namespaces/Makefile index 9280c703533e..f6c117ce2c2b 100644 --- a/tools/testing/selftests/namespaces/Makefile +++ b/tools/testing/selftests/namespaces/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only CFLAGS +=3D -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) =20 -TEST_GEN_PROGS :=3D nsid_test +TEST_GEN_PROGS :=3D nsid_test file_handle_test =20 include ../lib.mk =20 diff --git a/tools/testing/selftests/namespaces/file_handle_test.c b/tools/= testing/selftests/namespaces/file_handle_test.c new file mode 100644 index 000000000000..87573fa06990 --- /dev/null +++ b/tools/testing/selftests/namespaces/file_handle_test.c @@ -0,0 +1,1410 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../kselftest_harness.h" + +#ifndef FD_NSFS_ROOT +#define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */ +#endif + +TEST(nsfs_net_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open a namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/net"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_uts_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open UTS namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/uts"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_ipc_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open IPC namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/ipc"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_pid_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open PID namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/pid"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_mnt_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open mount namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/mnt"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_user_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open user namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/user"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_cgroup_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open cgroup namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/cgroup"); + ns_fd =3D open(ns_path, O_RDONLY); + if (ns_fd < 0) { + SKIP(free(handle); return, "cgroup namespace not available"); + } + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_time_handle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open time namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/time"); + ns_fd =3D open(ns_path, O_RDONLY); + if (ns_fd < 0) { + SKIP(free(handle); return, "time namespace not available"); + } + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Try to open using FD_NSFS_ROOT */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); close(ns_fd); + return, + "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd, 0); + + /* Verify we opened the correct namespace */ + ASSERT_EQ(fstat(ns_fd, &st1), 0); + ASSERT_EQ(fstat(fd, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_dev, st2.st_dev); + + close(fd); + close(ns_fd); + free(handle); +} + +TEST(nsfs_user_net_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current network namespace */ + ns_fd =3D open("/proc/self/ns/net", O_RDONLY); + ASSERT_GE(ns_fd, 0); + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new network namespace */ + ret =3D unshare(CLONE_NEWNET); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create network namespace */ + close(pipefd[1]); + exit(0); + } + + /* Try to open parent's network namespace handle from new user+net names= pace */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new network namespace"); + } + + /* Should fail with permission denied since we're in a different user nam= espace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_user_uts_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current UTS namespace */ + ns_fd =3D open("/proc/self/ns/uts", O_RDONLY); + ASSERT_GE(ns_fd, 0); + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new UTS namespace */ + ret =3D unshare(CLONE_NEWUTS); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create UTS namespace */ + close(pipefd[1]); + exit(0); + } + + /* Try to open parent's UTS namespace handle from new user+uts namespace= */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new UTS namespace"); + } + + /* Should fail with ESTALE since we're in a different user namespace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_user_ipc_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current IPC namespace */ + ns_fd =3D open("/proc/self/ns/ipc", O_RDONLY); + ASSERT_GE(ns_fd, 0); + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new IPC namespace */ + ret =3D unshare(CLONE_NEWIPC); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create IPC namespace */ + close(pipefd[1]); + exit(0); + } + + /* Try to open parent's IPC namespace handle from new user+ipc namespace= */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new IPC namespace"); + } + + /* Should fail with ESTALE since we're in a different user namespace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_user_mnt_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current mount namespace */ + ns_fd =3D open("/proc/self/ns/mnt", O_RDONLY); + ASSERT_GE(ns_fd, 0); + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new mount namespace */ + ret =3D unshare(CLONE_NEWNS); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create mount namespace */ + close(pipefd[1]); + exit(0); + } + + /* Try to open parent's mount namespace handle from new user+mnt namespa= ce */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new mount namespace"); + } + + /* Should fail with ESTALE since we're in a different user namespace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_user_cgroup_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current cgroup namespace */ + ns_fd =3D open("/proc/self/ns/cgroup", O_RDONLY); + if (ns_fd < 0) { + SKIP(free(handle); close(pipefd[0]); close(pipefd[1]); + return, "cgroup namespace not available"); + } + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new cgroup namespace */ + ret =3D unshare(CLONE_NEWCGROUP); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create cgroup namespace */ + close(pipefd[1]); + exit(0); + } + + /* Try to open parent's cgroup namespace handle from new user+cgroup nam= espace */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new cgroup namespace"); + } + + /* Should fail with ESTALE since we're in a different user namespace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_user_pid_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current PID namespace */ + ns_fd =3D open("/proc/self/ns/pid", O_RDONLY); + ASSERT_GE(ns_fd, 0); + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new PID namespace - requires fork to take effect */ + ret =3D unshare(CLONE_NEWPID); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create PID namespace */ + close(pipefd[1]); + exit(0); + } + + /* Fork again for PID namespace to take effect */ + pid_t child_pid =3D fork(); + if (child_pid < 0) { + write(pipefd[1], "N", + 1); /* Unable to fork in PID namespace */ + close(pipefd[1]); + exit(0); + } + + if (child_pid =3D=3D 0) { + /* Grandchild in new PID namespace */ + /* Try to open parent's PID namespace handle from new user+pid namespac= e */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", + 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Wait for grandchild */ + waitpid(child_pid, NULL, 0); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new PID namespace"); + } + + /* Should fail with ESTALE since we're in a different user namespace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_user_time_namespace_isolation) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + pid_t pid; + int status; + int pipefd[2]; + char result; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Create pipe for communication */ + ASSERT_EQ(pipe(pipefd), 0); + + /* Get handle for current time namespace */ + ns_fd =3D open("/proc/self/ns/time", O_RDONLY); + if (ns_fd < 0) { + SKIP(free(handle); close(pipefd[0]); close(pipefd[1]); + return, "time namespace not available"); + } + + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); close(pipefd[0]); + close(pipefd[1]); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + close(ns_fd); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* First create new user namespace to drop privileges */ + ret =3D unshare(CLONE_NEWUSER); + if (ret < 0) { + write(pipefd[1], "U", + 1); /* Unable to create user namespace */ + close(pipefd[1]); + exit(0); + } + + /* Write uid/gid mappings to maintain some capabilities */ + int uid_map_fd =3D open("/proc/self/uid_map", O_WRONLY); + int gid_map_fd =3D open("/proc/self/gid_map", O_WRONLY); + int setgroups_fd =3D open("/proc/self/setgroups", O_WRONLY); + + if (uid_map_fd < 0 || gid_map_fd < 0 || setgroups_fd < 0) { + write(pipefd[1], "M", 1); /* Unable to set mappings */ + close(pipefd[1]); + exit(0); + } + + /* Disable setgroups to allow gid mapping */ + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + /* Map current uid/gid to root in the new namespace */ + char mapping[64]; + snprintf(mapping, sizeof(mapping), "0 %d 1", getuid()); + write(uid_map_fd, mapping, strlen(mapping)); + close(uid_map_fd); + + snprintf(mapping, sizeof(mapping), "0 %d 1", getgid()); + write(gid_map_fd, mapping, strlen(mapping)); + close(gid_map_fd); + + /* Now create new time namespace - requires fork to take effect */ + ret =3D unshare(CLONE_NEWTIME); + if (ret < 0) { + write(pipefd[1], "N", + 1); /* Unable to create time namespace */ + close(pipefd[1]); + exit(0); + } + + /* Fork again for time namespace to take effect */ + pid_t child_pid =3D fork(); + if (child_pid < 0) { + write(pipefd[1], "N", + 1); /* Unable to fork in time namespace */ + close(pipefd[1]); + exit(0); + } + + if (child_pid =3D=3D 0) { + /* Grandchild in new time namespace */ + /* Try to open parent's time namespace handle from new user+time namesp= ace */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + + if (fd >=3D 0) { + /* Should NOT succeed - we're in a different user namespace */ + write(pipefd[1], "S", + 1); /* Unexpected success */ + close(fd); + } else if (errno =3D=3D ESTALE) { + /* Expected: Stale file handle */ + write(pipefd[1], "P", 1); + } else { + /* Other error */ + write(pipefd[1], "F", 1); + } + + close(pipefd[1]); + exit(0); + } + + /* Wait for grandchild */ + waitpid(child_pid, NULL, 0); + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + ASSERT_EQ(read(pipefd[0], &result, 1), 1); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(WEXITSTATUS(status), 0); + + if (result =3D=3D 'U') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new user namespace"); + } + if (result =3D=3D 'M') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot set uid/gid mappings"); + } + if (result =3D=3D 'N') { + SKIP(free(handle); close(pipefd[0]); + return, "Cannot create new time namespace"); + } + + /* Should fail with ESTALE since we're in a different user namespace */ + ASSERT_EQ(result, 'P'); + + close(pipefd[0]); + free(handle); +} + +TEST(nsfs_open_flags) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int ns_fd; + char ns_path[256]; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open a namespace file descriptor */ + snprintf(ns_path, sizeof(ns_path), "/proc/self/ns/net"); + ns_fd =3D open(ns_path, O_RDONLY); + ASSERT_GE(ns_fd, 0); + + /* Get handle for the namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(ns_fd, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(ns_fd); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + ASSERT_GT(handle->handle_bytes, 0); + + /* Test invalid flags that should fail */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_WRONLY); + ASSERT_LT(fd, 0); + ASSERT_EQ(errno, EPERM); + + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDWR); + ASSERT_LT(fd, 0); + ASSERT_EQ(errno, EPERM); + + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_CREAT); + ASSERT_LT(fd, 0); + ASSERT_EQ(errno, EINVAL); + + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_TRUNC); + ASSERT_LT(fd, 0); + ASSERT_EQ(errno, EINVAL); + + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_APPEND); + ASSERT_LT(fd, 0); + ASSERT_EQ(errno, EINVAL); + + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_DIRECT); + ASSERT_LT(fd, 0); + ASSERT_EQ(errno, EINVAL); + + close(ns_fd); + free(handle); +} + +TEST_HARNESS_MAIN --=20 2.47.3