From nobody Sun Feb 8 11:41:09 2026 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 2E7D0330B0E; Tue, 21 Oct 2025 11:43: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=1761047034; cv=none; b=JtKKBLtTI2/JFgZaMzwZtSVaHjesLmw0s/oggZqAfsDJsnjefeFbBSuWSKWmKoFsgryzRmmVttEfeHpr3Yy+GHaewVu2mNenFhxyyi8T+uDz02uaL+bEhIr6ekYR7LVGbQRoT1yhKg5EhVoIFv0P756bDJB6CpivmoF24hivgG0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047034; c=relaxed/simple; bh=wpu8fA7qXxdZSYnV2Wt9hfd/qe1FdRoJcNk3AI3VvA4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=neybPHJP6he+hV0y5xrBB0naoHYcZcShXNCeBwCas9vSSLVPMkCS6dsiQEaed6pWEjeVFyFJzVQfHEXVtG4M/R3k33V6+ki00hI7n0GDOsyRnDphJnAveEP3XilCgcHZckVo04QTaPGIRTVRw0cHcK3LYZ1jWVvB5YAjvUGDmOQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mjS4sk0Q; 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="mjS4sk0Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12EBCC4CEF5; Tue, 21 Oct 2025 11:43:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047033; bh=wpu8fA7qXxdZSYnV2Wt9hfd/qe1FdRoJcNk3AI3VvA4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mjS4sk0QTmIkELXAcJU8lcFnUD+afDGY0ZHvhxgZ5z0vJfgrh428582+xA82JXmtK wkoiRI8/il4b94YRi69gbHfUo2eH/8BYM5NOXlDhDg/mxFahhQPFg9PHnZReGGoJeo vZFAVJs6NADVKiiAy2LKhOs9GxpEXqnZqw6wQnViQhBjJyj8hM86obqe17lhclzI2d irG33clADT5LlM6MuY4WgVdvUq2U5A/I/mv3/5DdBIJdWNbDpOp9ZqXrP2ddMuNSXM JbjEPaZ3FkWMvC3nJgZ+YmLdAl5dRC2pR52e76uS3QwXtby5MtWJlKlkBbqGVNs2Zu uNroZlETLDuqw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:07 +0200 Subject: [PATCH RFC DRAFT 01/50] libfs: allow to specify s_d_flags 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: <20251021-work-namespace-nstree-listns-v1-1-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1073; i=brauner@kernel.org; h=from:subject:message-id; bh=wpu8fA7qXxdZSYnV2Wt9hfd/qe1FdRoJcNk3AI3VvA4=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3wjXZEbEZ/TtM6uIGFxsl5R0anZ+wWStty2/6/2/ P+jiyZFHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABOp7GFk2FPN/NznYaB1vobg fJPLK6dK6XKcjr8xfZXkkn1zGpS4fjMyHLxiKLp3+4GZp6/u52SW27chIdileu+Jnwc7TsrV3NH czAsA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Make it possible for pseudo filesystems to specify default dentry flags. Signed-off-by: Christian Brauner --- fs/libfs.c | 1 + include/linux/pseudo_fs.h | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/libfs.c b/fs/libfs.c index ce8c496a6940..4bb4d8a313e7 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -680,6 +680,7 @@ static int pseudo_fs_fill_super(struct super_block *s, = struct fs_context *fc) s->s_export_op =3D ctx->eops; s->s_xattr =3D ctx->xattr; s->s_time_gran =3D 1; + s->s_d_flags |=3D ctx->s_d_flags; root =3D new_inode(s); if (!root) return -ENOMEM; diff --git a/include/linux/pseudo_fs.h b/include/linux/pseudo_fs.h index 2503f7625d65..a651e60d9410 100644 --- a/include/linux/pseudo_fs.h +++ b/include/linux/pseudo_fs.h @@ -9,6 +9,7 @@ struct pseudo_fs_context { const struct xattr_handler * const *xattr; const struct dentry_operations *dops; unsigned long magic; + unsigned int s_d_flags; }; =20 struct pseudo_fs_context *init_pseudo(struct fs_context *fc, --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 70BBA32ED40; Tue, 21 Oct 2025 11:43: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=1761047039; cv=none; b=I2FPnOXXDjsFLLdy5uD1Cjwans1UnnoCthaHvv2OzFNnPc1uitqactF6gxmwzmB45n53KkHp5Ct5f7ZB65FAmla6lKZO9zde8Q5mHzoqfsPtTRYzOOs1J212gIAa72LGGTwJ9CpZLwnCjuMBXwmmjVLWtkzK/G2UuHMQXlDYVL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047039; c=relaxed/simple; bh=jSqJBpD/6utq5kB6r0uVAxUcKbpMKsXXqLyZPGG0ICk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BCHksQ4OalDKUfpTyiS1eBJc9U4eMEb7J5uvY7CAA3xF/mx+WzFqMgg2gcn9K2MbviDTtdErNSc2d/LD5PWItDjlGf2kWlX/gfibOvglPD2t+qmcVQ5CCtr4akP0EUCpcTmXoqimAIn68NPYlEWoFHNcil2yPOz2H0r+YAkjla4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gnhNCayn; 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="gnhNCayn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 377D4C4CEF1; Tue, 21 Oct 2025 11:43:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047039; bh=jSqJBpD/6utq5kB6r0uVAxUcKbpMKsXXqLyZPGG0ICk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gnhNCaynkM0wMfth/IMqriE+JgndxI+bTqUyj+wXWaqobttsBP32n1bOTm7T6UR7O PN9BUSUaCZZ60BWOQv/+qMuoUU6rILKgOZx8SRTf5o7mTZ4LhQr/4mbk3/BmR7aRth LCYOTa8bt9TOP2gTYSh7KHYkUkYOF5mAa2k8xRHJUdqKizvyfmeZj5c88hZ7d+Rk/X MldoAI/4/FIkLlrnzYs19iouUA5nf95oslSHHEhTGsKBtlqr6M9//LgmyyH+UaamP6 0SS1+O/rMehuZk2WUDmQT2W+jJQWf3+lMaNzlpFtoT7tfHi4I+8Q96Ti2DaJLCLIhP gMcp/sDMFxMuA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:08 +0200 Subject: [PATCH RFC DRAFT 02/50] nsfs: use inode_just_drop() 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: <20251021-work-namespace-nstree-listns-v1-2-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=930; i=brauner@kernel.org; h=from:subject:message-id; bh=jSqJBpD/6utq5kB6r0uVAxUcKbpMKsXXqLyZPGG0ICk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zzlsf+uqnpzEsJ7MEcDGpT1u65H7z1S6yw+yz+O Sblb1P5OkpZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTAG6yDSPD+ws3DSyXFBqvnLwk zOmO5UWlgnc3tB4etQlSkX/y6G++O8N/x3XG5+fNUw7pfqGk5rznMDvnuuV3Gww/15mX8TkfT73 LAwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Currently nsfs uses the default inode_generic_drop() fallback which drops the inode when it's unlinked or when it's unhashed. Since nsfs never hashes inodes that always amounts to dropping the inode. But that's just annoying to have to reason through every time we look at this code. Switch to inode_just_drop() which always drops the inode explicitly. This also aligns the behavior with pidfs which does the same. Signed-off-by: Christian Brauner --- fs/nsfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nsfs.c b/fs/nsfs.c index 648dc59bef7f..4e77eba0c8fc 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -408,6 +408,7 @@ static const struct super_operations nsfs_ops =3D { .statfs =3D simple_statfs, .evict_inode =3D nsfs_evict, .show_path =3D nsfs_show_path, + .drop_inode =3D inode_just_drop, }; =20 static int nsfs_init_inode(struct inode *inode, void *data) --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 DC83932E692; Tue, 21 Oct 2025 11:44:04 +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=1761047045; cv=none; b=r8Xd/DkTHtOVa8nLRePv08L4Z/5dDdXo2/W0RopPcD23D7XVtMr9B8UUX4TgBIXvDoGDw4QfOuYeePNysys1z6Qlf03V6ia1uhRiwxzYf4TXlMrF2dBVqnI8VwAPRaEFZM5GvRpx65aWIEsITGgmCz855PBvFI2Uo1JDBTSFoc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047045; c=relaxed/simple; bh=VMCLQ5Neu+JsCPfFhnjTC4pvJzkr6RMBoSrPUgoYfJM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W6r2sTwJJxceonevxeoG53Uc8Ih2oUrvwpMNrYbYxPGS+l6DuJJHl0TAnF6EtYUytp0sJct6Iumy0mVLWkZE54fRPQDND6usdHcgAzTZ6wQub9l24iP0KSCQIBdc5w+QOA5dD5giuF+pXPrB8I58bEslHB7C/hYXYLpHlqEnkJ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UQ1WDaKs; 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="UQ1WDaKs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8C55BC4CEF5; Tue, 21 Oct 2025 11:43:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047044; bh=VMCLQ5Neu+JsCPfFhnjTC4pvJzkr6RMBoSrPUgoYfJM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UQ1WDaKsPDEQbhZFxksWG3cs6XalP+MFAPtfhb1e27i+O56klnEYjmWmz8v+LNfEK lb1u3ORIzea+YbyE2BjPo3Ri8gQc3PlDFVMRfOnrT3UJp1pB846Ww0xbmKuAygaKTh hAQ+4TF0TCuO7HwF3aTUQJyq1J9YMxQK1kCUJpPzj4WOb9IugcS7bjNvekaqoqNpWa tR89Rvp8R1P5HAP9EHqXKmZNnFA/LZNG2fdzqCy8uGIp0+8jYdkK6wgYY0x4Xm9Vfg adVUATW/qL0yqG1lSFuIOUYkXp0ZFxqCY7iG2FBpqyIyO2EkHvnGKJumFPywN0AtDD Yj43n/EdOgnug== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:09 +0200 Subject: [PATCH RFC DRAFT 03/50] nsfs: raise DCACHE_DONTCACHE explicitly 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: <20251021-work-namespace-nstree-listns-v1-3-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=840; i=brauner@kernel.org; h=from:subject:message-id; bh=VMCLQ5Neu+JsCPfFhnjTC4pvJzkr6RMBoSrPUgoYfJM=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3yz8UNP+eY1LUL1iY67rCNVCw7o3c9QiCl3cGhsv Ju9c2t4RykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwET2lDAyrBLTWhs5/fCpWX7M a/nysnr+fSv/6vltg33EEtWkvx0icxj+aexvenF7bsxSP5MrDrGdrcEPeoTe1UgbSOpfXu966X8 lEwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 While nsfs dentries are never hashed and thus retain_dentry() will never consider them for placing them on the LRU it isn't great to always have to go and remember that. Raise DCACHE_DONTCACHE explicitly as a visual marker that dentries aren't kept but freed immediately instead. Signed-off-by: Christian Brauner --- fs/nsfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nsfs.c b/fs/nsfs.c index 4e77eba0c8fc..0e3fe8fda5bf 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -589,6 +589,7 @@ 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->s_d_flags |=3D DCACHE_DONTCACHE; ctx->ops =3D &nsfs_ops; ctx->eops =3D &nsfs_export_operations; ctx->dops =3D &ns_dentry_operations; --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 F1EAA32E73E; Tue, 21 Oct 2025 11:44:09 +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=1761047050; cv=none; b=YXQ4WDSGi0n9N+xkMyll1v9sjsx38q5jrTPeVEQaax1zZt8texUksOFMES3BKoKiLClGA9hEpBHm4wZcAXnR6VXd+/9h8w47cZC5ui73EMYcoNK8UwrVb1/0PprUoHNBi4vOHn4y+vkHbXMoMhO3ZgMQ81oSoHe9y2WuQMco9c0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047050; c=relaxed/simple; bh=LCe8V3QgmxQPWsHxmkO/HYNSTPj5l9bqGO1onywb9Xk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ct2vH6AjtTg9wSmarZZSQjrABAcmD4G66mh7Wk/JQcYJI/Pub0VjZi+XLsH4jG2iAs4q7UWmqjcyF9UJrHW+ffQIHvJZUSr+7q3W7iK2Q79oD0jlESJn0Z1YAuUNK2UFWKK2tDhEm6fJoLUzUZzH2Wg4GiP4Y4htB56+TRIG6SI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pu1xDtJn; 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="pu1xDtJn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D6104C4CEF1; Tue, 21 Oct 2025 11:44:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047049; bh=LCe8V3QgmxQPWsHxmkO/HYNSTPj5l9bqGO1onywb9Xk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pu1xDtJnprXIvW9VopwRTIAuFxGl24Tp6PZAaZBFgrQX/pZ3bXAl2hOhKnTPcKtk+ KZGgSPy3JeSpUQWGgj3S9grTqMDv2O6sUdkQeayHK06RzMjWRu/lFnQeZcE+aZE+tM 48lDjuD+0UDdqnaP6BSeJg+g1Mo15KkOQhZYyDij6esAO8yTEuLtRt7F4mdzjsXJ72 kXngMJev2z7TdiCNLHiMvHRTXjTxUN2tLLyoo9YfC305O9H2VLz6ej8hish4FJUOxK eH7jBdf5SK8mmX9K+nC05D2vRlJlKx0GSLAQyM80ibHAu4HTum3PBK6F19mKOdYjsC Zg31pBPEb1x1Q== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:10 +0200 Subject: [PATCH RFC DRAFT 04/50] pidfs: raise DCACHE_DONTCACHE explicitly 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: <20251021-work-namespace-nstree-listns-v1-4-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=824; i=brauner@kernel.org; h=from:subject:message-id; bh=LCe8V3QgmxQPWsHxmkO/HYNSTPj5l9bqGO1onywb9Xk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xzpUw74sT9VzwZYXxT9R+KPFHO3D9ZJZLnoPoXO f5tW1KXdZSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExk1mWGP7x7zG8x/LdL3bji doLlwp37ubctLuY+2vb9ieajYpamjTkMf8WUVhmoXBNrrn+06P82MTebamHOX/NtbZOu1/ft2mz 2iQkA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 While pidfs dentries are never hashed and thus retain_dentry() will never consider them for placing them on the LRU it isn't great to always have to go and remember that. Raise DCACHE_DONTCACHE explicitly as a visual marker that dentries aren't kept but freed immediately instead. Signed-off-by: Christian Brauner --- fs/pidfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/pidfs.c b/fs/pidfs.c index 0ef5b47d796a..db236427fc2c 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -1022,6 +1022,7 @@ static int pidfs_init_fs_context(struct fs_context *f= c) =20 fc->s_iflags |=3D SB_I_NOEXEC; fc->s_iflags |=3D SB_I_NODEV; + ctx->s_d_flags |=3D DCACHE_DONTCACHE; ctx->ops =3D &pidfs_sops; ctx->eops =3D &pidfs_export_operations; ctx->dops =3D &pidfs_dentry_operations; --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 82F9D32F75B; Tue, 21 Oct 2025 11:44:14 +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=1761047054; cv=none; b=bO5UVffDHZOhKTZcCoaJe0O9Z00IE4ZeWc1pCY9Gh5anFgBFHf6KL+j8VYd0bCXtXGlS8ax5XvJ85BU+x8W+6ytR1XXlR5W6gqj4LN+IBx8CPcJ1/u2PXj5dWpurDKKjFcfL+cgetYbsjSMi5A620CUbdldlb87peByc6zoghlM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047054; c=relaxed/simple; bh=KoKI9phRTGMhjpn+9D8BgtjcoxSIgpJa0JnjxzKpEbY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LxlunTkKWj7gejlTREkqKKRgpysHXuCKc9GynqsvkOEnvXOZ1jWf2fT8aWMRLaZw9tOkMQ2B5YUaCq0zWYvdtNCEXG7NKtAhrkxg0zWGS6gXB2TXyuk05e0eFHMpBYrqmedoNB+dDXz3nFsZeVgiuu5wLBZCiv+Ud64/7+elfEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Own9LxaO; 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="Own9LxaO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DC7EDC4CEFD; Tue, 21 Oct 2025 11:44:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047054; bh=KoKI9phRTGMhjpn+9D8BgtjcoxSIgpJa0JnjxzKpEbY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Own9LxaOxCPJgK+rss6yu3LOvggckkZJUzXvDnCFd9hWH67Vx+raWmWFZtSmgOJ4Y ZGuVtQzUuhFJ4EXY6xvatWIsikY5jOSHPP5NLm93LVfUNm7Iy8iUcUmxnOrsrG4Fzw zMeR98rZjXvd1yJhSGKBbZRFg/Q8GSODOQChwoZCN1BXm7DtgWPHa3Qdfitn63phUl 2wMoQSM4KlTCtEX4QOYaD8Vx2x2xjilPWa0BwZ6K1IPxZf6RTKxKq3/sw8CuR6JC7J NFPG8cjnR8antjb9CxpWYVFwh/bDQ2RF7JoNfsc7axWrfd62pjNiYbHzwOC18/U6eC PTNI5q22z0ppQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:11 +0200 Subject: [PATCH RFC DRAFT 05/50] nsfs: raise SB_I_NODEV and SB_I_NOEXEC 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: <20251021-work-namespace-nstree-listns-v1-5-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=647; i=brauner@kernel.org; h=from:subject:message-id; bh=KoKI9phRTGMhjpn+9D8BgtjcoxSIgpJa0JnjxzKpEbY=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xzPUlET+FOWH/IyylvX+3RTf8y6bW6e+rtvsaHH KkxGQ/ZO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACZioMbw341jYgfDjwwznwqj W87blNhiFp4UXpe/KOaV49ozi9/lNjMyLL43J9hgVYzwB/uIN69f7GJ1VVkXc79m466Sjh3bdHR nMwIA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 There's zero need for nsfs to allow device nodes or execution. Signed-off-by: Christian Brauner --- fs/nsfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nsfs.c b/fs/nsfs.c index 0e3fe8fda5bf..363be226e357 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -589,6 +589,8 @@ 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; + fc->s_iflags |=3D SB_I_NOEXEC; + fc->s_iflags |=3D SB_I_NODEV; ctx->s_d_flags |=3D DCACHE_DONTCACHE; ctx->ops =3D &nsfs_ops; ctx->eops =3D &nsfs_export_operations; --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 38E8E32ED29; Tue, 21 Oct 2025 11:44:19 +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=1761047060; cv=none; b=qdygHhCNmlZ9t2VxrHzP0aZDq/F7QdGbvfqMlj+vLLW1dONBeMO8HIFIBf0HKIOtSIMGofj/bYjfVmkWQC48daND8aBgOqp6WyKvKo1SibRDoRPrnglMrY/wrRYnZ6V3Ay3z0qtQY5uMpxBl/VLM0BmhHo5IJ0sSvIEH18i27lQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047060; c=relaxed/simple; bh=7aAHCcaecm2VZuosAD5WF6qVRIAZipjG6VYIR7g9o5A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xc55GAYFKCCWXyat99QXO7VNqeSZKljaiYdbUjNfMG/x06i0nv86hk9mlYce4UM5+fyte4ftKl5MlAwvTG55koZpZfzxkFom50u6tyfuD8E2kuR0SmNPpGG0iVlmVpQmJ1Syq6pTDCW0g+1DoMZvZ44Ot/4Db9gvYcmrxYaRjZY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y82yqj6d; 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="Y82yqj6d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7091C4CEF5; Tue, 21 Oct 2025 11:44:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047059; bh=7aAHCcaecm2VZuosAD5WF6qVRIAZipjG6VYIR7g9o5A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Y82yqj6d9aBly9/d3JdzIsvZ0gC7WxocVs1pSzc5B/GM5xVF56sEokeSmJj9xWQ2f AxR+d1jTNJzBxPXzmn1HJdD3DqX+v6GAvmpBTJ0IFAdZ5Uuy19/F3e4t/HRMCKn8Jy OO7Xugn2N7KT2Sbt+nhZkUf9zCEhdelIovC3BFq9G5xWX3d6/sPpZht8ckhImLMk8P RZjgSGY5iSd+VuIuKdm8okcxlS5X0nWVn1aX/L83aaUBM9fCL9FKcdLyPgo5p7BKK9 tSaTtupbUk1K9AE3UnE2i77evyfTssEye54k71cSBCSSDShnSoBpxSFcqI685YAZUL 9Lw3M7QvtaOPA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:12 +0200 Subject: [PATCH RFC DRAFT 06/50] nstree: simplify return 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: <20251021-work-namespace-nstree-listns-v1-6-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=670; i=brauner@kernel.org; h=from:subject:message-id; bh=7aAHCcaecm2VZuosAD5WF6qVRIAZipjG6VYIR7g9o5A=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zTULyoJv2x89unobEd/j3drZbrtjPPXH8kfd6Gl PTt1bldHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABN5s52R4XtpqM/CrDD72Zt+ bgrk0fBaedC94AL3x1NcFw8/XB5dtYzhFzPntGUGkvlv96143jS58QpvataUZpHHi+Mn2Xo82s3 oyg4A X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 node_to_ns() checks for NULL and the assert isn't really helpful and will have to be dropped later anyway. Signed-off-by: Christian Brauner --- kernel/nstree.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/kernel/nstree.c b/kernel/nstree.c index b24a320a11a6..369fd1675c6a 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -194,11 +194,6 @@ struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns= _type) break; } while (read_seqretry(&ns_tree->ns_tree_lock, seq)); =20 - if (!node) - return NULL; - - VFS_WARN_ON_ONCE(node_to_ns(node)->ns_type !=3D ns_type); - return node_to_ns(node); } =20 --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 F159732E681; Tue, 21 Oct 2025 11:44:25 +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=1761047066; cv=none; b=A8s4xZMrRePACAd10SyxeVC0GSWxlkXSxN8rJPWmn9nQLgW8j7uZMj3/ZZWub7KqA5CYs/8FKw6j3e3nE8pK/vAxYaISMbwCJLKNVKpzUy3kwK4mbxZ3vjT3BpFMUnM7Am8Zm9vvOvsr5WGDVXanJ8ynjCDclrJl3JA0/tzlE+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047066; c=relaxed/simple; bh=GmTU8Q/fclIPwxUSGwafLrmOAHz2L+FN5rNlGUSGB9Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XqMylGEFzci5Yk3gQgnxiT3Te0jjPNGgfQ3+SpGyT6dzlfJhlaHdsdul5ese/7XuraR9jeGe7JILK63VbxcJR5C8e/2taBPXnbvPSaaeNR4jHj4YBkL/xOBl6yWaTo7LBHNi83ZNOSZFlieQ9fX/VKP+I7UvqX9jrY7V/PbEUaA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hNIfXkyV; 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="hNIfXkyV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4EEC4C4CEF1; Tue, 21 Oct 2025 11:44:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047065; bh=GmTU8Q/fclIPwxUSGwafLrmOAHz2L+FN5rNlGUSGB9Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hNIfXkyVS2T600rPJfW0QEO0GGCxLcg8JUUGgqln/i2NzVuJJ78s4AGZHo8lTM/wz 4ZdqYgleuFDLbuHhq5N0aiw6ex7B+S1vmq0JSSJ0IrsF/UClq5LntEafqXerxpwWUL h0Gc4uwB1RACqVqJ//++XE7h7PqnWxF+X7aqqNyi2WUp/cQKQjvqlEWFHbhPNRGioj DTfUClzu3SQlktOBFmWO+sMw3PzXiuRYCXBvtYpNvT1eGs9lerQBYnRIvX80TpBefc G0PcZsrgDYRnY7x/f4ss8pXa2GqI3ceZUszDr+POvHLhbvtcJ1n5MuZX8a86JAFTbt Och95hBGtRcTQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:13 +0200 Subject: [PATCH RFC DRAFT 07/50] ns: initialize ns_list_node for initial namespaces 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: <20251021-work-namespace-nstree-listns-v1-7-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3505; i=brauner@kernel.org; h=from:subject:message-id; bh=GmTU8Q/fclIPwxUSGwafLrmOAHz2L+FN5rNlGUSGB9Y=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zz9SmnZ63k6e3e56zjz5n5l/Wrn9rdvIK57FPTE +7oT/UzO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACbSe5bhf6KG2tvdCjt2lBRP 8w53+/nHY1eY16QHQvzaF18fd761aSYjw7VLrvemnjzN4+TyyL/okltoovs2gdlbq0u2BGfavP2 oxAkA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Make sure that the list is always initialized for initial namespaces. Fixes: 885fc8ac0a4d ("nstree: make iterator generic") Signed-off-by: Christian Brauner --- fs/namespace.c | 1 + init/version-timestamp.c | 1 + ipc/msgutil.c | 1 + kernel/cgroup/cgroup.c | 1 + kernel/pid.c | 1 + kernel/time/namespace.c | 1 + kernel/user.c | 1 + 7 files changed, 7 insertions(+) diff --git a/fs/namespace.c b/fs/namespace.c index d82910f33dc4..8ef8ba3dd316 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5993,6 +5993,7 @@ struct mnt_namespace init_mnt_ns =3D { .passive =3D REFCOUNT_INIT(1), .mounts =3D RB_ROOT, .poll =3D __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll), + .ns.ns_list_node =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_list_node), }; =20 static void __init init_mount_tree(void) diff --git a/init/version-timestamp.c b/init/version-timestamp.c index d071835121c2..61b2405d97f9 100644 --- a/init/version-timestamp.c +++ b/init/version-timestamp.c @@ -20,6 +20,7 @@ struct uts_namespace init_uts_ns =3D { }, .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_uts_ns), + .ns.ns_list_node =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_list_node), #ifdef CONFIG_UTS_NS .ns.ops =3D &utsns_operations, #endif diff --git a/ipc/msgutil.c b/ipc/msgutil.c index 7a03f6d03de3..c9469fbce27c 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -30,6 +30,7 @@ struct ipc_namespace init_ipc_ns =3D { .ns.__ns_ref =3D REFCOUNT_INIT(1), .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_ipc_ns), + .ns.ns_list_node =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_list_node), #ifdef CONFIG_IPC_NS .ns.ops =3D &ipcns_operations, #endif diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 6ae5f48cf64e..a82918da8bae 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -256,6 +256,7 @@ struct cgroup_namespace init_cgroup_ns =3D { .ns.inum =3D ns_init_inum(&init_cgroup_ns), .root_cset =3D &init_css_set, .ns.ns_type =3D ns_common_type(&init_cgroup_ns), + .ns.ns_list_node =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_list_node), }; =20 static struct file_system_type cgroup2_fs_type; diff --git a/kernel/pid.c b/kernel/pid.c index 4fffec767a63..cb7574ca00f7 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -78,6 +78,7 @@ struct pid_namespace init_pid_ns =3D { .child_reaper =3D &init_task, .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_pid_ns), + .ns.ns_list_node =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_list_node), #ifdef CONFIG_PID_NS .ns.ops =3D &pidns_operations, #endif diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 5b6997f4dc3d..ee05cad288da 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -484,6 +484,7 @@ struct time_namespace init_time_ns =3D { .ns.inum =3D ns_init_inum(&init_time_ns), .ns.ops =3D &timens_operations, .frozen_offsets =3D true, + .ns.ns_list_node =3D LIST_HEAD_INIT(init_time_ns.ns.ns_list_node), }; =20 void __init time_ns_init(void) diff --git a/kernel/user.c b/kernel/user.c index 0163665914c9..b9cf3b056a71 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -70,6 +70,7 @@ struct user_namespace init_user_ns =3D { .owner =3D GLOBAL_ROOT_UID, .group =3D GLOBAL_ROOT_GID, .ns.inum =3D ns_init_inum(&init_user_ns), + .ns.ns_list_node =3D LIST_HEAD_INIT(init_user_ns.ns.ns_list_node), #ifdef CONFIG_USER_NS .ns.ops =3D &userns_operations, #endif --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 9D13032E681; Tue, 21 Oct 2025 11:44:31 +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=1761047071; cv=none; b=EZVbKbrLcAmADx3hEUUjR9g7qHraYGKCETqI+JXWt0JocBd2bIt4QK5NFWukr2GeHhQl/N8Vy4GyhtidBSl1DX87QTe64HEsCoOIWgh7L6/f7hJp6Bn3zu+p2E6Far75ZylqkK0sA9xTxxRDdbx9ZpNQKzpYlyyE1S9dBCMVVoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047071; c=relaxed/simple; bh=QM8oyzyJ0QczVJ0uxGx22MIzfw44XMMyED0mCYHZDF8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AtidW1vXL5CPs3kXBr1itUj5X9xYNcChOB0U23OxzSKwT9ZflowXb9IGfXBFHv5nQbLqXOOrKL8PN8S+/Ls/r87j/Q8y29vLCQ8JOwjEAzNV+DD5dL6wHyHiqb2Nv9LYifuDSwbCMqslyJDnkBpHlpdNZz/SGFN+zXb/so+VF14= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cA/9qQlH; 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="cA/9qQlH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F0DA8C4CEF5; Tue, 21 Oct 2025 11:44:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047071; bh=QM8oyzyJ0QczVJ0uxGx22MIzfw44XMMyED0mCYHZDF8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cA/9qQlHtIWh32Oj2GkiV31uJUcLZnvqPPbzP7HjxHdvFwaKyMvmRbq1TJY/3PMME 4iDtkxaydcVE/CuDSRfLnwHFjQ29ci4IGsjzGonwFh4dht4YqhB/ypdSeVjD9An7lT guOvWv5gojtOfmdQzGgMiQb04NnjlIyQ1iBTWhtV1BaN55kim7fctPswjLIUCK4pio txcBLLOQiq19FWdHh06rznzNV9BVXYCMKT9CH9+Hnt5a56QZKaXmg4/JCEiHDBRkFn O5b1B+nlCreiTLS86pyncRSw0sgbHVvWHC+cmrTGAxA3OPoPG4Wo4JRib151PS+4cf RcjiqSukZFrxQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:14 +0200 Subject: [PATCH RFC DRAFT 08/50] ns: add __ns_ref_read() 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: <20251021-work-namespace-nstree-listns-v1-8-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1108; i=brauner@kernel.org; h=from:subject:message-id; bh=QM8oyzyJ0QczVJ0uxGx22MIzfw44XMMyED0mCYHZDF8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zTmVHMyWo8zSs1f3PELLeo5smC3zprHBbulWP+f iIz1PhXRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwEQsUhn+2W/IML2/dgmTwkWn rRdEo7MC8qpzN/gcYp696OFJzo6034wM07WmCgv6enbvMlyXzDxrp+736R89jOa/N5H4URvE3m7 HCQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Implement ns_ref_read() the same way as ns_ref_{get,put}(). No point in making that any more special or different from the other helpers. Signed-off-by: Christian Brauner --- include/linux/ns_common.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index f5b68b8abb54..32114d5698dc 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -143,7 +143,12 @@ static __always_inline __must_check bool __ns_ref_get(= struct ns_common *ns) return refcount_inc_not_zero(&ns->__ns_ref); } =20 -#define ns_ref_read(__ns) refcount_read(&to_ns_common((__ns))->__ns_ref) +static __always_inline __must_check int __ns_ref_read(const struct ns_comm= on *ns) +{ + return refcount_read(&ns->__ns_ref); +} + +#define ns_ref_read(__ns) __ns_ref_read(to_ns_common((__ns))) #define ns_ref_inc(__ns) refcount_inc(&to_ns_common((__ns))->__ns_ref) #define ns_ref_get(__ns) __ns_ref_get(to_ns_common((__ns))) #define ns_ref_put(__ns) __ns_ref_put(to_ns_common((__ns))) --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 B6E28224AF9; Tue, 21 Oct 2025 11:44:36 +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=1761047076; cv=none; b=XnegMZwJNx+Yq9l2x0tgfui2nGMRsRyKNb2IMBdMa973V63VZDhi87IO/Zz8AXZcey3LCKYO7+NL5XgqFi6AcyZlr8e+tWrlwv7UBXTkXRTXUpqxMKth9OPQPmsxl/VN80Y6ncSIkeg3fqQrJSJkNmHWpXtMAV/DeE9iV3eEp80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047076; c=relaxed/simple; bh=FiitUvg09AgTVhs9E4zEJ6gk/1ltwJmCmgPCymEI4ts=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=am40aL54UxFQdbTsvNvnIGZjHsYNbAV0OJCS8qLoxSiv56u+pq7Ix7r8WvyuLObryXspxg5Xu/9XRGN44g7HTgZO8irYMVJmUFiOzvKzYMJzXCaI8wLooXFO2QaU1RQegHtWkxm538cVodhZMNz65B40ROyOlBtg8ARtRjI4b6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iVRoxhQ/; 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="iVRoxhQ/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D4D1C4CEF1; Tue, 21 Oct 2025 11:44:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047076; bh=FiitUvg09AgTVhs9E4zEJ6gk/1ltwJmCmgPCymEI4ts=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=iVRoxhQ/gb1elyQhDgVhjFqDTN9xEHXPRw1f/9zOo+CBGbX5vPfb8/Eov3nmDfW2Z 2yHtiF5RbosGjDxev/gsQhdyiVqrrA0bgo0mn+ZyBesBKEtwfGgjf1xI75O7h2JlUE dX6vHd4DF8W9Y1S2DmhYEmk+LzLs4ficj60XnDkr3WrM1YccTYhxqc6K0U4/6Q8WlB OoJ29sFEzbYg3bu2vVeyevTQdiyrCGIgaYrpPgNj5eE+CsY8/OuMmOwGEoIXGxI+pb Ykki8NfnX47SodAPvf3825dYPSkZKIrwcWOXNnwfiIXQ2sm5YfiSnslvN2sPtFTYXk iGO25/lg3YTLw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:15 +0200 Subject: [PATCH RFC DRAFT 09/50] ns: add active reference count 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: <20251021-work-namespace-nstree-listns-v1-9-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=25765; i=brauner@kernel.org; h=from:subject:message-id; bh=FiitUvg09AgTVhs9E4zEJ6gk/1ltwJmCmgPCymEI4ts=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3wzMZZrwWW529lsH38v86g/8FY3YWJs2o4oLTFJ6 WLbnRXuHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABNxNGNk6NQ/pPmtnO2SX9ei jcnP3mwsNay8mL3X/95fuVlKdVct7zL8dzAomsMr3bWl4t+UwxqJqyu54yb825n9qvfOmwmdAos mcAIA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The namespace tree is, among other things, currently used to support file handles for namespaces. When a namespace is created it is placed on the namespace trees and when it is destroyed it is removed from the namespace trees. While a namespace is on the namespace trees with a valid reference count it is possible to reopen it through a namespace file handle. This is all fine but has some issues that should be addressed. On current kernels a namespace is visible to userspace in the following cases: (1) The namespace is in use by a task. (2) The namespace is persisted through a VFS object (namespace file, bind-m= ount). Note that (2) only cares about direct persistence of the namespace itself not indirectly via e.g., file->f_cred file references or similar. (3) The namespace is a hierarchical namespace type and is the parent of a single or multiple child namespaces. Case (3) is interesting because it is possible that a parent namespace might not fulfill any of (1) or (2), i.e., is invisible to userspace but it may still be resurrected through the NS_GET_PARENT ioctl(). Currently namespace file handles allow much broader access to namespaces than what is currently possible via (1)-(4). The reason is that namespaces may remain pinned for completely internal reasons yet are inaccessible to userspace. For example, a user namespace my remain pinned by get_cred() calles to stash the opener's credentials into file->f_cred. As it stands file handles allow to resurrect such a users namespace even though this should not be possible via (1)-(3). This is a fundamental uapi change that we shouldn't do. Consider the following insane case. Various architectures support the CONFIG_MMU_LAZY_TLB_REFCOUNT option which uses lazy TLB destruction. When this option is set a userspace task's struct mm_struct may be used for kernel threads such as the idle task and will only be destroyed once the cpu's runqueue switch back to another task. The kernel thread will take a reference on the struct mm_struct. For ptrace() based access checks struct mm_struct stashes the user namespace of the task that struct mm_struct belonged to originally and thus takes a reference to the users namespace and pins it. So on a big idle system with loads and loads of CPUs user namespaces can be persisted for arbitrary amount of time which also means that can be resurrected using namespace file handles. That makes no sense whatsoever. We could ofc try and fix this but this is pointless surgery and there's no need to change the refcounting rules for the actual __ns_ref count. Instead we introduce a proper liveliness reference count __ns_ref_active which tracks (1)-(3). This is easy to do as all of these things are already managed centrally. Only (1)-(3) will count towards __ns_ref_active count and only namespaces which are active may be opened via namespace file handles. The __ns_ref_active reference count does not regulate the lifetime of the namespace itself. This is still done by __ns_ref. The __ns_ref_active count can only be elevated if the __ns_ref count is non-zero. Furthermore, it also doesn't regulate the presence of a namespace on the namespace trees. Any namespace remains on the namespace trees until it is actually destroyed. This will allow the kernel to always reach any namespace trivially and it will also enable stuff like bpf to walk the namespace lists on the system for tracing or general introspection purposes to e.g., debug problems where namespaces are pinned. Different namespaces under /proc//ns/ may have different lifetimes on current kernels. While most namespace are immediately released when the last task using them _exits_, the user- and pid namespace are persisted and thus both remain accessible via /proc//ns/. The user namespace lifetime is aliged with struct cred and is only released through exit_creds(). However, it becomes inaccessible to userspace once the last task using it is _reaped_, i.e., when release_task() is called and all proc entries are flushed. Similarly, the pid namespace is also visible until the last task using it has been reaped. Both the user- and pid namespace are marked as inactive once the task is reaped. Signed-off-by: Christian Brauner --- fs/namespace.c | 2 + fs/nsfs.c | 32 +++++++++++- include/linux/ns_common.h | 123 ++++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/nsfs.h | 3 ++ init/version-timestamp.c | 1 + ipc/msgutil.c | 1 + ipc/namespace.c | 1 + kernel/cgroup/cgroup.c | 1 + kernel/cgroup/namespace.c | 1 + kernel/cred.c | 17 +++++++ kernel/exit.c | 1 + kernel/nscommon.c | 53 +++++++++++++++++++- kernel/nsproxy.c | 7 +++ kernel/pid.c | 11 +++++ kernel/pid_namespace.c | 1 + kernel/time/namespace.c | 2 + kernel/user.c | 1 + kernel/user_namespace.c | 1 + kernel/utsname.c | 1 + net/core/net_namespace.c | 1 + 20 files changed, 259 insertions(+), 2 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 8ef8ba3dd316..87116def5ee3 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4173,6 +4173,7 @@ struct mnt_namespace *copy_mnt_ns(u64 flags, struct m= nt_namespace *ns, p =3D next_mnt(skip_mnt_tree(p), old); } ns_tree_add_raw(new_ns); + ns_ref_active_get_owner(new_ns); return new_ns; } =20 @@ -5989,6 +5990,7 @@ struct mnt_namespace init_mnt_ns =3D { .ns.ops =3D &mntns_operations, .user_ns =3D &init_user_ns, .ns.__ns_ref =3D REFCOUNT_INIT(1), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .ns.ns_type =3D ns_common_type(&init_mnt_ns), .passive =3D REFCOUNT_INIT(1), .mounts =3D RB_ROOT, diff --git a/fs/nsfs.c b/fs/nsfs.c index 363be226e357..a190e1e38442 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -58,6 +58,8 @@ const struct dentry_operations ns_dentry_operations =3D { static void nsfs_evict(struct inode *inode) { struct ns_common *ns =3D inode->i_private; + + __ns_ref_active_put(ns); clear_inode(inode); ns->ops->put(ns); } @@ -419,6 +421,10 @@ static int nsfs_init_inode(struct inode *inode, void *= data) inode->i_mode |=3D S_IRUGO; inode->i_fop =3D &ns_file_operations; inode->i_ino =3D ns->inum; + + if (!__ns_ref_active_get_not_zero(ns)) + return -ENOENT; + return 0; } =20 @@ -493,7 +499,7 @@ static struct dentry *nsfs_fh_to_dentry(struct super_bl= ock *sb, struct fid *fh, VFS_WARN_ON_ONCE(ns->ns_type !=3D fid->ns_type); VFS_WARN_ON_ONCE(ns->inum !=3D fid->ns_inum); =20 - if (!__ns_ref_get(ns)) + if (!ns_get(ns)) return NULL; } =20 @@ -614,3 +620,27 @@ void __init nsfs_init(void) nsfs_root_path.mnt =3D nsfs_mnt; nsfs_root_path.dentry =3D nsfs_mnt->mnt_root; } + +void nsproxy_ns_active_get(struct nsproxy *ns) +{ + ns_ref_active_get(ns->mnt_ns); + ns_ref_active_get(ns->uts_ns); + ns_ref_active_get(ns->ipc_ns); + ns_ref_active_get(ns->pid_ns_for_children); + ns_ref_active_get(ns->cgroup_ns); + ns_ref_active_get(ns->net_ns); + ns_ref_active_get(ns->time_ns); + ns_ref_active_get(ns->time_ns_for_children); +} + +void nsproxy_ns_active_put(struct nsproxy *ns) +{ + ns_ref_active_put(ns->mnt_ns); + ns_ref_active_put(ns->uts_ns); + ns_ref_active_put(ns->ipc_ns); + ns_ref_active_put(ns->pid_ns_for_children); + ns_ref_active_put(ns->cgroup_ns); + ns_ref_active_put(ns->net_ns); + ns_ref_active_put(ns->time_ns); + ns_ref_active_put(ns->time_ns_for_children); +} diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 32114d5698dc..5d19471235ab 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -4,7 +4,9 @@ =20 #include #include +#include #include +#include =20 struct proc_ns_operations; =20 @@ -37,6 +39,73 @@ extern const struct proc_ns_operations cgroupns_operatio= ns; extern const struct proc_ns_operations timens_operations; extern const struct proc_ns_operations timens_for_children_operations; =20 +/* + * Namespace lifetimes are managed via a two-tier reference counting model: + * + * (1) __ns_ref (refcount_t): Main reference count tracking memory lifetim= e. + * Controls when the namespace structure itself is freed. It also + * pins the namespace on the namespace trees whereas (2) only + * regulates their visibility to userspace. + * + * (2) __ns_ref_active (atomic_t): Reference count tracking active users. + * Controls visibility of the namespace in the namespace trees. + * Any live task that uses the namespace (via nsproxy or cred) holds + * an active reference. Any open file descriptor or bind-mount of + * the namespace holds an active reference. Once all tasks have + * called exit_task_namespaces() and all file descriptors and + * bind-mounts have been released the active reference count drops + * to zero and the namespace becomes inactive. IOW, the namespace + * cannot be listed or opened via file handles anymore. + * + * Note that it is valid to transition from active to inactive and + * back from inactive to active e.g., when walking a hierarchical + * namespace tree upwards and reopening parent namespaces via + * NS_GET_PARENT that only exist because they are a parent of an + * actively used namespace. + * + * Relationship and lifecycle states: + * + * - Active (__ns_ref_active > 0): + * Namespace is actively used by one or more tasks. The namespace can + * be reopened via /proc//ns/ or discovered in the + * namespace tree. + * + * - Inactive (__ns_ref_active =3D=3D 0, __ns_ref > 0): + * No tasks are actively using the namespace and it isn't pinned by + * any bind-mounts or open file descriptors anymore. But the namespace + * is still kept alive by internal references. For example, the user + * namespace could be pinned by an open file through file->f_cred + * references when one of the now defunct tasks had opened a file and + * handed the file descriptor off to another process via a UNIX + * socket. Such references keep the namespace structure alive through + * __ns_ref but will not take an active reference. + * + * - Destroyed (__ns_ref =3D=3D 0): + * No references remain. The namespace is removed from the tree and free= d. + * + * State transitions: + * + * Active -> Inactive: + * When the last task using the namespace exits (via + * exit_task_namespaces()), it drops its active references to all + * namespaces apart from the pid namespace which remains accessible + * until the task has been reaped and its pid number is released. + * + * Inactive -> Active: + * When walking a hierarchical namespace tree upwards and reopening + * parent namespaces via NS_GET_PARENT that only exist because they + * are a parent of an actively used namespace it is possible to + * necrobump an inactive namespace back to the active state. + * + * Inactive -> Destroyed: + * When __ns_ref drops to zero (last file descriptor closed, last bind + * mount removed, parent namespace released), the namespace is removed + * from the tree and the memory is freed (after RCU grace period). + * + * Initial namespaces: + * Boot-time namespaces (init_net, init_pid_ns, etc.) start with + * __ns_ref_active =3D 1 and remain active forever. + */ struct ns_common { u32 ns_type; struct dentry *stashed; @@ -48,6 +117,7 @@ struct ns_common { u64 ns_id; struct rb_node ns_tree_node; struct list_head ns_list_node; + atomic_t __ns_ref_active; /* do not use directly */ }; struct rcu_head ns_rcu; }; @@ -56,6 +126,13 @@ struct ns_common { int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_= ns_operations *ops, int inum); void __ns_common_free(struct ns_common *ns); =20 +static __always_inline bool is_initial_namespace(struct ns_common *ns) +{ + VFS_WARN_ON_ONCE(ns->inum =3D=3D 0); + return unlikely(in_range(ns->inum, MNT_NS_INIT_INO, + IPC_NS_INIT_INO - MNT_NS_INIT_INO + 1)); +} + #define to_ns_common(__ns) \ _Generic((__ns), \ struct cgroup_namespace *: &(__ns)->ns, \ @@ -133,6 +210,11 @@ void __ns_common_free(struct ns_common *ns); =20 #define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns))) =20 +static __always_inline __must_check int __ns_ref_active_read(const struct = ns_common *ns) +{ + return atomic_read(&ns->__ns_ref_active); +} + static __always_inline __must_check bool __ns_ref_put(struct ns_common *ns) { return refcount_dec_and_test(&ns->__ns_ref); @@ -155,4 +237,45 @@ static __always_inline __must_check int __ns_ref_read(= const struct ns_common *ns #define ns_ref_put_and_lock(__ns, __lock) \ refcount_dec_and_lock(&to_ns_common((__ns))->__ns_ref, (__lock)) =20 +#define ns_ref_active_read(__ns) \ + ((__ns) ? __ns_ref_active_read(to_ns_common(__ns)) : 0) + +void __ns_ref_active_get_owner(struct ns_common *ns); + +static __always_inline void __ns_ref_active_get(struct ns_common *ns) +{ + WARN_ON_ONCE(atomic_add_negative(1, &ns->__ns_ref_active)); + VFS_WARN_ON_ONCE(is_initial_namespace(ns) && __ns_ref_active_read(ns) <= =3D 0); +} +#define ns_ref_active_get(__ns) \ + do { if (__ns) __ns_ref_active_get(to_ns_common(__ns)); } while (0) + +static __always_inline bool __ns_ref_active_get_not_zero(struct ns_common = *ns) +{ + return atomic_inc_not_zero(&ns->__ns_ref_active); +} + +#define ns_ref_active_get_owner(__ns) \ + do { if (__ns) __ns_ref_active_get_owner(to_ns_common(__ns)); } while (0) + +void __ns_ref_active_put_owner(struct ns_common *ns); + +static __always_inline void __ns_ref_active_put(struct ns_common *ns) +{ + if (atomic_dec_and_test(&ns->__ns_ref_active)) + __ns_ref_active_put_owner(ns); +} +#define ns_ref_active_put(__ns) \ + do { if (__ns) __ns_ref_active_put(to_ns_common(__ns)); } while (0) + +/* + * Grab a reference if the namespace is still active. This is + * intentionally racy. + */ +static __always_inline bool ns_get(struct ns_common *ns) +{ + VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) && !__ns_ref_read(ns)); + return __ns_ref_active_read(ns) && __ns_ref_get(ns); +} + #endif diff --git a/include/linux/nsfs.h b/include/linux/nsfs.h index e5a5fa83d36b..731b67fc2fec 100644 --- a/include/linux/nsfs.h +++ b/include/linux/nsfs.h @@ -37,4 +37,7 @@ void nsfs_init(void); =20 #define current_in_namespace(__ns) (__current_namespace_from_type(__ns) = =3D=3D __ns) =20 +void nsproxy_ns_active_get(struct nsproxy *ns); +void nsproxy_ns_active_put(struct nsproxy *ns); + #endif /* _LINUX_NSFS_H */ diff --git a/init/version-timestamp.c b/init/version-timestamp.c index 61b2405d97f9..c38498f94646 100644 --- a/init/version-timestamp.c +++ b/init/version-timestamp.c @@ -10,6 +10,7 @@ struct uts_namespace init_uts_ns =3D { .ns.ns_type =3D ns_common_type(&init_uts_ns), .ns.__ns_ref =3D REFCOUNT_INIT(2), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .name =3D { .sysname =3D UTS_SYSNAME, .nodename =3D UTS_NODENAME, diff --git a/ipc/msgutil.c b/ipc/msgutil.c index c9469fbce27c..d7c66b430470 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -28,6 +28,7 @@ DEFINE_SPINLOCK(mq_lock); */ struct ipc_namespace init_ipc_ns =3D { .ns.__ns_ref =3D REFCOUNT_INIT(1), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_ipc_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_list_node), diff --git a/ipc/namespace.c b/ipc/namespace.c index 59b12fcb40bd..23390d4f9b1f 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -87,6 +87,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_na= mespace *user_ns, sem_init_ns(ns); shm_init_ns(ns); ns_tree_add(ns); + ns_ref_active_get_owner(ns); =20 return ns; =20 diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index a82918da8bae..a18ec090ad7e 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -251,6 +251,7 @@ bool cgroup_enable_per_threadgroup_rwsem __read_mostly; /* cgroup namespace for init task */ struct cgroup_namespace init_cgroup_ns =3D { .ns.__ns_ref =3D REFCOUNT_INIT(2), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .user_ns =3D &init_user_ns, .ns.ops =3D &cgroupns_operations, .ns.inum =3D ns_init_inum(&init_cgroup_ns), diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c index fdbe57578e68..08be24baad98 100644 --- a/kernel/cgroup/namespace.c +++ b/kernel/cgroup/namespace.c @@ -31,6 +31,7 @@ static struct cgroup_namespace *alloc_cgroup_ns(void) if (ret) return ERR_PTR(ret); ns_tree_add(new_ns); + ns_ref_active_get_owner(new_ns); return no_free_ptr(new_ns); } =20 diff --git a/kernel/cred.c b/kernel/cred.c index dbf6b687dc5c..25de5b76bbe4 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -343,6 +343,13 @@ int copy_creds(struct task_struct *p, u64 clone_flags) =20 p->cred =3D p->real_cred =3D get_cred(new); inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); + + /* + * Increment active ref for user_ns. Each task gets its own active + * reference, even if CLONE_THREAD shares the cred structure. + */ + ns_ref_active_get(new->user_ns); + return 0; =20 error_put: @@ -435,6 +442,16 @@ int commit_creds(struct cred *new) */ if (new->user !=3D old->user || new->user_ns !=3D old->user_ns) inc_rlimit_ucounts(new->ucounts, UCOUNT_RLIMIT_NPROC, 1); + + /* + * Swap active refs if changing user_ns. This task is switching from + * actively using old->user_ns to actively using new->user_ns. + */ + if (new->user_ns !=3D old->user_ns) { + ns_ref_active_get(new->user_ns); + ns_ref_active_put(old->user_ns); + } + rcu_assign_pointer(task->real_cred, new); rcu_assign_pointer(task->cred, new); if (new->user !=3D old->user || new->user_ns !=3D old->user_ns) diff --git a/kernel/exit.c b/kernel/exit.c index 9f74e8f1c431..599375553c1f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -291,6 +291,7 @@ void release_task(struct task_struct *p) write_unlock_irq(&tasklist_lock); /* @thread_pid can't go away until free_pids() below */ proc_flush_pid(thread_pid); + ns_ref_active_put(p->real_cred->user_ns); add_device_randomness(&p->se.sum_exec_runtime, sizeof(p->se.sum_exec_runtime)); free_pids(post.pids); diff --git a/kernel/nscommon.c b/kernel/nscommon.c index c1fb2bad6d72..a324a12868fc 100644 --- a/kernel/nscommon.c +++ b/kernel/nscommon.c @@ -2,6 +2,7 @@ =20 #include #include +#include #include =20 #ifdef CONFIG_DEBUG_VFS @@ -52,6 +53,8 @@ static void ns_debug(struct ns_common *ns, const struct p= roc_ns_operations *ops) =20 int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_= ns_operations *ops, int inum) { + int ret; + refcount_set(&ns->__ns_ref, 1); ns->stashed =3D NULL; ns->ops =3D ops; @@ -68,10 +71,58 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type,= const struct proc_ns_ope ns->inum =3D inum; return 0; } - return proc_alloc_inum(&ns->inum); + ret =3D proc_alloc_inum(&ns->inum); + if (ret) + return ret; + /* + * Tree ref starts at 0. It's incremented when namespace enters + * active use (installed in nsproxy) and decremented when all + * active uses are gone. Initial namespaces are always active. + */ + if (is_initial_namespace(ns)) + atomic_set(&ns->__ns_ref_active, 1); + else + atomic_set(&ns->__ns_ref_active, 0); + return 0; } =20 void __ns_common_free(struct ns_common *ns) { proc_free_inum(ns->inum); } + +void __ns_ref_active_get_owner(struct ns_common *ns) +{ + struct user_namespace *owner; + + if (unlikely(!ns->ops)) + return; + VFS_WARN_ON_ONCE(!ns->ops->owner); + owner =3D ns->ops->owner(ns); + VFS_WARN_ON_ONCE(!owner && ns !=3D to_ns_common(&init_user_ns)); + if (!owner) + return; + /* Skip init_user_ns as it's always active */ + if (owner =3D=3D &init_user_ns) + return; + WARN_ON_ONCE(atomic_add_negative(1, &to_ns_common(owner)->__ns_ref_active= )); +} + +void __ns_ref_active_put_owner(struct ns_common *ns) +{ + struct user_namespace *owner; + + do { + if (unlikely(!ns->ops)) + return; + VFS_WARN_ON_ONCE(!ns->ops->owner); + owner =3D ns->ops->owner(ns); + VFS_WARN_ON_ONCE(!owner && ns !=3D to_ns_common(&init_user_ns)); + if (!owner) + return; + /* Skip init_user_ns as it's always active */ + if (owner =3D=3D &init_user_ns) + return; + ns =3D to_ns_common(owner); + } while (atomic_dec_and_test(&to_ns_common(owner)->__ns_ref_active)); +} diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index 19aa64ab08c8..3324d827f6bc 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -26,6 +26,7 @@ #include #include #include +#include =20 static struct kmem_cache *nsproxy_cachep; =20 @@ -179,12 +180,15 @@ int copy_namespaces(u64 flags, struct task_struct *ts= k) if ((flags & CLONE_VM) =3D=3D 0) timens_on_fork(new_ns, tsk); =20 + nsproxy_ns_active_get(new_ns); tsk->nsproxy =3D new_ns; return 0; } =20 void free_nsproxy(struct nsproxy *ns) { + nsproxy_ns_active_put(ns); + put_mnt_ns(ns->mnt_ns); put_uts_ns(ns->uts_ns); put_ipc_ns(ns->ipc_ns); @@ -232,6 +236,9 @@ void switch_task_namespaces(struct task_struct *p, stru= ct nsproxy *new) =20 might_sleep(); =20 + if (new) + nsproxy_ns_active_get(new); + task_lock(p); ns =3D p->nsproxy; p->nsproxy =3D new; diff --git a/kernel/pid.c b/kernel/pid.c index cb7574ca00f7..4f7b5054e23d 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -72,6 +72,7 @@ static int pid_max_max =3D PID_MAX_LIMIT; */ struct pid_namespace init_pid_ns =3D { .ns.__ns_ref =3D REFCOUNT_INIT(2), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .idr =3D IDR_INIT(init_pid_ns.idr), .pid_allocated =3D PIDNS_ADDING, .level =3D 0, @@ -118,9 +119,13 @@ static void delayed_put_pid(struct rcu_head *rhp) void free_pid(struct pid *pid) { int i; + struct pid_namespace *active_ns; =20 lockdep_assert_not_held(&tasklist_lock); =20 + active_ns =3D pid->numbers[pid->level].ns; + ns_ref_active_put(active_ns); + spin_lock(&pidmap_lock); for (i =3D 0; i <=3D pid->level; i++) { struct upid *upid =3D pid->numbers + i; @@ -285,6 +290,12 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t = *set_tid, spin_unlock(&pidmap_lock); idr_preload_end(); =20 + /* + * Increment active ref for the task's active PID namespace. + * This marks the namespace as actively in use by a running task. + */ + ns_ref_active_get(ns); + return pid; =20 out_unlock: diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 650be58d8d18..2e678338c6d1 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -124,6 +124,7 @@ static struct pid_namespace *create_pid_namespace(struc= t user_namespace *user_ns #endif =20 ns_tree_add(ns); + ns_ref_active_get_owner(ns); return ns; =20 out_free_inum: diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index ee05cad288da..2e7c110bd13f 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -106,6 +106,7 @@ static struct time_namespace *clone_time_ns(struct user= _namespace *user_ns, ns->offsets =3D old_ns->offsets; ns->frozen_offsets =3D false; ns_tree_add(ns); + ns_ref_active_get_owner(ns); return ns; =20 fail_free_page: @@ -480,6 +481,7 @@ const struct proc_ns_operations timens_for_children_ope= rations =3D { struct time_namespace init_time_ns =3D { .ns.ns_type =3D ns_common_type(&init_time_ns), .ns.__ns_ref =3D REFCOUNT_INIT(3), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_time_ns), .ns.ops =3D &timens_operations, diff --git a/kernel/user.c b/kernel/user.c index b9cf3b056a71..bf60532856db 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -67,6 +67,7 @@ struct user_namespace init_user_ns =3D { }, .ns.ns_type =3D ns_common_type(&init_user_ns), .ns.__ns_ref =3D REFCOUNT_INIT(3), + .ns.__ns_ref_active =3D ATOMIC_INIT(1), .owner =3D GLOBAL_ROOT_UID, .group =3D GLOBAL_ROOT_GID, .ns.inum =3D ns_init_inum(&init_user_ns), diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 03cb63883d04..9da3ee9e2eb1 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -160,6 +160,7 @@ int create_user_ns(struct cred *new) =20 set_cred_user_ns(new, ns); ns_tree_add(ns); + ns_ref_active_get_owner(ns); return 0; fail_keyring: #ifdef CONFIG_PERSISTENT_KEYRINGS diff --git a/kernel/utsname.c b/kernel/utsname.c index ebbfc578a9d3..18f55a05ad5b 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -60,6 +60,7 @@ static struct uts_namespace *clone_uts_ns(struct user_nam= espace *user_ns, ns->user_ns =3D get_user_ns(user_ns); up_read(&uts_sem); ns_tree_add(ns); + ns_ref_active_get_owner(ns); return ns; =20 fail_free: diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b0e0f22d7b21..f30fb78f020c 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -450,6 +450,7 @@ static __net_init int setup_net(struct net *net) list_add_tail_rcu(&net->list, &net_namespace_list); up_write(&net_rwsem); ns_tree_add_raw(net); + ns_ref_active_get_owner(net); out: return error; =20 --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 934F9331A41; Tue, 21 Oct 2025 11:44:42 +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=1761047082; cv=none; b=iBOxH5FsNdbGKm+7jvvbuq0dRsKn6kEuBaHqwM6PuVYH/XxE54k+2AnH89qgKQq2KP+RMB4lQ2kyFrIjIPIItjy7Q65vRyJMrSGd3YAABjq92DmSPm0jeWBI8Kit2zR61yD7GNeQSYQtCOQ811xQFjYprLlUaTo38tO3QRNEoaU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047082; c=relaxed/simple; bh=eNIUpqO2UCHoi2ksC8FU54CizOc19jWeKxEd6r2H28o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pSoUV1UbLK8N5kSLZKWbBp0pEI8S7ILXYp8Iw7cn9b7svGIli5M0xsiSoJqd7Y6/nxjcP4dnL5Z5b1Ai7eMpJwhVDOVwEnXT2+RfrtDewsxovHPv36adoQJloAqREW9ZXc/Llc0oZzrww2RJ5L4yyIL85WJB8YddjF1TKEF0G94= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z5WLHdd+; 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="Z5WLHdd+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12456C4CEF1; Tue, 21 Oct 2025 11:44:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047082; bh=eNIUpqO2UCHoi2ksC8FU54CizOc19jWeKxEd6r2H28o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Z5WLHdd+EBfxO8Wsx4dELH3U3MnpmfFj+1e0RdpBk+8Z9N1PMClqYZ8vg+Nn7il/7 nC0KRI3vJ4uyCYS22JXA6Tkhde+X5OJ3itknXaLTlxcDKKmbGoeIjqRiN033iwQefP mzpT9u1mkUlxhNl6ATQ8GvJNqEUQyDUBIP2h95vCM5VSy7jdCQy28akWj9fqadHinT MUFN7ZNiAuCR0xlkCJQyMIzOOnz01n4gegwqDCNmN2xM2WOTPLnsXUtaLgaIxDGGfe k/8GvYG9s/akqsUHebsAsbjux5Ji5DI/ATAFYc7anDtJ/QKUd0+t2jKfwsEkSJkB+T S9Sk43Qk9ujMg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:16 +0200 Subject: [PATCH RFC DRAFT 10/50] ns: use anonymous struct to group list member 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: <20251021-work-namespace-nstree-listns-v1-10-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=775; i=brauner@kernel.org; h=from:subject:message-id; bh=eNIUpqO2UCHoi2ksC8FU54CizOc19jWeKxEd6r2H28o=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3yzXZVR83TgjbuKGScXzf67xtDm2M9pt1Qbk82Pz f13dQPLgo5SFgYxLgZZMUUWh3aTcLnlPBWbjTI1YOawMoEMYeDiFICJnN3PyDBRL+T2DJ9VwnHH UryZBDaca1vWbmbxr+5PV1ZDbHbgrwxGhlN8Tlmv5+/4qaVpN+tt8tmKpH83H+3WL2g9YBnSvvz kZj4A X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Make it easier to spot that they belong together conceptually. Signed-off-by: Christian Brauner --- include/linux/ns_common.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 5d19471235ab..34e072986955 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -115,8 +115,10 @@ struct ns_common { union { struct { u64 ns_id; - struct rb_node ns_tree_node; - struct list_head ns_list_node; + struct /* per type rbtree and list */ { + struct rb_node ns_tree_node; + struct list_head ns_list_node; + }; atomic_t __ns_ref_active; /* do not use directly */ }; struct rcu_head ns_rcu; --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 A99B332E12F; Tue, 21 Oct 2025 11:44: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=1761047087; cv=none; b=ki97ObD1NINJKE8/vQeaEIyM4CJnNung7+27Zas4T76zVk2FuVYqu4qrEf3KEFiS4NAjieno+WxepbtdngydhtBDr+WbN7wRtEKPepGR8h299iod2YucdonjcFeMZ1EVDImq0KbLiC9hucxRSY+9nXJ1rmX56UEedVLUrxFIGg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047087; c=relaxed/simple; bh=O61lzlU7zIePmJGHxACkFGdVOWtNCGmg2WWZDRE/vXY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iy9CeTBZWdFMRseb5U2BirrpTM8SbOsx5qar6WlJoqIXry2lKqcRpDhUo0Bre+FI5IE02SUHYEkzn7PvOl/opKGeJar5DkAWg2VjtIX1XG4BPrjvOxreCx7BgMi3Ce76r8KBE/3JU5Tft9upkx8Ebj+IdPMhrqUcGB3bJrtAgx8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=caNcfmTi; 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="caNcfmTi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9BDEEC4CEFD; Tue, 21 Oct 2025 11:44:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047087; bh=O61lzlU7zIePmJGHxACkFGdVOWtNCGmg2WWZDRE/vXY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=caNcfmTie/lE/JyZgf9BgZ3DR7Qo6q1YgftwZl885K10h6UhzgTfKQ2m85d6kDhEU L2a98838n2yE6C/dubS1liQhc/wqVdzzchjWQmLutr4q9law/cYsbeEHyN0kjGUgm2 XsqT4ngMyhWRIt2nSYBM/edA0EgrRefVrhaZnxmYfh1O49iGSO7mrbqsR90H5m5mYM X7JOZHY9Z95vSjMXFycv/+0CXp/fp3coMEZHAFYQccPRLq8IwNwEr6MYBdusOWl0MA xj4cEOZGntXFGjxMlDCdfObN+ZYf7uxYVXiDzeoOpYQHpIWfD0B/B2nG8tQKMmaz+4 XCtPaKcmd5SWA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:17 +0200 Subject: [PATCH RFC DRAFT 11/50] nstree: introduce a unified tree 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: <20251021-work-namespace-nstree-listns-v1-11-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=8126; i=brauner@kernel.org; h=from:subject:message-id; bh=O61lzlU7zIePmJGHxACkFGdVOWtNCGmg2WWZDRE/vXY=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3yz+c/L+ac8Stv46oq0Hk/fMmuX1knVvZf9PFw+c H/iOhhysqOUhUGMi0FWTJHFod0kXG45T8Vmo0wNmDmsTCBDGLg4BWAiT7Yw/C+vWJMRZjAhU6eq +P3Vyf4xzJPsM9KFuNLif8/7dza/ZQ8jwwTO7kU39lTyPg9VOtKe5GvjOmWJ0LvHxXd8/tjaMt1 rZAIA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 This will allow userspace to lookup and stat a namespace simply by its identifier without having to know what type of namespace it is. Signed-off-by: Christian Brauner --- include/linux/ns_common.h | 4 ++ kernel/nscommon.c | 1 + kernel/nstree.c | 94 ++++++++++++++++++++++++++++++++++++-------= ---- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 34e072986955..ad65005d3371 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -115,6 +115,10 @@ struct ns_common { union { struct { u64 ns_id; + struct /* global namespace rbtree and list */ { + struct rb_node ns_unified_tree_node; + struct list_head ns_unified_list_node; + }; struct /* per type rbtree and list */ { struct rb_node ns_tree_node; struct list_head ns_list_node; diff --git a/kernel/nscommon.c b/kernel/nscommon.c index a324a12868fc..c97a7bbb7d76 100644 --- a/kernel/nscommon.c +++ b/kernel/nscommon.c @@ -61,6 +61,7 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, c= onst struct proc_ns_ope ns->ns_id =3D 0; ns->ns_type =3D ns_type; RB_CLEAR_NODE(&ns->ns_tree_node); + RB_CLEAR_NODE(&ns->ns_unified_tree_node); INIT_LIST_HEAD(&ns->ns_list_node); =20 #ifdef CONFIG_DEBUG_VFS diff --git a/kernel/nstree.c b/kernel/nstree.c index 369fd1675c6a..d21df06b6747 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -4,31 +4,30 @@ #include #include =20 +__cacheline_aligned_in_smp DEFINE_SEQLOCK(ns_tree_lock); +static struct rb_root ns_unified_tree =3D RB_ROOT; /* protected by ns_tree= _lock */ + /** * 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 * @type: type of namespaces in this tree */ struct ns_tree { - struct rb_root ns_tree; - struct list_head ns_list; - seqlock_t ns_tree_lock; - int type; + struct rb_root ns_tree; + struct list_head ns_list; + int type; }; =20 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, }; =20 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); @@ -36,42 +35,36 @@ 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, }; =20 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, }; =20 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, }; =20 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, }; =20 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, }; =20 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, }; =20 @@ -84,6 +77,13 @@ static inline struct ns_common *node_to_ns(const struct = rb_node *node) return rb_entry(node, struct ns_common, ns_tree_node); } =20 +static inline struct ns_common *node_to_ns_unified(const struct rb_node *n= ode) +{ + if (!node) + return NULL; + return rb_entry(node, struct ns_common, ns_unified_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); @@ -98,13 +98,27 @@ static inline int ns_cmp(struct rb_node *a, const struc= t rb_node *b) return 0; } =20 +static inline int ns_cmp_unified(struct rb_node *a, const struct rb_node *= b) +{ + struct ns_common *ns_a =3D node_to_ns_unified(a); + struct ns_common *ns_b =3D node_to_ns_unified(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; =20 VFS_WARN_ON_ONCE(!ns->ns_id); =20 - write_seqlock(&ns_tree->ns_tree_lock); + write_seqlock(&ns_tree_lock); =20 VFS_WARN_ON_ONCE(ns->ns_type !=3D ns_tree->type); =20 @@ -119,7 +133,8 @@ void __ns_tree_add_raw(struct ns_common *ns, struct ns_= tree *ns_tree) else list_add_rcu(&ns->ns_list_node, &node_to_ns(prev)->ns_list_node); =20 - write_sequnlock(&ns_tree->ns_tree_lock); + rb_find_add_rcu(&ns->ns_unified_tree_node, &ns_unified_tree, ns_cmp_unifi= ed); + write_sequnlock(&ns_tree_lock); =20 VFS_WARN_ON_ONCE(node); } @@ -130,11 +145,12 @@ void __ns_tree_remove(struct ns_common *ns, struct ns= _tree *ns_tree) VFS_WARN_ON_ONCE(list_empty(&ns->ns_list_node)); VFS_WARN_ON_ONCE(ns->ns_type !=3D ns_tree->type); =20 - write_seqlock(&ns_tree->ns_tree_lock); + write_seqlock(&ns_tree_lock); rb_erase(&ns->ns_tree_node, &ns_tree->ns_tree); + rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree); list_bidir_del_rcu(&ns->ns_list_node); RB_CLEAR_NODE(&ns->ns_tree_node); - write_sequnlock(&ns_tree->ns_tree_lock); + write_sequnlock(&ns_tree_lock); } EXPORT_SYMBOL_GPL(__ns_tree_remove); =20 @@ -150,6 +166,17 @@ static int ns_find(const void *key, const struct rb_no= de *node) return 0; } =20 +static int ns_find_unified(const void *key, const struct rb_node *node) +{ + const u64 ns_id =3D *(u64 *)key; + const struct ns_common *ns =3D node_to_ns_unified(node); + + if (ns_id < ns->ns_id) + return -1; + if (ns_id > ns->ns_id) + return 1; + return 0; +} =20 static struct ns_tree *ns_tree_from_type(int ns_type) { @@ -175,28 +202,51 @@ static struct ns_tree *ns_tree_from_type(int ns_type) return NULL; } =20 -struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns_type) +static struct ns_common *__ns_unified_tree_lookup_rcu(u64 ns_id) { - struct ns_tree *ns_tree; struct rb_node *node; unsigned int seq; =20 - RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "suspicious ns_tree_lookup_rcu() = usage"); + do { + seq =3D read_seqbegin(&ns_tree_lock); + node =3D rb_find_rcu(&ns_id, &ns_unified_tree, ns_find_unified); + if (node) + break; + } while (read_seqretry(&ns_tree_lock, seq)); + + return node_to_ns_unified(node); +} + +static 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; =20 ns_tree =3D ns_tree_from_type(ns_type); if (!ns_tree) return NULL; =20 do { - seq =3D read_seqbegin(&ns_tree->ns_tree_lock); + seq =3D read_seqbegin(&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)); + } while (read_seqretry(&ns_tree_lock, seq)); =20 return node_to_ns(node); } =20 +struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns_type) +{ + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "suspicious ns_tree_lookup_rcu() = usage"); + + if (ns_type) + return __ns_tree_lookup_rcu(ns_id, ns_type); + + return __ns_unified_tree_lookup_rcu(ns_id); +} + /** * ns_tree_adjoined_rcu - find the next/previous namespace in the same * tree --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 102183321B3; Tue, 21 Oct 2025 11:44: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=1761047093; cv=none; b=GmUtrHMSPg8Ee88v1GV8I/aZWByeylj0+b+SAh49Oe9eXvUfA/8/oNQ7ePWSFcBnDqZj2wRDiYJlKRbGfV9hbBUp5L+6UJyqIece7mQnT50RVdnw/em07wK84LZRgrIkwIN1uk4QNaWISNyJoh1py2dw1pDn4VYmObLchC045Ds= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047093; c=relaxed/simple; bh=eWr4sp3ZFxiKmdi2bQvM/V/b89IuZ5Yj6h5wRkppsEI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H5VpitGPhsAbYoY8/LFvyIT2bf+smOxlq4GtCsCbCFyGB2MTvegVWQIBz5XkJv54tZdlLASM16rN3WwUMTvCeL2Xu2Ywxd3yzYxSbWgDPmLDP3Pc2EjykUjjGj9ELGfUgpX6ip2bkDkglhz2+tKKVlBWJVYv+mlmxnlHLLx4IYI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JYJboOxS; 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="JYJboOxS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0121BC4CEF1; Tue, 21 Oct 2025 11:44:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047092; bh=eWr4sp3ZFxiKmdi2bQvM/V/b89IuZ5Yj6h5wRkppsEI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JYJboOxSdjvgZ72iFp79ep7mtAlNBvWehcuffbFyhLCGqjmqEdiB1uXDSS4Xp8+Z9 2w91e6Vjl2WDorjBQI5+IjlpJwYIwsIlIspjbS0Sve398GNcLurAY/UqxJs73mlLZK 6izkD33g4iuZ8Tnncrrw0kkboPpI9XhTwnOxNyaC0XYFZstVba/uWLwEVgIm7fFJyn uAqbYyfsWGCY/5ZxIGDrGMUdVEjJ24/PP7mNqA2Q7r4UVOfnaH/Iu2Wbdce7NAcE3S EiMv950HoBaMRtimjoX+w+5GoB834LKRi3eF2U6rBGegU4CDqmUpDqIDmLPUZr6ZGc 8QCBA5S25IyAg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:18 +0200 Subject: [PATCH RFC DRAFT 12/50] nstree: allow lookup solely based on inode 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: <20251021-work-namespace-nstree-listns-v1-12-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1215; i=brauner@kernel.org; h=from:subject:message-id; bh=eWr4sp3ZFxiKmdi2bQvM/V/b89IuZ5Yj6h5wRkppsEI=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3z7wVL2f3n670Bxkc6KRlWndfMjz51+nyhYKy+w7 q++3o3EjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIk8PcXwh/O43b0f68z6I2v+ 3ZpuzXPTJkywqWtlm/AlBTXzr462jxgZ1lXJzlW5yXD5iKNEzQSlq0fkvhu36LuoddfpHnz/xUi RGwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The namespace file handle struct nsfs_file_handle is uapi and userspace is expressly allowed to generate file handles without going through name_to_handle_at(). Allow userspace to generate a file handle where both the inode number and the namespace type are zero and just pass in the unique namespace id. The kernel uses the unified namespace tree to find the namespace and open the file handle. When the kernel creates a file handle via name_to_handle_at() it will always fill in the type and the inode number allowing userspace to retrieve core information. Signed-off-by: Christian Brauner --- fs/nsfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nsfs.c b/fs/nsfs.c index a190e1e38442..ba5863ee4150 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -496,8 +496,8 @@ static struct dentry *nsfs_fh_to_dentry(struct super_bl= ock *sb, struct fid *fh, return NULL; =20 VFS_WARN_ON_ONCE(ns->ns_id !=3D fid->ns_id); - VFS_WARN_ON_ONCE(ns->ns_type !=3D fid->ns_type); - VFS_WARN_ON_ONCE(ns->inum !=3D fid->ns_inum); + if (fid->ns_inum && (fid->ns_inum !=3D ns->inum)) + return NULL; =20 if (!ns_get(ns)) return NULL; --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 CCD1F3321CC; Tue, 21 Oct 2025 11:44:58 +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=1761047098; cv=none; b=mjCFhziS1Hh6I2/b0IUlmsUh2GJoWUNl8qBbJNOwFAtwrEWMXa3IpceTKJ55e08UNwI8k5EMM6yRJUmABvWLUWlX7a9SqKj7UyMVqWJVPfNinonOVsK97LzsxH2bmMhnNnCtxoiLgbjvBOm+YqjZ+0CKJUGnJoRJ6oU2LEung1c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047098; c=relaxed/simple; bh=0Z06FS7PHlmbbOXNaiYAotrcXY1wE2OxBYSA5XT3a6Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Sp8RRxWW2FYxzx2nxw29k0TbSkl7qzK8O8PHt0WmbUc9OzhaVYmoLh0pDPqZmar3HIEmgD4nLAUUqAQUg54A0556VUts7RIePuNzQq5n+65hfpLdyBVDBCYzLJYoF6MJkNAYiVs0eYQhhHlWCB0cDXx9AeSgWZY28lCjdXROlFI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kWW3VcX0; 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="kWW3VcX0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88277C4CEF1; Tue, 21 Oct 2025 11:44:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047098; bh=0Z06FS7PHlmbbOXNaiYAotrcXY1wE2OxBYSA5XT3a6Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kWW3VcX0M3TMk7YVqkSZ5+lzz5RaH52E946bVAWpoMZ+bojRkGGiUHfTN+k54qy57 Xa5U4BLkIRt/3uHrP5aLHxriLfM1hVdd8H7pQ7XbUFSagZz0fWWwOcMgYI6HFL8ISt +JMN+R4Jh0zWJnnb+76N8X3SG80SIYZyU4HE2Omtiz5s6SVM5mBdt69NQK57m06ToI e/8UlJq1/5QPq9qe+80aoBil2nQM+zQ9KV/1R9knS1UR6SvF6cC2+uFhvdpFav7ALG BCbdCteAiXlRQGTEnJVxzdiI2A/prMsAVm1kNBvBcNsuKrSEfYuwOPDIDRojD7vuBd 2R9/YW32RMMzQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:19 +0200 Subject: [PATCH RFC DRAFT 13/50] nstree: assign fixed ids to the initial namespaces 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: <20251021-work-namespace-nstree-listns-v1-13-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=6182; i=brauner@kernel.org; h=from:subject:message-id; bh=0Z06FS7PHlmbbOXNaiYAotrcXY1wE2OxBYSA5XT3a6Q=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xbILydectXo2lu822310eb6Z3pzlfRXX8isEGB3 Vbm0jLujlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIlIWjEyPPZw0+WNZ/vffs7b Ol96TbTH5q3Kx3kWvlz1cfa9Sp02B0aGWQe7O5l++z6Vf9MyIzN5tkICS37kze/3KqdWNXyLW/u RFwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The initial set of namespace comes with fixed inode numbers making it easy for userspace to identify them solely based on that information. This has long preceeded anything here. Similarly, let's assign fixed namespace ids for the initial namespaces. Kill the cookie and use a sequentially increasing number. This has the nice side-effect that the owning user namespace will always have a namespace id that is smaller than any of it's descendant namespaces. Signed-off-by: Christian Brauner --- fs/namespace.c | 2 +- include/linux/nstree.h | 26 ++++++++++++++++++++++---- include/uapi/linux/nsfs.h | 14 ++++++++++++++ kernel/nstree.c | 13 ++++++++----- net/core/net_namespace.c | 2 +- 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 87116def5ee3..5d8a80e1e944 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4094,7 +4094,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user= _namespace *user_ns, bool a return ERR_PTR(ret); } if (!anon) - ns_tree_gen_id(&new_ns->ns); + ns_tree_gen_id(new_ns); refcount_set(&new_ns->passive, 1); new_ns->mounts =3D RB_ROOT; init_waitqueue_head(&new_ns->poll); diff --git a/include/linux/nstree.h b/include/linux/nstree.h index 8b8636690473..96ee71622517 100644 --- a/include/linux/nstree.h +++ b/include/linux/nstree.h @@ -8,6 +8,7 @@ #include #include #include +#include =20 extern struct ns_tree cgroup_ns_tree; extern struct ns_tree ipc_ns_tree; @@ -29,7 +30,22 @@ extern struct ns_tree uts_ns_tree; struct user_namespace *: &(user_ns_tree), \ struct uts_namespace *: &(uts_ns_tree)) =20 -u64 ns_tree_gen_id(struct ns_common *ns); +#define ns_init_id(__ns) \ + _Generic((__ns), \ + struct cgroup_namespace *: CGROUP_NS_INIT_ID, \ + struct ipc_namespace *: IPC_NS_INIT_ID, \ + struct mnt_namespace *: MNT_NS_INIT_ID, \ + struct net *: NET_NS_INIT_ID, \ + struct pid_namespace *: PID_NS_INIT_ID, \ + struct time_namespace *: TIME_NS_INIT_ID, \ + struct user_namespace *: USER_NS_INIT_ID, \ + struct uts_namespace *: UTS_NS_INIT_ID) + +#define ns_tree_gen_id(__ns) \ + __ns_tree_gen_id(to_ns_common(__ns), \ + (((__ns) =3D=3D ns_init_ns(__ns)) ? ns_init_id(__ns) : 0)) + +u64 __ns_tree_gen_id(struct ns_common *ns, u64 id); 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); @@ -37,9 +53,9 @@ struct ns_common *__ns_tree_adjoined_rcu(struct ns_common= *ns, struct ns_tree *ns_tree, bool previous); =20 -static inline void __ns_tree_add(struct ns_common *ns, struct ns_tree *ns_= tree) +static inline void __ns_tree_add(struct ns_common *ns, struct ns_tree *ns_= tree, u64 id) { - ns_tree_gen_id(ns); + __ns_tree_gen_id(ns, id); __ns_tree_add_raw(ns, ns_tree); } =20 @@ -59,7 +75,9 @@ static inline void __ns_tree_add(struct ns_common *ns, st= ruct ns_tree *ns_tree) * 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)) +#define ns_tree_add(__ns) \ + __ns_tree_add(to_ns_common(__ns), to_ns_tree(__ns), \ + (((__ns) =3D=3D ns_init_ns(__ns)) ? ns_init_id(__ns) : 0)) =20 /** * ns_tree_remove - Remove a namespace from a namespace tree diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h index e098759ec917..f8bc2aad74d6 100644 --- a/include/uapi/linux/nsfs.h +++ b/include/uapi/linux/nsfs.h @@ -67,4 +67,18 @@ struct nsfs_file_handle { #define NSFS_FILE_HANDLE_SIZE_VER0 16 /* sizeof first published struct */ #define NSFS_FILE_HANDLE_SIZE_LATEST sizeof(struct nsfs_file_handle) /* si= zeof latest published struct */ =20 +enum init_ns_id { + IPC_NS_INIT_ID =3D 1ULL, + UTS_NS_INIT_ID =3D 2ULL, + USER_NS_INIT_ID =3D 3ULL, + PID_NS_INIT_ID =3D 4ULL, + CGROUP_NS_INIT_ID =3D 5ULL, + TIME_NS_INIT_ID =3D 6ULL, + NET_NS_INIT_ID =3D 7ULL, + MNT_NS_INIT_ID =3D 8ULL, +#ifdef __KERNEL__ + NS_LAST_INIT_ID =3D MNT_NS_INIT_ID, +#endif +}; + #endif /* __LINUX_NSFS_H */ diff --git a/kernel/nstree.c b/kernel/nstree.c index d21df06b6747..de5ceda44637 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -68,8 +68,6 @@ struct ns_tree time_ns_tree =3D { .type =3D CLONE_NEWTIME, }; =20 -DEFINE_COOKIE(namespace_cookie); - static inline struct ns_common *node_to_ns(const struct rb_node *node) { if (!node) @@ -278,15 +276,20 @@ struct ns_common *__ns_tree_adjoined_rcu(struct ns_co= mmon *ns, /** * ns_tree_gen_id - generate a new namespace id * @ns: namespace to generate id for + * @id: if non-zero, this is the initial namespace and this is a fixed id * * 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) +u64 __ns_tree_gen_id(struct ns_common *ns, u64 id) { - guard(preempt)(); - ns->ns_id =3D gen_cookie_next(&namespace_cookie); + static atomic64_t namespace_cookie =3D ATOMIC64_INIT(NS_LAST_INIT_ID + 1); + + if (id) + ns->ns_id =3D id; + else + ns->ns_id =3D atomic64_inc_return(&namespace_cookie); return ns->ns_id; } diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index f30fb78f020c..a76b9b9709d6 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -439,7 +439,7 @@ static __net_init int setup_net(struct net *net) LIST_HEAD(net_exit_list); int error =3D 0; =20 - net->net_cookie =3D ns_tree_gen_id(&net->ns); + net->net_cookie =3D ns_tree_gen_id(net); =20 list_for_each_entry(ops, &pernet_list, list) { error =3D ops_init(ops, net); --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 9A339302770; Tue, 21 Oct 2025 11:45:04 +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=1761047104; cv=none; b=eumhXii5FvHXVXlttZi3yB6UZJNzGI4F891/nuIA6QEdtk/W/LSniSHpxOJs9gFmJoB0C6DTdUQefVJRUFnHFokGEf7WdkHhQyDsXTFLqsu9kVR/NJkXMH0AakpdTDCEG86Kf8h1mEOn+DcWJjLtOGqnUVE00lMJC9LnxsgHR4Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047104; c=relaxed/simple; bh=wDeGvgekKi09C6MeiCLFUF2cCe1JtDXGXJ+HNHX+esw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RwlZ8Y0I6dPTmnLmXiFpj9d+dXPrxy87CaW/cGRmDmpY3J6wTeg5AVsmB/RK69FkAw+Ki5PuJ1yyLhGI9iO3lPX8/2PHkUL/fPd/ZdckD+UvBDFxkl4gqKaTYcmGtX9IGkKYkzEKiHX2t9NTb77QLk6WGuu/vxRjsK+mtP+2VfE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HgUkwYWV; 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="HgUkwYWV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4158EC116D0; Tue, 21 Oct 2025 11:44:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047104; bh=wDeGvgekKi09C6MeiCLFUF2cCe1JtDXGXJ+HNHX+esw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HgUkwYWVLsUwV3wlU4c8zE4vjpKBmhpETgH2GvSwOPeGdug0VcYG5pRbTdjdmJdaM maa9vfs17zESm5goVMO1Sar1o+1s8+dHn/UgxW4qbmzQRDl9IBoiVwH0FMYxEvC/Q+ 9K8uQQT8mcnpuKUYRUnri7fjmML9wrfk3bqajtukzeSOly7+RrPYz4PaCPF4VJ0sh0 0UV/YOQ9tPKJRV2gQFpg/XvuenJLELAdq/ghNc02waDzU6HclSBqvJwtDBS1WEI9wY XyEdKhndC/kWCOACw8O3urBxenkISmk9TqCRjN6muEAwg/upp42DfAAuvREVjlAOkV A0jbY2O/xPeMg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:20 +0200 Subject: [PATCH RFC DRAFT 14/50] ns: maintain list of owned namespaces 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: <20251021-work-namespace-nstree-listns-v1-14-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=7611; i=brauner@kernel.org; h=from:subject:message-id; bh=wDeGvgekKi09C6MeiCLFUF2cCe1JtDXGXJ+HNHX+esw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zLtZK1P76DT0eYfdkioVTuB9PvTOvmffzqQ4SDw FutFNasjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgImknGBkmH97+yZGJht/w8Tq s90PNvU/Yq3TfNncUFgczbS2rSn/MsN/74BrKfXBtx7tWZDHMXMi604un8D1U9M6OrnNK1smiCT wAgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The namespace tree doesn't express the ownership concept of namespace appropriately. Maintain a list of directly owned namespaces per user namespace. This will allow userspace and the kernel to use the listns() system call to walk the namespace tree by owning user namespace. Read-only list operations are completely lockless. Signed-off-by: Christian Brauner --- fs/namespace.c | 2 ++ include/linux/ns_common.h | 4 ++++ init/version-timestamp.c | 2 ++ ipc/msgutil.c | 2 ++ kernel/cgroup/cgroup.c | 2 ++ kernel/nscommon.c | 2 ++ kernel/nstree.c | 19 +++++++++++++++++++ kernel/pid.c | 2 ++ kernel/time/namespace.c | 2 ++ kernel/user.c | 2 ++ 10 files changed, 39 insertions(+) diff --git a/fs/namespace.c b/fs/namespace.c index 5d8a80e1e944..d460ca79f0e7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5996,6 +5996,8 @@ struct mnt_namespace init_mnt_ns =3D { .mounts =3D RB_ROOT, .poll =3D __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll), .ns.ns_list_node =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_list_node), + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_owner), }; =20 static void __init init_mount_tree(void) diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index ad65005d3371..1afeaa93d319 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -123,6 +123,10 @@ struct ns_common { struct rb_node ns_tree_node; struct list_head ns_list_node; }; + struct /* namespace ownership list */ { + struct list_head ns_owner; /* list of namespaces owned by this namespa= ce */ + struct list_head ns_owner_entry; /* node in the owner namespace's ns_o= wned list */ + }; atomic_t __ns_ref_active; /* do not use directly */ }; struct rcu_head ns_rcu; diff --git a/init/version-timestamp.c b/init/version-timestamp.c index c38498f94646..e5c278dabecf 100644 --- a/init/version-timestamp.c +++ b/init/version-timestamp.c @@ -22,6 +22,8 @@ struct uts_namespace init_uts_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_uts_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_list_node), + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_owner), #ifdef CONFIG_UTS_NS .ns.ops =3D &utsns_operations, #endif diff --git a/ipc/msgutil.c b/ipc/msgutil.c index d7c66b430470..ce1de73725c0 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -32,6 +32,8 @@ struct ipc_namespace init_ipc_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_ipc_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_list_node), + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_owner), #ifdef CONFIG_IPC_NS .ns.ops =3D &ipcns_operations, #endif diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index a18ec090ad7e..41a1fc562ed0 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -258,6 +258,8 @@ struct cgroup_namespace init_cgroup_ns =3D { .root_cset =3D &init_css_set, .ns.ns_type =3D ns_common_type(&init_cgroup_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_list_node), + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_owner), }; =20 static struct file_system_type cgroup2_fs_type; diff --git a/kernel/nscommon.c b/kernel/nscommon.c index c97a7bbb7d76..0ef2939daf33 100644 --- a/kernel/nscommon.c +++ b/kernel/nscommon.c @@ -63,6 +63,8 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, c= onst struct proc_ns_ope RB_CLEAR_NODE(&ns->ns_tree_node); RB_CLEAR_NODE(&ns->ns_unified_tree_node); INIT_LIST_HEAD(&ns->ns_list_node); + INIT_LIST_HEAD(&ns->ns_owner); + INIT_LIST_HEAD(&ns->ns_owner_entry); =20 #ifdef CONFIG_DEBUG_VFS ns_debug(ns, ops); diff --git a/kernel/nstree.c b/kernel/nstree.c index de5ceda44637..829682bb04a1 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -3,6 +3,7 @@ #include #include #include +#include =20 __cacheline_aligned_in_smp DEFINE_SEQLOCK(ns_tree_lock); static struct rb_root ns_unified_tree =3D RB_ROOT; /* protected by ns_tree= _lock */ @@ -113,8 +114,10 @@ static inline int ns_cmp_unified(struct rb_node *a, co= nst struct rb_node *b) void __ns_tree_add_raw(struct ns_common *ns, struct ns_tree *ns_tree) { struct rb_node *node, *prev; + const struct proc_ns_operations *ops =3D ns->ops; =20 VFS_WARN_ON_ONCE(!ns->ns_id); + VFS_WARN_ON_ONCE(ns->ns_type !=3D ns_tree->type); =20 write_seqlock(&ns_tree_lock); =20 @@ -132,6 +135,21 @@ void __ns_tree_add_raw(struct ns_common *ns, struct ns= _tree *ns_tree) list_add_rcu(&ns->ns_list_node, &node_to_ns(prev)->ns_list_node); =20 rb_find_add_rcu(&ns->ns_unified_tree_node, &ns_unified_tree, ns_cmp_unifi= ed); + + if (ops) { + struct user_namespace *user_ns; + + VFS_WARN_ON_ONCE(!ops->owner); + user_ns =3D ops->owner(ns); + if (user_ns) { + struct ns_common *owner =3D &user_ns->ns; + VFS_WARN_ON_ONCE(owner->ns_type !=3D CLONE_NEWUSER); + list_add_tail_rcu(&ns->ns_owner_entry, &owner->ns_owner); + } else { + /* Only the initial user namespace doesn't have an owner. */ + VFS_WARN_ON_ONCE(ns !=3D to_ns_common(&init_user_ns)); + } + } write_sequnlock(&ns_tree_lock); =20 VFS_WARN_ON_ONCE(node); @@ -148,6 +166,7 @@ void __ns_tree_remove(struct ns_common *ns, struct ns_t= ree *ns_tree) rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree); list_bidir_del_rcu(&ns->ns_list_node); RB_CLEAR_NODE(&ns->ns_tree_node); + list_bidir_del_rcu(&ns->ns_owner_entry); write_sequnlock(&ns_tree_lock); } EXPORT_SYMBOL_GPL(__ns_tree_remove); diff --git a/kernel/pid.c b/kernel/pid.c index 4f7b5054e23d..f82dab348540 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -80,6 +80,8 @@ struct pid_namespace init_pid_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_pid_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_list_node), + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_owner), #ifdef CONFIG_PID_NS .ns.ops =3D &pidns_operations, #endif diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 2e7c110bd13f..15cb74267c75 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -485,6 +485,8 @@ struct time_namespace init_time_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_time_ns), .ns.ops =3D &timens_operations, + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_time_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_time_ns.ns.ns_owner), .frozen_offsets =3D true, .ns.ns_list_node =3D LIST_HEAD_INIT(init_time_ns.ns.ns_list_node), }; diff --git a/kernel/user.c b/kernel/user.c index bf60532856db..e392768ccd44 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -72,6 +72,8 @@ struct user_namespace init_user_ns =3D { .group =3D GLOBAL_ROOT_GID, .ns.inum =3D ns_init_inum(&init_user_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_user_ns.ns.ns_list_node), + .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_user_ns.ns.ns_owner_entry), + .ns.ns_owner =3D LIST_HEAD_INIT(init_user_ns.ns.ns_owner), #ifdef CONFIG_USER_NS .ns.ops =3D &userns_operations, #endif --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 EAFAD3321CA; Tue, 21 Oct 2025 11:45:09 +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=1761047110; cv=none; b=m/L3woVW+ZMc2QMb9auUdNZJ+AU1BcHa0wkNaaTX9W1ywbA80gOFPkG30687NdoQcR+ZH/9bepdeAX1uqB5uyn6vP6qDWEl01WjKerSOIRMJLK84lce6g1gTCUHoz/yX2+gWFw8l/7mNHJdPPWY4DvsXpDIPzjkMFBa4M52vsA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047110; c=relaxed/simple; bh=WzCNs8mY+FmpJ+YGymHPLKTZYpsE6yN0bYa2ba9zCgU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eT7+223pfeLuP52P7GBYQaCEmFiNrpGE09YyWApVuPYHNf9iTNLaK4ZBZxntLzhNefmutrR54Ot5H1S1ip7HXwVzWazziz1TzZF7UdJiF6V/CNGeQsNurW/LQ0XZDbJKsvVxuNG2MGZOjRhdXk9uXo2qVCkBSNXCbYsWVGoaEfA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iVOEqrRb; 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="iVOEqrRb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B086FC4CEF1; Tue, 21 Oct 2025 11:45:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047109; bh=WzCNs8mY+FmpJ+YGymHPLKTZYpsE6yN0bYa2ba9zCgU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=iVOEqrRbKsqhKVeOK+TrO3d+tGdKqHMWNXcxDjCgdaUbrq9tlFiY7LOQB0FD4EMAV lJd0Hu8olltIgL0CQVxQSVbhxGecw+4MjoPY/q0ozj73uFjWcqLWeXWlVmeUyK7vD9 MA22cyZFx4FGK1kXBAabvMLr9R+N+KdGpiDU/5fD3E3UglSX45U2mEoywZbiCldtcm ReFlGDpHCItcEo+Q85ABn3S2IHGuBhaw+NcOae+XFSs+qrTNNN/5orasnWFjVsu8N/ ot5N8IU5fl88H6X4HGafoO/nEYXh6I2of+n1UC/C1vqunQr6F2cwHMHOtLjImjuTU7 xdGCleMtoyTiQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:21 +0200 Subject: [PATCH RFC DRAFT 15/50] nstree: add listns() 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: <20251021-work-namespace-nstree-listns-v1-15-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=30001; i=brauner@kernel.org; h=from:subject:message-id; bh=WzCNs8mY+FmpJ+YGymHPLKTZYpsE6yN0bYa2ba9zCgU=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xbYPd6VYFfU9r93lMpql/0Dn39NzM97kt6ydZLO +JXTuhP7ShlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZiIPiPDbxYVT0f1zGomhxqe 6P89WQpH9A6/YJwcKWC0z4xHWGvvLYZ/ljoF0srLbrnpR5lE2eVdPhHB8LWOu+fmb+N3Gx3ufAh mBQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a new listns() system call that allows userspace to iterate through namespaces in the system. This provides a programmatic interface to discover and inspect namespaces, enhancing existing namespace apis. Currently, there is no direct way for userspace to enumerate namespaces in the system. Applications must resort to scanning /proc//ns/ across all processes, which is: 1. Inefficient - requires iterating over all processes 2. Incomplete - misses inactive namespaces that aren't attached to any running process but are kept alive by file descriptors, bind mounts, or parent namespace references 3. Permission-heavy - requires access to /proc for many processes 4. No ordering or ownership. 5. No filtering per namespace type: Must always iterate and check all namespaces. The list goes on. The listns() system call solves these problems by providing direct kernel-level enumeration of namespaces. It is similar to listmount() but obviously tailored to namespaces. /* * @req: Pointer to struct ns_id_req specifying search parameters * @ns_ids: User buffer to receive namespace IDs * @nr_ns_ids: Size of ns_ids buffer (maximum number of IDs to return) * @flags: Reserved for future use (must be 0) */ ssize_t listns(const struct ns_id_req *req, u64 *ns_ids, size_t nr_ns_ids, unsigned int flags); Returns: - On success: Number of namespace IDs written to ns_ids - On error: Negative error code /* * @size: Structure size * @ns_id: Starting point for iteration; use 0 for first call, then * use the last returned ID for subsequent calls to paginate * @ns_type: Bitmask of namespace types to include (from enum ns_type): * 0: Return all namespace types * MNT_NS: Mount namespaces * NET_NS: Network namespaces * USER_NS: User namespaces * etc. Can be OR'd together * @user_ns_id: Filter results to namespaces owned by this user namespace: * 0: Return all namespaces (subject to permission checks) * LISTNS_CURRENT_USER: Namespaces owned by caller's user name= space * Other value: Namespaces owned by the specified user namespa= ce ID */ struct ns_id_req { __u32 size; /* sizeof(struct ns_id_req) */ __u32 spare; /* Reserved, must be 0 */ __u64 ns_id; /* Last seen namespace ID (for pagination) */ __u32 ns_type; /* Filter by namespace type(s) */ __u32 spare2; /* Reserved, must be 0 */ __u64 user_ns_id; /* Filter by owning user namespace */ }; Example 1: List all namespaces void list_all_namespaces(void) { struct ns_id_req req =3D { .size =3D sizeof(req), .ns_id =3D 0, /* Start from beginning */ .ns_type =3D 0, /* All types */ .user_ns_id =3D 0, /* All user namespaces */ }; uint64_t ids[100]; ssize_t ret; printf("All namespaces in the system:\n"); do { ret =3D listns(&req, ids, 100, 0); if (ret < 0) { perror("listns"); break; } for (ssize_t i =3D 0; i < ret; i++) printf(" Namespace ID: %llu\n", (unsigned long long)ids[i]); /* Continue from last seen ID */ if (ret > 0) req.ns_id =3D ids[ret - 1]; } while (ret =3D=3D 100); /* Buffer was full, more may exist */ } Example 2: List network namespaces only void list_network_namespaces(void) { struct ns_id_req req =3D { .size =3D sizeof(req), .ns_id =3D 0, .ns_type =3D NET_NS, /* Only network namespaces */ .user_ns_id =3D 0, }; uint64_t ids[100]; ssize_t ret; ret =3D listns(&req, ids, 100, 0); if (ret < 0) { perror("listns"); return; } printf("Network namespaces: %zd found\n", ret); for (ssize_t i =3D 0; i < ret; i++) printf(" netns ID: %llu\n", (unsigned long long)ids[i]); } Example 3: List namespaces owned by current user namespace void list_owned_namespaces(void) { struct ns_id_req req =3D { .size =3D sizeof(req), .ns_id =3D 0, .ns_type =3D 0, /* All types */ .user_ns_id =3D LISTNS_CURRENT_USER, /* Current userns */ }; uint64_t ids[100]; ssize_t ret; ret =3D listns(&req, ids, 100, 0); if (ret < 0) { perror("listns"); return; } printf("Namespaces owned by my user namespace: %zd\n", ret); for (ssize_t i =3D 0; i < ret; i++) printf(" ns ID: %llu\n", (unsigned long long)ids[i]); } Example 4: List multiple namespace types void list_network_and_mount_namespaces(void) { struct ns_id_req req =3D { .size =3D sizeof(req), .ns_id =3D 0, .ns_type =3D NET_NS | MNT_NS, /* Network and mount */ .user_ns_id =3D 0, }; uint64_t ids[100]; ssize_t ret; ret =3D listns(&req, ids, 100, 0); printf("Network and mount namespaces: %zd found\n", ret); } Example 5: Pagination through large namespace sets void list_all_with_pagination(void) { struct ns_id_req req =3D { .size =3D sizeof(req), .ns_id =3D 0, .ns_type =3D 0, .user_ns_id =3D 0, }; uint64_t ids[50]; size_t total =3D 0; ssize_t ret; printf("Enumerating all namespaces with pagination:\n"); while (1) { ret =3D listns(&req, ids, 50, 0); if (ret < 0) { perror("listns"); break; } if (ret =3D=3D 0) break; /* No more namespaces */ total +=3D ret; printf(" Batch: %zd namespaces\n", ret); /* Last ID in this batch becomes start of next batch */ req.ns_id =3D ids[ret - 1]; if (ret < 50) break; /* Partial batch =3D end of results */ } printf("Total: %zu namespaces\n", total); } Permission Model listns() respects namespace isolation and capabilities: (1) Global listing (user_ns_id =3D 0): - Requires CAP_SYS_ADMIN in the namespace's owning user namespace - OR the namespace must be in the caller's namespace context (e.g., a namespace the caller is currently using) - User namespaces additionally allow listing if the caller has CAP_SYS_ADMIN in that user namespace itself (2) Owner-filtered listing (user_ns_id !=3D 0): - Requires CAP_SYS_ADMIN in the specified owner user namespace - OR the namespace must be in the caller's namespace context - This allows unprivileged processes to enumerate namespaces they own (3) Visibility: - Only "active" namespaces are listed - A namespace is active if it has a non-zero __ns_ref_active count - This includes namespaces used by running processes, held by open file descriptors, or kept active by bind mounts - Inactive namespaces (kept alive only by internal kernel references) are not visible via listns() Signed-off-by: Christian Brauner --- fs/namespace.c | 1 + fs/nsfs.c | 39 +++++ include/linux/ns_common.h | 5 +- include/linux/syscalls.h | 4 + include/uapi/linux/nsfs.h | 44 +++++ init/version-timestamp.c | 1 + ipc/msgutil.c | 1 + kernel/cgroup/cgroup.c | 1 + kernel/nscommon.c | 3 + kernel/nstree.c | 404 ++++++++++++++++++++++++++++++++++++++++++= +++- kernel/pid.c | 1 + kernel/time/namespace.c | 1 + kernel/user.c | 1 + 13 files changed, 501 insertions(+), 5 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index d460ca79f0e7..980296b0ec86 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5996,6 +5996,7 @@ struct mnt_namespace init_mnt_ns =3D { .mounts =3D RB_ROOT, .poll =3D __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll), .ns.ns_list_node =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_unified_lis= t_node), .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_owner_entry), .ns.ns_owner =3D LIST_HEAD_INIT(init_mnt_ns.ns.ns_owner), }; diff --git a/fs/nsfs.c b/fs/nsfs.c index ba5863ee4150..629139a25d65 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -465,6 +465,45 @@ static int nsfs_encode_fh(struct inode *inode, u32 *fh= , int *max_len, return FILEID_NSFS; } =20 +bool is_current_namespace(struct ns_common *ns) +{ + switch (ns->ns_type) { +#ifdef CONFIG_CGROUPS + case CLONE_NEWCGROUP: + return current_in_namespace(to_cg_ns(ns)); +#endif +#ifdef CONFIG_IPC_NS + case CLONE_NEWIPC: + return current_in_namespace(to_ipc_ns(ns)); +#endif + case CLONE_NEWNS: + return current_in_namespace(to_mnt_ns(ns)); +#ifdef CONFIG_NET_NS + case CLONE_NEWNET: + return current_in_namespace(to_net_ns(ns)); +#endif +#ifdef CONFIG_PID_NS + case CLONE_NEWPID: + return current_in_namespace(to_pid_ns(ns)); +#endif +#ifdef CONFIG_TIME_NS + case CLONE_NEWTIME: + return current_in_namespace(to_time_ns(ns)); +#endif +#ifdef CONFIG_USER_NS + case CLONE_NEWUSER: + return current_in_namespace(to_user_ns(ns)); +#endif +#ifdef CONFIG_UTS_NS + case CLONE_NEWUTS: + return current_in_namespace(to_uts_ns(ns)); +#endif + default: + VFS_WARN_ON_ONCE(true); + return false; + } +} + static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid= *fh, int fh_len, int fh_type) { diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 1afeaa93d319..151d9e594500 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -123,8 +123,10 @@ struct ns_common { struct rb_node ns_tree_node; struct list_head ns_list_node; }; - struct /* namespace ownership list */ { + struct /* namespace ownership rbtree and list */ { + struct rb_root ns_owner_tree; /* rbtree of namespaces owned by this na= mespace */ struct list_head ns_owner; /* list of namespaces owned by this namespa= ce */ + struct rb_node ns_owner_tree_node; /* node in the owner namespace's rb= tree */ struct list_head ns_owner_entry; /* node in the owner namespace's ns_o= wned list */ }; atomic_t __ns_ref_active; /* do not use directly */ @@ -133,6 +135,7 @@ struct ns_common { }; }; =20 +bool is_current_namespace(struct ns_common *ns); int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_= ns_operations *ops, int inum); void __ns_common_free(struct ns_common *ns); =20 diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 66c06fcdfe19..cf84d98964b2 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -77,6 +77,7 @@ struct cachestat_range; struct cachestat; struct statmount; struct mnt_id_req; +struct ns_id_req; struct xattr_args; struct file_attr; =20 @@ -437,6 +438,9 @@ asmlinkage long sys_statmount(const struct mnt_id_req _= _user *req, asmlinkage long sys_listmount(const struct mnt_id_req __user *req, u64 __user *mnt_ids, size_t nr_mnt_ids, unsigned int flags); +asmlinkage long sys_listns(const struct ns_id_req __user *req, + u64 __user *ns_ids, size_t nr_ns_ids, + unsigned int flags); asmlinkage long sys_truncate(const char __user *path, long length); asmlinkage long sys_ftruncate(unsigned int fd, off_t length); #if BITS_PER_LONG =3D=3D 32 diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h index f8bc2aad74d6..a25e38d1c874 100644 --- a/include/uapi/linux/nsfs.h +++ b/include/uapi/linux/nsfs.h @@ -81,4 +81,48 @@ enum init_ns_id { #endif }; =20 +enum ns_type { + TIME_NS =3D (1ULL << 7), /* CLONE_NEWTIME */ + MNT_NS =3D (1ULL << 17), /* CLONE_NEWNS */ + CGROUP_NS =3D (1ULL << 25), /* CLONE_NEWCGROUP */ + UTS_NS =3D (1ULL << 26), /* CLONE_NEWUTS */ + IPC_NS =3D (1ULL << 27), /* CLONE_NEWIPC */ + USER_NS =3D (1ULL << 28), /* CLONE_NEWUSER */ + PID_NS =3D (1ULL << 29), /* CLONE_NEWPID */ + NET_NS =3D (1ULL << 30), /* CLONE_NEWNET */ +}; + +/** + * struct ns_id_req - namespace ID request structure + * @size: size of this structure + * @spare: reserved for future use + * @filter: filter mask + * @ns_id: last namespace id + * @user_ns_id: owning user namespace ID + * + * Structure for passing namespace ID and miscellaneous parameters to + * statns(2) and listns(2). + * + * For statns(2) @param represents the request mask. + * For listns(2) @param represents the last listed mount id (or zero). + */ +struct ns_id_req { + __u32 size; + __u32 spare; + __u64 ns_id; + struct /* listns */ { + __u32 ns_type; + __u32 spare2; + __u64 user_ns_id; + }; +}; + +/* + * Special @user_ns_id value that can be passed to listns() + */ +#define LISTNS_CURRENT_USER 0xffffffffffffffff /* Caller's userns */ + +/* List of all ns_id_req versions. */ +#define NS_ID_REQ_SIZE_VER0 32 /* sizeof first published struct */ + #endif /* __LINUX_NSFS_H */ diff --git a/init/version-timestamp.c b/init/version-timestamp.c index e5c278dabecf..cd6f435d5fde 100644 --- a/init/version-timestamp.c +++ b/init/version-timestamp.c @@ -22,6 +22,7 @@ struct uts_namespace init_uts_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_uts_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_unified_lis= t_node), .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_owner_entry), .ns.ns_owner =3D LIST_HEAD_INIT(init_uts_ns.ns.ns_owner), #ifdef CONFIG_UTS_NS diff --git a/ipc/msgutil.c b/ipc/msgutil.c index ce1de73725c0..3708f325228d 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -32,6 +32,7 @@ struct ipc_namespace init_ipc_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_ipc_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_unified_lis= t_node), .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_owner_entry), .ns.ns_owner =3D LIST_HEAD_INIT(init_ipc_ns.ns.ns_owner), #ifdef CONFIG_IPC_NS diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 41a1fc562ed0..9ab0e7d7b54d 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -258,6 +258,7 @@ struct cgroup_namespace init_cgroup_ns =3D { .root_cset =3D &init_css_set, .ns.ns_type =3D ns_common_type(&init_cgroup_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_unified_= list_node), .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_owner_entry), .ns.ns_owner =3D LIST_HEAD_INIT(init_cgroup_ns.ns.ns_owner), }; diff --git a/kernel/nscommon.c b/kernel/nscommon.c index 0ef2939daf33..bf9a30fa82d6 100644 --- a/kernel/nscommon.c +++ b/kernel/nscommon.c @@ -62,7 +62,10 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, = const struct proc_ns_ope ns->ns_type =3D ns_type; RB_CLEAR_NODE(&ns->ns_tree_node); RB_CLEAR_NODE(&ns->ns_unified_tree_node); + RB_CLEAR_NODE(&ns->ns_owner_tree_node); INIT_LIST_HEAD(&ns->ns_list_node); + INIT_LIST_HEAD(&ns->ns_unified_list_node); + ns->ns_owner_tree =3D RB_ROOT; INIT_LIST_HEAD(&ns->ns_owner); INIT_LIST_HEAD(&ns->ns_owner_entry); =20 diff --git a/kernel/nstree.c b/kernel/nstree.c index 829682bb04a1..62d7571aced4 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -2,11 +2,14 @@ =20 #include #include +#include +#include #include #include =20 __cacheline_aligned_in_smp DEFINE_SEQLOCK(ns_tree_lock); static struct rb_root ns_unified_tree =3D RB_ROOT; /* protected by ns_tree= _lock */ +static LIST_HEAD(ns_unified_list); /* protected by ns_tree_lock */ =20 /** * struct ns_tree - Namespace tree @@ -83,6 +86,13 @@ static inline struct ns_common *node_to_ns_unified(const= struct rb_node *node) return rb_entry(node, struct ns_common, ns_unified_tree_node); } =20 +static inline struct ns_common *node_to_ns_owner(const struct rb_node *nod= e) +{ + if (!node) + return NULL; + return rb_entry(node, struct ns_common, ns_owner_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); @@ -111,6 +121,20 @@ static inline int ns_cmp_unified(struct rb_node *a, co= nst struct rb_node *b) return 0; } =20 +static inline int ns_cmp_owner(struct rb_node *a, const struct rb_node *b) +{ + struct ns_common *ns_a =3D node_to_ns_owner(a); + struct ns_common *ns_b =3D node_to_ns_owner(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; @@ -134,7 +158,13 @@ void __ns_tree_add_raw(struct ns_common *ns, struct ns= _tree *ns_tree) else list_add_rcu(&ns->ns_list_node, &node_to_ns(prev)->ns_list_node); =20 + /* Add to unified tree and list */ rb_find_add_rcu(&ns->ns_unified_tree_node, &ns_unified_tree, ns_cmp_unifi= ed); + prev =3D rb_prev(&ns->ns_unified_tree_node); + if (!prev) + list_add_rcu(&ns->ns_unified_list_node, &ns_unified_list); + else + list_add_rcu(&ns->ns_unified_list_node, &node_to_ns_unified(prev)->ns_un= ified_list_node); =20 if (ops) { struct user_namespace *user_ns; @@ -144,7 +174,16 @@ void __ns_tree_add_raw(struct ns_common *ns, struct ns= _tree *ns_tree) if (user_ns) { struct ns_common *owner =3D &user_ns->ns; VFS_WARN_ON_ONCE(owner->ns_type !=3D CLONE_NEWUSER); - list_add_tail_rcu(&ns->ns_owner_entry, &owner->ns_owner); + + /* Insert into owner's rbtree */ + rb_find_add_rcu(&ns->ns_owner_tree_node, &owner->ns_owner_tree, ns_cmp_= owner); + + /* Insert into owner's list in sorted order */ + prev =3D rb_prev(&ns->ns_owner_tree_node); + if (!prev) + list_add_rcu(&ns->ns_owner_entry, &owner->ns_owner); + else + list_add_rcu(&ns->ns_owner_entry, &node_to_ns_owner(prev)->ns_owner_en= try); } else { /* Only the initial user namespace doesn't have an owner. */ VFS_WARN_ON_ONCE(ns !=3D to_ns_common(&init_user_ns)); @@ -157,16 +196,36 @@ void __ns_tree_add_raw(struct ns_common *ns, struct n= s_tree *ns_tree) =20 void __ns_tree_remove(struct ns_common *ns, struct ns_tree *ns_tree) { + const struct proc_ns_operations *ops =3D ns->ops; + struct user_namespace *user_ns; + 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->ns_type !=3D ns_tree->type); =20 write_seqlock(&ns_tree_lock); rb_erase(&ns->ns_tree_node, &ns_tree->ns_tree); - rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree); - list_bidir_del_rcu(&ns->ns_list_node); RB_CLEAR_NODE(&ns->ns_tree_node); - list_bidir_del_rcu(&ns->ns_owner_entry); + + list_bidir_del_rcu(&ns->ns_list_node); + + rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree); + RB_CLEAR_NODE(&ns->ns_unified_tree_node); + + list_bidir_del_rcu(&ns->ns_unified_list_node); + + /* Remove from owner's rbtree if this namespace has an owner */ + if (ops) { + user_ns =3D ops->owner(ns); + if (user_ns) { + struct ns_common *owner =3D &user_ns->ns; + rb_erase(&ns->ns_owner_tree_node, &owner->ns_owner_tree); + RB_CLEAR_NODE(&ns->ns_owner_tree_node); + } + + list_bidir_del_rcu(&ns->ns_owner_entry); + } + write_sequnlock(&ns_tree_lock); } EXPORT_SYMBOL_GPL(__ns_tree_remove); @@ -312,3 +371,340 @@ u64 __ns_tree_gen_id(struct ns_common *ns, u64 id) ns->ns_id =3D atomic64_inc_return(&namespace_cookie); return ns->ns_id; } + +struct klistns { + u64 *kns_ids; + u32 nr_ns_ids; + u64 last_ns_id; + u64 user_ns_id; + u32 ns_type; + struct user_namespace *user_ns; + struct ns_common *first_ns; +}; + +static void __free_klistns_free(const struct klistns *kls) +{ + if (kls->user_ns_id !=3D LISTNS_CURRENT_USER) + put_user_ns(kls->user_ns); + if (kls->first_ns) + kls->first_ns->ops->put(kls->first_ns); + kvfree(kls->kns_ids); +} + +#define NS_ALL (PID_NS | USER_NS | MNT_NS | UTS_NS | IPC_NS | NET_NS | CGR= OUP_NS | TIME_NS) + +static int copy_ns_id_req(const struct ns_id_req __user *req, + struct ns_id_req *kreq) +{ + int ret; + size_t usize; + + BUILD_BUG_ON(sizeof(struct ns_id_req) !=3D NS_ID_REQ_SIZE_VER0); + + ret =3D get_user(usize, &req->size); + if (ret) + return -EFAULT; + if (unlikely(usize > PAGE_SIZE)) + return -E2BIG; + if (unlikely(usize < NS_ID_REQ_SIZE_VER0)) + return -EINVAL; + memset(kreq, 0, sizeof(*kreq)); + ret =3D copy_struct_from_user(kreq, sizeof(*kreq), req, usize); + if (ret) + return ret; + if (kreq->spare !=3D 0) + return -EINVAL; + if (kreq->ns_type & ~NS_ALL) + return -EOPNOTSUPP; + return 0; +} + +static inline int prepare_klistns(struct klistns *kls, struct ns_id_req *k= req, + size_t nr_ns_ids) +{ + kls->last_ns_id =3D kreq->ns_id; + kls->user_ns_id =3D kreq->user_ns_id; + kls->nr_ns_ids =3D nr_ns_ids; + kls->ns_type =3D kreq->ns_type; + + kls->kns_ids =3D kvmalloc_array(nr_ns_ids, sizeof(*kls->kns_ids), + GFP_KERNEL_ACCOUNT); + if (!kls->kns_ids) + return -ENOMEM; + + return 0; +} + +/* + * Lookup a namespace owned by owner with id >=3D ns_id. + * Returns the namespace with the smallest id that is >=3D ns_id. + */ +static struct ns_common *lookup_ns_owner_at(u64 ns_id, struct ns_common *o= wner) +{ + struct ns_common *ret =3D NULL; + struct rb_node *node; + + VFS_WARN_ON_ONCE(owner->ns_type !=3D CLONE_NEWUSER); + + read_seqlock_excl(&ns_tree_lock); + node =3D owner->ns_owner_tree.rb_node; + + while (node) { + struct ns_common *ns =3D node_to_ns_owner(node); + + if (ns_id <=3D ns->ns_id) { + ret =3D ns; + if (ns_id =3D=3D ns->ns_id) + break; + node =3D node->rb_left; + } else { + node =3D node->rb_right; + } + } + + if (ret && !ns_get(ret)) + ret =3D NULL; + read_sequnlock_excl(&ns_tree_lock); + return ret; +} + +static struct ns_common *lookup_ns_id(u64 mnt_ns_id, int ns_type) +{ + struct ns_common *ns; + + guard(rcu)(); + ns =3D ns_tree_lookup_rcu(mnt_ns_id, ns_type); + if (!ns) + return NULL; + + if (!ns_get(ns)) + return NULL; + + return ns; +} + +static ssize_t do_listns_userns(struct klistns *kls) +{ + u64 *ns_ids =3D kls->kns_ids; + size_t nr_ns_ids =3D kls->nr_ns_ids; + struct ns_common *ns, *first_ns =3D NULL; + const struct list_head *head; + bool userns_capable; + ssize_t ret; + + VFS_WARN_ON_ONCE(!kls->user_ns_id); + + if (kls->user_ns_id =3D=3D LISTNS_CURRENT_USER) + ns =3D to_ns_common(current_user_ns()); + else if (kls->user_ns_id) + ns =3D lookup_ns_id(kls->user_ns_id, CLONE_NEWUSER); + if (!ns) + return -EINVAL; + kls->user_ns =3D to_user_ns(ns); + + /* + * Use the rbtree to find the first namespace we care about and + * then use it's list entry to iterate from there. + */ + if (kls->last_ns_id) { + kls->first_ns =3D lookup_ns_owner_at(kls->last_ns_id + 1, ns); + if (!kls->first_ns) + return -ENOENT; + first_ns =3D kls->first_ns; + } + + ret =3D 0; + head =3D &to_ns_common(kls->user_ns)->ns_owner; + userns_capable =3D ns_capable_noaudit(kls->user_ns, CAP_SYS_ADMIN); + guard(rcu)(); + if (!first_ns) + first_ns =3D list_entry_rcu(head->next, typeof(*ns), ns_owner_entry); + for (ns =3D first_ns; &ns->ns_owner_entry !=3D head && nr_ns_ids; + ns =3D list_entry_rcu(ns->ns_owner_entry.next, typeof(*ns), ns_owner= _entry)) { + if (kls->ns_type && !(kls->ns_type & ns->ns_type)) + continue; + if (!__ns_ref_active_read(ns)) + continue; + if (!userns_capable && !is_current_namespace(ns) && + ((ns->ns_type !=3D CLONE_NEWUSER) || + !ns_capable_noaudit(to_user_ns(ns), CAP_SYS_ADMIN))) + continue; + *ns_ids =3D ns->ns_id; + ns_ids++; + nr_ns_ids--; + ret++; + } + + return ret; +} + +/* + * Lookup a namespace with id >=3D ns_id in either the unified tree or a t= ype-specific tree. + * Returns the namespace with the smallest id that is >=3D ns_id. + */ +static struct ns_common *lookup_ns_id_at(u64 ns_id, int ns_type) +{ + struct ns_common *ret =3D NULL; + struct ns_tree *ns_tree =3D NULL; + struct rb_node *node; + + if (ns_type) { + ns_tree =3D ns_tree_from_type(ns_type); + if (!ns_tree) + return NULL; + } + + read_seqlock_excl(&ns_tree_lock); + if (ns_tree) + node =3D ns_tree->ns_tree.rb_node; + else + node =3D ns_unified_tree.rb_node; + + while (node) { + struct ns_common *ns; + + if (ns_type) + ns =3D node_to_ns(node); + else + ns =3D node_to_ns_unified(node); + + if (ns_id <=3D ns->ns_id) { + if (ns_type) + ret =3D node_to_ns(node); + else + ret =3D node_to_ns_unified(node); + if (ns_id =3D=3D ns->ns_id) + break; + node =3D node->rb_left; + } else { + node =3D node->rb_right; + } + } + + if (ret && !ns_get(ret)) + ret =3D NULL; + read_sequnlock_excl(&ns_tree_lock); + return ret; +} + +static inline struct ns_common *first_ns_common(const struct list_head *he= ad, + struct ns_tree *ns_tree) +{ + if (ns_tree) + return list_entry_rcu(head->next, struct ns_common, ns_list_node); + return list_entry_rcu(head->next, struct ns_common, ns_unified_list_node); +} + +static inline struct ns_common *next_ns_common(struct ns_common *ns, + struct ns_tree *ns_tree) +{ + if (ns_tree) + return list_entry_rcu(ns->ns_list_node.next, struct ns_common, ns_list_n= ode); + return list_entry_rcu(ns->ns_unified_list_node.next, struct ns_common, ns= _unified_list_node); +} + +static inline bool ns_common_is_head(struct ns_common *ns, + const struct list_head *head, + struct ns_tree *ns_tree) +{ + if (ns_tree) + return &ns->ns_list_node =3D=3D head; + return &ns->ns_unified_list_node =3D=3D head; +} + +static ssize_t do_listns(struct klistns *kls) +{ + u64 *ns_ids =3D kls->kns_ids; + size_t nr_ns_ids =3D kls->nr_ns_ids; + struct ns_common *ns, *first_ns =3D NULL; + struct ns_tree *ns_tree =3D NULL; + const struct list_head *head; + struct user_namespace *user_ns; + ssize_t ret; + + if (hweight32(kls->ns_type) =3D=3D 1) { + ns_tree =3D ns_tree_from_type(kls->ns_type); + if (!ns_tree) + return -EINVAL; + } + + if (kls->last_ns_id) { + kls->first_ns =3D lookup_ns_id_at(kls->last_ns_id + 1, 0); + if (!kls->first_ns) + return -ENOENT; + first_ns =3D kls->first_ns; + } + + ret =3D 0; + if (ns_tree) + head =3D &ns_tree->ns_list; + else + head =3D &ns_unified_list; + + guard(rcu)(); + if (!first_ns) + first_ns =3D first_ns_common(head, ns_tree); + + for (ns =3D first_ns; !ns_common_is_head(ns, head, ns_tree) && nr_ns_ids; + ns =3D next_ns_common(ns, ns_tree)) { + if (kls->ns_type && !(kls->ns_type & ns->ns_type)) + continue; + if (!__ns_ref_active_read(ns)) + continue; + /* Check permissions */ + if (!ns->ops) + user_ns =3D NULL; + else + user_ns =3D ns->ops->owner(ns); + if (!user_ns) + user_ns =3D &init_user_ns; + if (!ns_capable_noaudit(user_ns, CAP_SYS_ADMIN) && + !is_current_namespace(ns) && + ((ns->ns_type !=3D CLONE_NEWUSER) || + !ns_capable_noaudit(to_user_ns(ns), CAP_SYS_ADMIN))) + continue; + *ns_ids++ =3D ns->ns_id; + nr_ns_ids--; + ret++; + } + + return ret; +} + +SYSCALL_DEFINE4(listns, const struct ns_id_req __user *, req, + u64 __user *, ns_ids, size_t, nr_ns_ids, unsigned int, flags) +{ + struct klistns klns __free(klistns_free) =3D {}; + const size_t maxcount =3D 1000000; + struct ns_id_req kreq; + ssize_t ret; + + if (flags) + return -EINVAL; + + if (unlikely(nr_ns_ids > maxcount)) + return -EOVERFLOW; + + if (!access_ok(ns_ids, nr_ns_ids * sizeof(*ns_ids))) + return -EFAULT; + + ret =3D copy_ns_id_req(req, &kreq); + if (ret) + return ret; + + ret =3D prepare_klistns(&klns, &kreq, nr_ns_ids); + if (ret) + return ret; + + if (kreq.user_ns_id) + ret =3D do_listns_userns(&klns); + else + ret =3D do_listns(&klns); + if (ret <=3D 0) + return ret; + + if (copy_to_user(ns_ids, klns.kns_ids, ret * sizeof(*ns_ids))) + return -EFAULT; + + return ret; +} diff --git a/kernel/pid.c b/kernel/pid.c index f82dab348540..a1bfb2924476 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -80,6 +80,7 @@ struct pid_namespace init_pid_ns =3D { .user_ns =3D &init_user_ns, .ns.inum =3D ns_init_inum(&init_pid_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_unified_lis= t_node), .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_owner_entry), .ns.ns_owner =3D LIST_HEAD_INIT(init_pid_ns.ns.ns_owner), #ifdef CONFIG_PID_NS diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 15cb74267c75..acbeec049263 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -489,6 +489,7 @@ struct time_namespace init_time_ns =3D { .ns.ns_owner =3D LIST_HEAD_INIT(init_time_ns.ns.ns_owner), .frozen_offsets =3D true, .ns.ns_list_node =3D LIST_HEAD_INIT(init_time_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_time_ns.ns.ns_unified_li= st_node), }; =20 void __init time_ns_init(void) diff --git a/kernel/user.c b/kernel/user.c index e392768ccd44..68fe16617d38 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -72,6 +72,7 @@ struct user_namespace init_user_ns =3D { .group =3D GLOBAL_ROOT_GID, .ns.inum =3D ns_init_inum(&init_user_ns), .ns.ns_list_node =3D LIST_HEAD_INIT(init_user_ns.ns.ns_list_node), + .ns.ns_unified_list_node =3D LIST_HEAD_INIT(init_user_ns.ns.ns_unified_li= st_node), .ns.ns_owner_entry =3D LIST_HEAD_INIT(init_user_ns.ns.ns_owner_entry), .ns.ns_owner =3D LIST_HEAD_INIT(init_user_ns.ns.ns_owner), #ifdef CONFIG_USER_NS --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 4ECAB32E748; Tue, 21 Oct 2025 11:45:15 +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=1761047115; cv=none; b=aI6TyNSYbiK3FhYuNHPkA9gShuuavBFV5TjqsRrWJ01X0QofxuGVt4L7/C44ihiNQWV+7jSXmL8XujNNA8vCMU+3FjJ1J6iA/rlmHxKUbnGu2f02lv75SlMuEveYONK6nA77bwOKPzfNEF94EL/LvHXhh2hByxa7hnfbbLK2WaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047115; c=relaxed/simple; bh=XpmxvPjEDm5RoykVT0IX3VWa5Fn08+MBXhfC/U2Zx18=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PgLLK+lQ76dSZk2G9mF70vLpZxiTVyMwkF6HrAMr2mO0Qh4FgAx1eCwSNyu2lmyjMUlkT5nVYntUWPV+TSRfgLeZyVpRuTzmBfsEvWSO8eWtZOLj2ttknb5d3iLlW3p3OYygwbYDw0yVe7tUNuDLbK3dyd05lqumbAK6RwXvdlc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MESou/QK; 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="MESou/QK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E08CFC4CEFF; Tue, 21 Oct 2025 11:45:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047115; bh=XpmxvPjEDm5RoykVT0IX3VWa5Fn08+MBXhfC/U2Zx18=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MESou/QKrNcrguckZGTkihXT4Ew/vIocj9B4C1CKUO3UU3FBIb/4uVzkRycf6wDgH /RaJB0u9CDnUd9ptGaFzoftX32dJp3pnPcgcotSn9jtlluj6SE8s1PthoUjGszJmnD wXI298BGK4HCetDindY0/cIASKNexYRT5Twb34ZC6PIGXE5P9Ky8syC9IGcvxU+CL8 NRlHgD0DtV7O8SbNImqaYxM10ZATsl79gESig2X9PHFXy1fdrXYYbFuGTwFBGrhuln BDVZU/io2DFrS0kKNCUp4elRyLtwhYi+mSDWtyhugOZx7fIEVDVLNJK82JCVBRq8ud zraEZIqei8hmw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:22 +0200 Subject: [PATCH RFC DRAFT 16/50] arch: hookup listns() system call 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: <20251021-work-namespace-nstree-listns-v1-16-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=8897; i=brauner@kernel.org; h=from:subject:message-id; bh=XpmxvPjEDm5RoykVT0IX3VWa5Fn08+MBXhfC/U2Zx18=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3yrI/ZzFuOzhvjAhjlT5XNWMk9dIlQweWnLlGcbT swRmWdb1lHKwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjCRGbMY/rvt1/i6Z9/0Sucb Vf98bQND9Th1DFJW2DzO0N4oENBnPouRoYnpu0PNrelcvCs3K29PD953LEhd7WBV4QlrLX8LNnc XXgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add the listns() system call to all architectures. Signed-off-by: Christian Brauner --- arch/alpha/kernel/syscalls/syscall.tbl | 1 + arch/arm/tools/syscall.tbl | 1 + arch/arm64/tools/syscall_32.tbl | 1 + arch/m68k/kernel/syscalls/syscall.tbl | 1 + arch/microblaze/kernel/syscalls/syscall.tbl | 1 + arch/mips/kernel/syscalls/syscall_n32.tbl | 1 + arch/mips/kernel/syscalls/syscall_n64.tbl | 1 + arch/mips/kernel/syscalls/syscall_o32.tbl | 1 + arch/parisc/kernel/syscalls/syscall.tbl | 1 + arch/powerpc/kernel/syscalls/syscall.tbl | 1 + arch/s390/kernel/syscalls/syscall.tbl | 1 + arch/sh/kernel/syscalls/syscall.tbl | 1 + arch/sparc/kernel/syscalls/syscall.tbl | 1 + arch/x86/entry/syscalls/syscall_32.tbl | 1 + arch/x86/entry/syscalls/syscall_64.tbl | 1 + arch/xtensa/kernel/syscalls/syscall.tbl | 1 + include/uapi/asm-generic/unistd.h | 4 +++- scripts/syscall.tbl | 1 + 18 files changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/sys= calls/syscall.tbl index 16dca28ebf17..3fed97478058 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -509,3 +509,4 @@ 577 common open_tree_attr sys_open_tree_attr 578 common file_getattr sys_file_getattr 579 common file_setattr sys_file_setattr +580 common listns sys_listns diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index b07e699aaa3c..fd09afae72a2 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -484,3 +484,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/arm64/tools/syscall_32.tbl b/arch/arm64/tools/syscall_32.= tbl index 8d9088bc577d..8cdfe5d4dac9 100644 --- a/arch/arm64/tools/syscall_32.tbl +++ b/arch/arm64/tools/syscall_32.tbl @@ -481,3 +481,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/sysca= lls/syscall.tbl index f41d38dfbf13..871a5d67bf41 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -469,3 +469,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/= kernel/syscalls/syscall.tbl index 580af574fe73..022fc85d94b3 100644 --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl @@ -475,3 +475,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/s= yscalls/syscall_n32.tbl index d824ffe9a014..8cedc83c3266 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -408,3 +408,4 @@ 467 n32 open_tree_attr sys_open_tree_attr 468 n32 file_getattr sys_file_getattr 469 n32 file_setattr sys_file_setattr +470 n32 listns sys_listns diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/s= yscalls/syscall_n64.tbl index 7a7049c2c307..9b92bddf06b5 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -384,3 +384,4 @@ 467 n64 open_tree_attr sys_open_tree_attr 468 n64 file_getattr sys_file_getattr 469 n64 file_setattr sys_file_setattr +470 n64 listns sys_listns diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/s= yscalls/syscall_o32.tbl index d330274f0601..f810b8a55716 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -457,3 +457,4 @@ 467 o32 open_tree_attr sys_open_tree_attr 468 o32 file_getattr sys_file_getattr 469 o32 file_setattr sys_file_setattr +470 o32 listns sys_listns diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/s= yscalls/syscall.tbl index 88a788a7b18d..39bdacaa530b 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -468,3 +468,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel= /syscalls/syscall.tbl index b453e80dfc00..ec4458cdb97b 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -560,3 +560,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/sysca= lls/syscall.tbl index 8a6744d658db..5863787ab036 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -472,3 +472,4 @@ 467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr sys_file_setattr +470 common listns sys_listns sys_listns diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/= syscall.tbl index 5e9c9eff5539..969c11325ade 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -473,3 +473,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/sys= calls/syscall.tbl index ebb7d06d1044..39aa26b6a50b 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -515,3 +515,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscal= ls/syscall_32.tbl index 4877e16da69a..b3b2658cb8d1 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -475,3 +475,4 @@ 467 i386 open_tree_attr sys_open_tree_attr 468 i386 file_getattr sys_file_getattr 469 i386 file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscal= ls/syscall_64.tbl index ced2a1deecd7..8a4ac4841be6 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -394,6 +394,7 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns =20 # # Due to a historical design error, certain syscalls are numbered differen= tly diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/s= yscalls/syscall.tbl index 374e4cb788d8..438a3b170402 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -440,3 +440,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/u= nistd.h index 04e0077fb4c9..942370b3f5d2 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -857,9 +857,11 @@ __SYSCALL(__NR_open_tree_attr, sys_open_tree_attr) __SYSCALL(__NR_file_getattr, sys_file_getattr) #define __NR_file_setattr 469 __SYSCALL(__NR_file_setattr, sys_file_setattr) +#define __NR_listns 470 +__SYSCALL(__NR_listns, sys_listns) =20 #undef __NR_syscalls -#define __NR_syscalls 470 +#define __NR_syscalls 471 =20 /* * 32 bit systems traditionally used different diff --git a/scripts/syscall.tbl b/scripts/syscall.tbl index d1ae5e92c615..e74868be513c 100644 --- a/scripts/syscall.tbl +++ b/scripts/syscall.tbl @@ -410,3 +410,4 @@ 467 common open_tree_attr sys_open_tree_attr 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr +470 common listns sys_listns --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 1F82432E745; Tue, 21 Oct 2025 11:45:20 +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=1761047120; cv=none; b=Tkg5G7wKOnWS+W7KTGBZpuikUA8yNYidIUenzXHFa5L8mG5I1fViXadiZrMhJZrLsFQLWWz/AfKXHSfE6wEKf+rLrxoOKvzDbjKC/AKNoqWQcwGWjGFNorh3IthJTYLAT1j/fQYfTLXjO1Yxo0KtJPxh1TzsiCXp8526x6BNC/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047120; c=relaxed/simple; bh=1Vbdfejrzu8I2m1UigJuDF0ynX7SsD3EwMJY3zP1DiU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AaRWPlTxUE0kzyEb7sui3+Lv8IMQCHIDmbftaPVXKrxfqeUo31frx87cfqppdtZEL5PQAfVDb/ylcEBFiAIrbJZtUvs9b+9tpCx+sx7f80XVDLPFytBG1nbGBFuh4O20tFfbThrjR4dwkyvgwUt1pnLxtUddQYK38eUS+Frlqzw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nIysmLqK; 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="nIysmLqK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6788EC4CEF1; Tue, 21 Oct 2025 11:45:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047120; bh=1Vbdfejrzu8I2m1UigJuDF0ynX7SsD3EwMJY3zP1DiU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nIysmLqKgliZzQicmhaxkog8T0k7NA8a9yJ5wF/TPWd4nGEfUWtmlLzbTD++crrkq dd4kiKLhWttUe2y6tU/CI7/c7qlI9HBdCpg0BaJEXjgKVJ6LZDNwGZ2xY+tEHK6WMl 4Sn8YuyCXLDUfTg/VQ4OQ6/tsOqROPYLt+JHgJMOhMep6InXfWIOo9xPgVL5MCnhff /erff4xatRs/k1rVmQ4q0d0EdEDuRBO/1JN6JkuHpcrSeFldXR1LqMDdUjLp7mlZtl ufRkgKqqHUxKb0FjviggKDrg5owBltQgUd0cEdG1jB/4oXRuS0hVKUxcgemx42SBwT 8ngaYtv29ie7A== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:23 +0200 Subject: [PATCH RFC DRAFT 17/50] nsfs: update tools 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: <20251021-work-namespace-nstree-listns-v1-17-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2616; i=brauner@kernel.org; h=from:subject:message-id; bh=1Vbdfejrzu8I2m1UigJuDF0ynX7SsD3EwMJY3zP1DiU=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3wbaXeCnaHf/JhtqqwyX1vJArdWtdgl2ycdzGf+d 69lns3ujlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgImEP2RkWKMhMc9Ywe3ttPif UotOGctMW7zmWbfevsuxZ/R2XI/fVc/IcHDfmpkLFiWJb3pSkH9IlSvi71qntfJs3tznq38V3+x 7xwkA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Ensure all the new uapi bits are visible for the selftests. Signed-off-by: Christian Brauner --- tools/include/uapi/linux/nsfs.h | 70 +++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 70 insertions(+) diff --git a/tools/include/uapi/linux/nsfs.h b/tools/include/uapi/linux/nsf= s.h index 33c9b578b3b2..a25e38d1c874 100644 --- a/tools/include/uapi/linux/nsfs.h +++ b/tools/include/uapi/linux/nsfs.h @@ -53,6 +53,76 @@ enum init_ns_ino { TIME_NS_INIT_INO =3D 0xEFFFFFFAU, NET_NS_INIT_INO =3D 0xEFFFFFF9U, MNT_NS_INIT_INO =3D 0xEFFFFFF8U, +#ifdef __KERNEL__ + MNT_NS_ANON_INO =3D 0xEFFFFFF7U, +#endif }; =20 +struct nsfs_file_handle { + __u64 ns_id; + __u32 ns_type; + __u32 ns_inum; +}; + +#define NSFS_FILE_HANDLE_SIZE_VER0 16 /* sizeof first published struct */ +#define NSFS_FILE_HANDLE_SIZE_LATEST sizeof(struct nsfs_file_handle) /* si= zeof latest published struct */ + +enum init_ns_id { + IPC_NS_INIT_ID =3D 1ULL, + UTS_NS_INIT_ID =3D 2ULL, + USER_NS_INIT_ID =3D 3ULL, + PID_NS_INIT_ID =3D 4ULL, + CGROUP_NS_INIT_ID =3D 5ULL, + TIME_NS_INIT_ID =3D 6ULL, + NET_NS_INIT_ID =3D 7ULL, + MNT_NS_INIT_ID =3D 8ULL, +#ifdef __KERNEL__ + NS_LAST_INIT_ID =3D MNT_NS_INIT_ID, +#endif +}; + +enum ns_type { + TIME_NS =3D (1ULL << 7), /* CLONE_NEWTIME */ + MNT_NS =3D (1ULL << 17), /* CLONE_NEWNS */ + CGROUP_NS =3D (1ULL << 25), /* CLONE_NEWCGROUP */ + UTS_NS =3D (1ULL << 26), /* CLONE_NEWUTS */ + IPC_NS =3D (1ULL << 27), /* CLONE_NEWIPC */ + USER_NS =3D (1ULL << 28), /* CLONE_NEWUSER */ + PID_NS =3D (1ULL << 29), /* CLONE_NEWPID */ + NET_NS =3D (1ULL << 30), /* CLONE_NEWNET */ +}; + +/** + * struct ns_id_req - namespace ID request structure + * @size: size of this structure + * @spare: reserved for future use + * @filter: filter mask + * @ns_id: last namespace id + * @user_ns_id: owning user namespace ID + * + * Structure for passing namespace ID and miscellaneous parameters to + * statns(2) and listns(2). + * + * For statns(2) @param represents the request mask. + * For listns(2) @param represents the last listed mount id (or zero). + */ +struct ns_id_req { + __u32 size; + __u32 spare; + __u64 ns_id; + struct /* listns */ { + __u32 ns_type; + __u32 spare2; + __u64 user_ns_id; + }; +}; + +/* + * Special @user_ns_id value that can be passed to listns() + */ +#define LISTNS_CURRENT_USER 0xffffffffffffffff /* Caller's userns */ + +/* List of all ns_id_req versions. */ +#define NS_ID_REQ_SIZE_VER0 32 /* sizeof first published struct */ + #endif /* __LINUX_NSFS_H */ --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 5250832ED49; Tue, 21 Oct 2025 11:45:26 +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=1761047126; cv=none; b=KDxsDeVuLgoGsmf2E2fkEaMOTjDGNorm7kIubfGZPn0CUBp14Kpc86THy9z3aaXP2oBgs8xlJkGTb7pLpg2ycFYT+l7e87UPp8QvFcDSZL8saZzteClcF8wf8vDFPVir94UM2HxujrGHxc9598kJGmnamUOgMIJlcuaCmixFAK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047126; c=relaxed/simple; bh=5c8S8VpHc/7sZMeT1/SbhEW34RvFd3Tre08SPwP5pEQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Yy8ZLJ4TujYZIs+lTbkx3KXHTdsDp3FaI2sftWdgwfhogl9rzZIHGA+aADq/YK4YvDwtXkZME1sPoS3idDmtIwRsOTUS9awAZeTbbnwfwutIZs6rfeI34/TUaFUkQU8bgYvZsMz6jnlW6nvI3GtumXFhTnxGITVxo1qS9uDNsXM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kCr65ean; 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="kCr65ean" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6CFA8C4CEF1; Tue, 21 Oct 2025 11:45:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047126; bh=5c8S8VpHc/7sZMeT1/SbhEW34RvFd3Tre08SPwP5pEQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kCr65eanvMnYJZba2Kgc4XWQmNq4LGa8p0PTDJ7XNwDA3M4G3rlJiPdrX02Bl3nHb bZU1poX6N8vtTsAp+WNmwd2Q4YvLmo7eWBJJKc4QAv4byevGaxDEdyW/VYjfn+J83y wxLAqKQJ5hG9tB7gEQhS692ij8yVUolecm4yA2w/XLjpiDBqn7opi6fvDwmeVmzbG2 xoxeT0w7lXI/EU3xnIMKHLDd/FL3Ho6qq/hyjf+zKP+gA/jcEFG16NdvBB/PErHIj3 EcLy2VtNRVemM2+R/xRGoWsMhljHCQykdswfH+0rfKua7O70L8cB2DeuBchE4e+bIW MWRbPVkReHfqw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:24 +0200 Subject: [PATCH RFC DRAFT 18/50] selftests/filesystems: remove CLONE_NEWPIDNS from setup_userns() helper 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: <20251021-work-namespace-nstree-listns-v1-18-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=852; i=brauner@kernel.org; h=from:subject:message-id; bh=5c8S8VpHc/7sZMeT1/SbhEW34RvFd3Tre08SPwP5pEQ=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3w7v1koKPPS3VnmJlGnFoqlGj8pnMJrc+B2ZNxDi xtsUqJJHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABO55MvwvzQ6987ivYJrTCR3 Sbk9kPrSvfX4khNXvViCclySUqeI6DEynJr/JEWpf6ODTHyTx65AhXPh3FLnTyYvv1fWX8ZvvOw UCwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 This is effectively unused and doesn't really server any purpose after having reviewed all of the tests that rely on it. Signed-off-by: Christian Brauner --- tools/testing/selftests/filesystems/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/filesystems/utils.c b/tools/testing/se= lftests/filesystems/utils.c index c43a69dffd83..a0c64f415a7f 100644 --- a/tools/testing/selftests/filesystems/utils.c +++ b/tools/testing/selftests/filesystems/utils.c @@ -487,7 +487,7 @@ int setup_userns(void) uid_t uid =3D getuid(); gid_t gid =3D getgid(); =20 - ret =3D unshare(CLONE_NEWNS|CLONE_NEWUSER|CLONE_NEWPID); + ret =3D unshare(CLONE_NEWNS|CLONE_NEWUSER); if (ret) { ksft_exit_fail_msg("unsharing mountns and userns: %s\n", strerror(errno)); --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 09E1533343C; Tue, 21 Oct 2025 11:45:31 +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=1761047132; cv=none; b=DJDuNvqUIW6PT9XZ1/9SFI1Q8BgUlLv8/cfNLTzaE0bTEzUL7P80dnSoKZrg1IQbUAuWdoxzZJENOXbATY9WeoNchySw+IBuIOwYwgULRR39PewDErbHXGadS/IXN1Cs1nmNxL26gEk/CyR702lmKcDSxXFsg0+u6P3uRmP75WQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047132; c=relaxed/simple; bh=zTxekEdjlVJZprVoI/00FXYGRRSOiQasmJAHzIPasqQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OCJ42dUCbbbXU51sE4kd00o6MwgGzzyEf550kX5rGBwoOTRSJZLZHs/4jdDNPkeOWRoXPM2c39QG2USW0Tyq6H4yELFyebnXujPWM2/b/rhuhLjJ51ubud1EeePiXKAq93RqBVru5Urfnh6MtZKqE+z4QWgvTbxZGOkXF9YBJcs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mQ8Mx/sY; 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="mQ8Mx/sY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A9DDAC4CEF1; Tue, 21 Oct 2025 11:45:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047131; bh=zTxekEdjlVJZprVoI/00FXYGRRSOiQasmJAHzIPasqQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mQ8Mx/sY+y/7NHkRcoGq+SQ6MXsnhhPoig0NxkqLdGEa2Xnktd5KVIgWHxNgrNdMm mj3ktizPR6nMI6PJmAvATb+21q7mdAQyzpV1WKqWYys4UMjB0bUGXzDTXP0/E0fbG9 d8t75GsEybF9284m7fkjn//keUsm7e+uZ4Mk1xMqhw3ftFTaNOZwZHENP5r0O/imKN XwxBPpUz4T9p9y/6InRZLOfHZXByiRErzMYdji9FdkB5EBGd7hsW0QzI4Pl0uU0m9l SmgROzbxUB4mcVaHC/12D1Gsi3o4EYlCsnpw1RGpXhA36mnGOmPoxdPEQerB4HFvb2 qAW/mAgndyJ3A== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:25 +0200 Subject: [PATCH RFC DRAFT 19/50] selftests/namespaces: first active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-19-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3703; i=brauner@kernel.org; h=from:subject:message-id; bh=zTxekEdjlVJZprVoI/00FXYGRRSOiQasmJAHzIPasqQ=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y76b9H6M1P3z2/vpCcEXH5zlMWu/7e217HxNg6V 38MfXt7TkcpC4MYF4OsmCKLQ7tJuNxynorNRpkaMHNYmUCGMHBxCsBE5hYw/NOp6f9880xaFKdg 6b1HGyetrnz3092h82Wo5uasDxfdP4Yx/BUwjFe+VLTkpGVXFUvibJE27iVTl39xzNG+t/Cllgq TMgsA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that initial namespaces can be reopened via file handle. Initial namespaces should always have a ref count of one from boot. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/.gitignore | 1 + tools/testing/selftests/namespaces/Makefile | 5 +- .../selftests/namespaces/ns_active_ref_test.c | 74 ++++++++++++++++++= ++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/namespaces/.gitignore b/tools/testing/= selftests/namespaces/.gitignore index ccfb40837a73..100cc5bfef04 100644 --- a/tools/testing/selftests/namespaces/.gitignore +++ b/tools/testing/selftests/namespaces/.gitignore @@ -1,3 +1,4 @@ nsid_test file_handle_test init_ino_test +ns_active_ref_test diff --git a/tools/testing/selftests/namespaces/Makefile b/tools/testing/se= lftests/namespaces/Makefile index 5fe4b3dc07d3..5cea938cdde8 100644 --- a/tools/testing/selftests/namespaces/Makefile +++ b/tools/testing/selftests/namespaces/Makefile @@ -1,7 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only CFLAGS +=3D -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) +LDLIBS +=3D -lcap =20 -TEST_GEN_PROGS :=3D nsid_test file_handle_test init_ino_test +TEST_GEN_PROGS :=3D nsid_test file_handle_test init_ino_test ns_active_ref= _test =20 include ../lib.mk =20 +$(OUTPUT)/ns_active_ref_test: ../filesystems/utils.c + diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c new file mode 100644 index 000000000000..21514a537b26 --- /dev/null +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../kselftest_harness.h" +#include "../filesystems/utils.h" + +#ifndef FD_NSFS_ROOT +#define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */ +#endif + +/* + * Test that initial namespaces can be reopened via file handle. + * Initial namespaces should have active ref count of 1 from boot. + */ +TEST(init_ns_always_active) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd1, fd2; + struct stat st1, st2; + + handle =3D malloc(sizeof(*handle) + MAX_HANDLE_SZ); + ASSERT_NE(handle, NULL); + + /* Open initial network namespace */ + fd1 =3D open("/proc/1/ns/net", O_RDONLY); + ASSERT_GE(fd1, 0); + + /* Get file handle for initial namespace */ + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(fd1, "", handle, &mount_id, AT_EMPTY_PATH); + if (ret < 0 && errno =3D=3D EOPNOTSUPP) { + SKIP(free(handle); close(fd1); + return, "nsfs doesn't support file handles"); + } + ASSERT_EQ(ret, 0); + + /* Close the namespace fd */ + close(fd1); + + /* Try to reopen via file handle - should succeed since init ns is always= active */ + fd2 =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd2 < 0 && (errno =3D=3D EINVAL || errno =3D=3D EOPNOTSUPP)) { + SKIP(free(handle); + return, "open_by_handle_at with FD_NSFS_ROOT not supported"); + } + ASSERT_GE(fd2, 0); + + /* Verify we opened the same namespace */ + fd1 =3D open("/proc/1/ns/net", O_RDONLY); + ASSERT_GE(fd1, 0); + ASSERT_EQ(fstat(fd1, &st1), 0); + ASSERT_EQ(fstat(fd2, &st2), 0); + ASSERT_EQ(st1.st_ino, st2.st_ino); + + close(fd1); + close(fd2); + free(handle); +} + +TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 578E632ED59; Tue, 21 Oct 2025 11:45:36 +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=1761047137; cv=none; b=erVfISP6hVo64HVLAcTBLIbE6+rw3QSfUtVHl25nr+j9pqJaF2zoXbnkei+FUZNN9VA99piJdxeSxkQQu5WRMFzG8Yz21umcYBzB130oqik6Nr6J0MR/Zsrsbg54ByFOBbPfH89Yk8CSgWhJW4AUAOB7h7TJapzjpsidG6Pnm/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047137; c=relaxed/simple; bh=Pa0j7tNfgc1/Tkfnlhd7s6hsezXzZgIe91NhoiJaauI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cHT04vt8xFqu8bTOWGyR7nTXhmbL4N05j/9NCfKL5d8C29c/8WM5quxrKgHQPMORiX6QGOWVEjrz82M6r7q68yosOnmlhdWrRrhViBq2MG959KyXNow/ekzDyKo5aw2JOVEq+EHGDE0TqJPBnP8++fNCgbK9TTm/Zn7prpdKETs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fM8OS4bF; 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="fM8OS4bF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05813C4CEFF; Tue, 21 Oct 2025 11:45:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047136; bh=Pa0j7tNfgc1/Tkfnlhd7s6hsezXzZgIe91NhoiJaauI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fM8OS4bFd7iN4dJ5dDNdN8cYIXeB0NyZIo1GxTl1QuZ40qq3mvQqbwGx+CBZDlNHL /oQcLQKm5mFtPls9m/8c5UaiWRu8O9cCeeqkXUzxXqsKWFR6IggtogiJ/cNTfG4k8u Gx/LNMXWPLc1Cd8J/SXuMrJqfEkLykEV69NrPNcFPzLlxvoSY78Wsg62CIyrNmQkmn v73NiVCqpJjL9PkQXrkMhaI+NQfJkXXwxW9NorBzyzME7wSD4ttVpMshyQOqWazeLz wwqq3K5xLbj46MYxk5IjhVJFvoImsC0dGN4wfmdn1VB+5eeJUwCAJkgIuJtZV8ey7r TT4KrETKeFc5w== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:26 +0200 Subject: [PATCH RFC DRAFT 20/50] selftests/namespaces: second active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-20-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2999; i=brauner@kernel.org; h=from:subject:message-id; bh=Pa0j7tNfgc1/Tkfnlhd7s6hsezXzZgIe91NhoiJaauI=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zLZyIdtygqSnySJotVXVfUi5j9e/uD5lUceRf43 z9XLXFpRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwERMfjAyPNX4eIDRmunF4Yne /Md7Ytf7i4i6WK6azOSl/MT54WLpnwx/hS/955V4vNo5/d2ujLQ5X3zY1GY89L356TOb0AvlA5+ yuQE= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test namespace lifecycle: create a namespace in a child process, get a file handle while it's active, then try to reopen after the process exits (namespace becomes inactive). Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 89 ++++++++++++++++++= ++++ 1 file changed, 89 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 21514a537b26..f628b4a4a927 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -71,4 +71,93 @@ TEST(init_ns_always_active) free(handle); } =20 +/* + * Test namespace lifecycle: create a namespace in a child process, + * get a file handle while it's active, then try to reopen after + * the process exits (namespace becomes inactive). + */ +TEST(ns_inactive_after_exit) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int pipefd[2]; + pid_t pid; + int status; + char buf[sizeof(*handle) + MAX_HANDLE_SZ]; + + /* Create pipe for passing file handle from child */ + 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 < 0) { + close(pipefd[1]); + exit(1); + } + + /* Open our new namespace */ + fd =3D open("/proc/self/ns/net", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get file handle for the namespace */ + handle =3D (struct file_handle *)buf; + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(fd, "", handle, &mount_id, AT_EMPTY_PATH); + close(fd); + + if (ret < 0) { + close(pipefd[1]); + exit(1); + } + + /* Send handle to parent */ + write(pipefd[1], buf, sizeof(*handle) + handle->handle_bytes); + close(pipefd[1]); + + /* Exit - namespace should become inactive */ + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + /* Read file handle from child */ + ret =3D read(pipefd[0], buf, sizeof(buf)); + close(pipefd[0]); + + /* Wait for child to exit */ + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to create namespace or get handle"); + } + + ASSERT_GT(ret, 0); + handle =3D (struct file_handle *)buf; + + /* Try to reopen namespace - should fail with ENOENT since it's inactive = */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd >=3D 0) { + /* Namespace is still active - this could happen if cleanup is slow */ + TH_LOG("Warning: Namespace still active after process exit"); + close(fd); + } else { + /* Should fail with ENOENT (namespace inactive) or ESTALE */ + ASSERT_TRUE(errno =3D=3D ENOENT || errno =3D=3D ESTALE); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 38A04333456; Tue, 21 Oct 2025 11:45:42 +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=1761047142; cv=none; b=h8rwezb8ncwFDVOu+z6MqjMeG6LCbgyz98fSMqTi54IZHZWbWxCTRHkjX3BKGmyA17hgdstr78ktprUJ9EHkTkzv5syKsO6Td9KQWK3D1rZe512NYgRSzwtF8vj82zAzBrPcBYgXM5BWHQ/jJrK41AFhXCnd4/bVG27Q+fqx2Mk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047142; c=relaxed/simple; bh=RDvCp753eytqBU6RSu1QM6e320xY8EyidsVLpCI0zLo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UhA4zotpcu4o3GLWcTvWFHoZvhd8l3jdu7jvhDcimBYcHv/m4SoI7lmff0Af+y6UgOU6fNnYaiRlkhGNEJegEeRV02Z0fNTcB1SwuGBnjA7AaxB0JoYkNOklULWQJD57ED1Bmv7wyVOF5MeBwXRImqiWBGY4Hu3Pps/fA/sAlNA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O5BqrqdX; 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="O5BqrqdX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 411ABC4CEF1; Tue, 21 Oct 2025 11:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047142; bh=RDvCp753eytqBU6RSu1QM6e320xY8EyidsVLpCI0zLo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=O5BqrqdXnTmUGJzOG5lohLFAXA4oN5CTfBe83OTWFxEvNFNaqgvy6agZsDoNDtKGB HQbNwaKZJ7MssB7MEwYoM6ZdS0h8PzWbBR1UUgc+wTxekM3K60IDmzPO3Hf3utdTK0 qvDH6vJMCJSgbVenWQEINAp5EUTxzYqBaUREp3pTCPXgEtYTkkW1ESATukXV2OoGt5 unNIjlky69JJBGN+b8Iyu1ndvRsGQZR6TvqRoO+uklZxNq9lf4y0YCfZNZWiUye+eu oIjIyTnMXnVYHUzy5a3ftavPAj+c+66MEC2n46682MT34AnfQAfvehjtMFf0p+AEOD hwP9kBFXHH8yA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:27 +0200 Subject: [PATCH RFC DRAFT 21/50] selftests/namespaces: third active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-21-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3662; i=brauner@kernel.org; h=from:subject:message-id; bh=RDvCp753eytqBU6RSu1QM6e320xY8EyidsVLpCI0zLo=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y7hHPfry/5lgY3mPptW09ZrXz+68E72X6j57r9L V1rvve+7ihlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhInAIjw/50c4k/R6fIakXu Pcn2P9yZn3tS3wZmd/138nlNn04+Xsrwz140IOEl69cXtl9W9382yGy66yasfTNx9mHZxH9JVrN Z2QE= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that a namespace remains active while a process is using it, even after the creating process exits. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 128 +++++++++++++++++= ++++ 1 file changed, 128 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index f628b4a4a927..63233f22517a 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -160,4 +160,132 @@ TEST(ns_inactive_after_exit) } } =20 +/* + * Test that a namespace remains active while a process is using it, + * even after the creating process exits. + */ +TEST(ns_active_with_multiple_processes) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int pipefd[2]; + int syncpipe[2]; + pid_t pid1, pid2; + int status; + char buf[sizeof(*handle) + MAX_HANDLE_SZ]; + char sync_byte; + + /* Create pipes for communication */ + ASSERT_EQ(pipe(pipefd), 0); + ASSERT_EQ(pipe(syncpipe), 0); + + pid1 =3D fork(); + ASSERT_GE(pid1, 0); + + if (pid1 =3D=3D 0) { + /* First child - creates namespace */ + close(pipefd[0]); + close(syncpipe[1]); + + /* Create new network namespace */ + ret =3D unshare(CLONE_NEWNET); + if (ret < 0) { + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + + /* Open and get handle */ + fd =3D open("/proc/self/ns/net", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + + handle =3D (struct file_handle *)buf; + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(fd, "", handle, &mount_id, AT_EMPTY_PATH); + close(fd); + + if (ret < 0) { + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + + /* Send handle to parent */ + write(pipefd[1], buf, sizeof(*handle) + handle->handle_bytes); + close(pipefd[1]); + + /* Wait for signal before exiting */ + read(syncpipe[0], &sync_byte, 1); + close(syncpipe[0]); + exit(0); + } + + /* Parent reads handle */ + close(pipefd[1]); + ret =3D read(pipefd[0], buf, sizeof(buf)); + close(pipefd[0]); + ASSERT_GT(ret, 0); + + handle =3D (struct file_handle *)buf; + + /* Create second child that will keep namespace active */ + pid2 =3D fork(); + ASSERT_GE(pid2, 0); + + if (pid2 =3D=3D 0) { + /* Second child - reopens the namespace */ + close(syncpipe[0]); + close(syncpipe[1]); + + /* Open the namespace via handle */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0) { + exit(1); + } + + /* Join the namespace */ + ret =3D setns(fd, CLONE_NEWNET); + close(fd); + if (ret < 0) { + exit(1); + } + + /* Sleep to keep namespace active */ + sleep(1); + exit(0); + } + + /* Let second child enter the namespace */ + usleep(100000); /* 100ms */ + + /* Signal first child to exit */ + close(syncpipe[0]); + sync_byte =3D 'X'; + write(syncpipe[1], &sync_byte, 1); + close(syncpipe[1]); + + /* Wait for first child */ + waitpid(pid1, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + /* Namespace should still be active because second child is using it */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd < 0) { + /* If this fails, second child might not have entered namespace yet */ + TH_LOG("Warning: Could not reopen namespace (errno=3D%d)", errno); + } else { + close(fd); + } + + /* Wait for second child */ + waitpid(pid2, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 48AEA244693; Tue, 21 Oct 2025 11:45: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=1761047148; cv=none; b=muuz55KE3TIh3AE6XhK10NBx8jZA5KGYvYbu2o8NJwqIwSPJiEWDOvTusUB8JSBmGnlWyRK0jdXPw1oK54mAc/jWVsRq5G+zKDmGjELTIEOaPCzLE8cZ41JSbdStasn5n7O9ws1n5Amzu0qbdx0TBnFex7p29RX+u2lY1ibWITk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047148; c=relaxed/simple; bh=Xovo3cXcUN+Ljmv09mWRu/zdhsZObjVTLb0tW+lNHe8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pyUbTNlZzAugpLYugobDnIbYyEm1EH6l9lSRO5yaQhHhOGiIQsu56X7UILjLAhXZZMZWlIqdvWahmZFTuq6qbaD/cgxs7JGyOO9Md0xiDnZ+Yz/ZiklELcf/Hh8BV63HyyGdcm8M8Lcxdw+rsIwZ2E2Kd3eKhnY5/ozqyBn+eaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aCGgY8/2; 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="aCGgY8/2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 899B6C4CEF1; Tue, 21 Oct 2025 11:45:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047147; bh=Xovo3cXcUN+Ljmv09mWRu/zdhsZObjVTLb0tW+lNHe8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=aCGgY8/21CRlRoI57qcuePamgNkBMjzG5z3Ns1tTuSFLdzQdi6wHazMo024U7s8mT aU57aHwJxJ3pMlH6jbyUO78ADeRVPFKr3wIznIKcjBDDb5ajvx3AsIQvwM7gnPxumm 2yw7aHxly5hkLTpGio/5OtH60isS1i5o+esHXAftL8LUb9e1m5qCL6wJigNYqQDQdR LQucohfjOwpkLU/d6ZKfNY5ieVeREs8l96m/FIThZP9OIg/PQ09QpvyREpNrso89lP QbAJ6ktw6s10WHXGDZEpxSIe9R/a/RobytZ5eXqMDVU6dc8UOcV857i1iMOtlODkuE 1Dqe0HY3rdWKA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:28 +0200 Subject: [PATCH RFC DRAFT 22/50] selftests/namespaces: fourth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-22-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3057; i=brauner@kernel.org; h=from:subject:message-id; bh=Xovo3cXcUN+Ljmv09mWRu/zdhsZObjVTLb0tW+lNHe8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3yr/+0EO9OEUJl9yzU2m2st1VzDs6rGJfpZ/o9P8 hxTg+/v6ihlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhI93yG/37vbb+0KactCXx4 Njzz633mFXxBzyJmXvnndOx36Ws1r30M/3OZCtr2bm79k2SXev2ddGxc3MLC5mfWnPdkZm246iS 0gA0A X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test user namespace active ref tracking via credential lifecycle. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 97 ++++++++++++++++++= ++++ 1 file changed, 97 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 63233f22517a..b9836693f5ec 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -288,4 +288,101 @@ TEST(ns_active_with_multiple_processes) ASSERT_TRUE(WIFEXITED(status)); } =20 +/* + * Test user namespace active ref tracking via credential lifecycle + */ +TEST(userns_active_ref_lifecycle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int pipefd[2]; + pid_t pid; + int status; + char buf[sizeof(*handle) + MAX_HANDLE_SZ]; + + 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 < 0) { + close(pipefd[1]); + exit(1); + } + + /* Set up uid/gid mappings */ + 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 >=3D 0 && gid_map_fd >=3D 0 && setgroups_fd >=3D 0) { + write(setgroups_fd, "deny", 4); + close(setgroups_fd); + + 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); + } + + /* Get file handle */ + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + handle =3D (struct file_handle *)buf; + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(fd, "", handle, &mount_id, AT_EMPTY_PATH); + close(fd); + + if (ret < 0) { + close(pipefd[1]); + exit(1); + } + + /* Send handle to parent */ + write(pipefd[1], buf, sizeof(*handle) + handle->handle_bytes); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + ret =3D read(pipefd[0], buf, sizeof(buf)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to create user namespace"); + } + + ASSERT_GT(ret, 0); + handle =3D (struct file_handle *)buf; + + /* Namespace should be inactive after all tasks exit */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd >=3D 0) { + TH_LOG("Warning: User namespace still active after process exit"); + close(fd); + } else { + ASSERT_TRUE(errno =3D=3D ENOENT || errno =3D=3D ESTALE); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 8862B33373E; Tue, 21 Oct 2025 11:45: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=1761047153; cv=none; b=nCP2PXbwstSP1jmZLt/6c4AbMg9HrK7Irnb1iytMkRoCSV7mqFgBwDtHJhcDwfhlL/qYNeAAa+23m8Ck1cmZXJwqa7JoTgWtb7lK16T6RM9GTs/nu9zu1ftlxVu2L6KxSeO/G52fQGg49rZ5Xk8CYo6LIilELF2FuDfbHqcb1nM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047153; c=relaxed/simple; bh=Hpp75xec5mwn0pm6bwe74NHV8CGVz16jvWJi/wNRADw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G8liSgc1lKoGoxtnlq+f++SAMRdCB33GfRjjRvkhNnPCPxcyY9XOAUHOgnAIGHgrhEN+28hMUpa8lGVu/0YCDWTTG4mh062//5GwDOaq4MwnbJ73gNARExGRVlvpv0mp0WC4TTAWryB35+SRsVWk67r7ms/s7M+N46pZPtO5cWY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CePo0S6J; 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="CePo0S6J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 40A8EC4CEFF; Tue, 21 Oct 2025 11:45:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047153; bh=Hpp75xec5mwn0pm6bwe74NHV8CGVz16jvWJi/wNRADw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=CePo0S6JZfKaro9at7USO6yQYm4UCaRUk+KUzAbSZOOc/VCY08NTdgjgx+sN0sNBI YHk3DjGwidbY6XHQ6qhAHvDfqWR++gWSY1sGFYYEdeGSZqIyNchh+dDOshd5ZRWzX6 7Du43RTSHXYyHsjTy0j7y1o8qVZgX36RWTwgK8UQHc0KzoDq+gFm9Uh0SR3CvC+ixp IWEdzV9nX94EGLreEMPuJ/h4T6B8cSRlqTBpcH5+ogNflDhc4VqkEqzKMBf06+zfCk rZzO3jqO9O0/BS27rc0gu4toZXYzrv4UKaHZvGHhAt8qsXnQurP3sKbarbN1fWV2J3 wB52OOJC4+/+A== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:29 +0200 Subject: [PATCH RFC DRAFT 23/50] selftests/namespaces: fifth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-23-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2525; i=brauner@kernel.org; h=from:subject:message-id; bh=Hpp75xec5mwn0pm6bwe74NHV8CGVz16jvWJi/wNRADw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3z7d2Ynu9ln7doXJ1WvvzQMUAwxOtc1jeexr3bJt d4Zy4LudZSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEzk8x9GhqvH3zF+2jjrvlTV 6he7FO4uv7aXY53mrSLjW69azzk+2xLEyLDgDeec+x0b/zp/z6goaFu6XLwgd4vsnsdndz7hkDM 9P50BAA== X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test PID namespace active ref tracking Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 88 ++++++++++++++++++= ++++ 1 file changed, 88 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index b9836693f5ec..66665bd39e9b 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -385,4 +385,92 @@ TEST(userns_active_ref_lifecycle) } } =20 +/* + * Test PID namespace active ref tracking + */ +TEST(pidns_active_ref_lifecycle) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int pipefd[2]; + pid_t pid; + int status; + char buf[sizeof(*handle) + MAX_HANDLE_SZ]; + + 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 < 0) { + close(pipefd[1]); + exit(1); + } + + /* Fork to actually enter the PID namespace */ + pid_t child =3D fork(); + if (child < 0) { + close(pipefd[1]); + exit(1); + } + + if (child =3D=3D 0) { + /* Grandchild - in new PID namespace */ + fd =3D open("/proc/self/ns/pid", O_RDONLY); + if (fd < 0) { + exit(1); + } + + handle =3D (struct file_handle *)buf; + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(fd, "", handle, &mount_id, AT_EMPTY_PATH); + close(fd); + + if (ret < 0) { + exit(1); + } + + /* Send handle to grandparent */ + write(pipefd[1], buf, sizeof(*handle) + handle->handle_bytes); + close(pipefd[1]); + exit(0); + } + + /* Wait for grandchild */ + waitpid(child, NULL, 0); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + ret =3D read(pipefd[0], buf, sizeof(buf)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (ret <=3D 0) { + SKIP(return, "Child failed to create PID namespace or get handle"); + } + + handle =3D (struct file_handle *)buf; + + /* Namespace should be inactive after all processes exit */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd >=3D 0) { + TH_LOG("Warning: PID namespace still active after process exit"); + close(fd); + } else { + ASSERT_TRUE(errno =3D=3D ENOENT || errno =3D=3D ESTALE); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 D0169342149; Tue, 21 Oct 2025 11:45:58 +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=1761047158; cv=none; b=evz+BpbcM3mZ7orFsZBigajAJLkUFQ0WYxFVRNfJVg8DE2XPpwW0ITqiah2SaB+cjHk3dRNiyUBR6aP+PaNOdyMYdJWr+rnQ7mOZ6huFS4cBGLfBVvtBILF+bmXv9mI0e4T1STvlUFgKrw7YKRvmSwwUNnd+1x/L2JKutZI4oT8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047158; c=relaxed/simple; bh=uOH3CT+OUgM5Z/Sy7CrxJmBWupBsQ4/yDAh+nMm1LYg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TlQiXPnzMXbPjz3wHfofHlkQ5SNOZ5gSCfiaIOjEA59lHKyrgkZhuTqLFIF5rN1iLGtzd32PGPLdRvsUtDSMb2u9o9P5hAFsYuVJZur8stp3bxLgxQyh6uKo/MAVMv63FW7ZMaebVzPV1FmAnEvE44oWKyrOVFqMxfFi5mQhbFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H1fi4Gr1; 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="H1fi4Gr1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7DBC7C4CEF5; Tue, 21 Oct 2025 11:45:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047158; bh=uOH3CT+OUgM5Z/Sy7CrxJmBWupBsQ4/yDAh+nMm1LYg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H1fi4Gr1EFMYDUL1pzIJeZIZDzQ/JHPbq1JUifXDaByHwA1mJ8p5FmttWqDmceJbP dONWJKpu8Gy/+14E5zseA9FBiERE7lY65IrvdMxIO1gCrogPd+0kNRDcH+BFdPzZ1D nTq2qCUgfGIeeSVM1Ppqq5jL3lITA9gibMnOdqOhgHHc08iBFtMlrJmwvZqiA4vdtt BQYfngfQYSAUyey6+PW4mnlumXPniQIbuDlYUX151DA15/rw0orrcwMmokxH9B5u3E /UJuOoFRKvdEb6R5AUJk9zi0U7KcD+lTwJhwDY+WXvPJUghcwx/jAjnQBOj2fH2eoL ze6HPLUp1lGMA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:30 +0200 Subject: [PATCH RFC DRAFT 24/50] selftests/namespaces: sixth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-24-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=6091; i=brauner@kernel.org; h=from:subject:message-id; bh=uOH3CT+OUgM5Z/Sy7CrxJmBWupBsQ4/yDAh+nMm1LYg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y7e5/o7xv/EhY+i315crLvttDN6j4dkTOcn02Sd Gxo5ObW6ShlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZiIjjYjw/ujKpImcTJM85P4 t5TaLZnWN3mf5Od1Agr/pEy0vnnsK2b4ZxOtK8pknJ2QYnqMeTr/v9NcjPMzv5vfeThp9ef+3B2 BTAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that an open file descriptor keeps a namespace active. Even after the creating process exits, the namespace should remain active as long as an fd is held open. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 168 +++++++++++++++++= ++++ 1 file changed, 168 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 66665bd39e9b..dbb1eb8a04b2 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -473,4 +473,172 @@ TEST(pidns_active_ref_lifecycle) } } =20 +/* + * Test that an open file descriptor keeps a namespace active. + * Even after the creating process exits, the namespace should remain + * active as long as an fd is held open. + */ +TEST(ns_fd_keeps_active) +{ + struct file_handle *handle; + int mount_id; + int ret; + int nsfd; + int pipe_child_ready[2]; + int pipe_parent_ready[2]; + pid_t pid; + int status; + char buf[sizeof(*handle) + MAX_HANDLE_SZ]; + char sync_byte; + char proc_path[64]; + + ASSERT_EQ(pipe(pipe_child_ready), 0); + ASSERT_EQ(pipe(pipe_parent_ready), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipe_child_ready[0]); + close(pipe_parent_ready[1]); + + TH_LOG("Child: creating new network namespace"); + + /* Create new network namespace */ + ret =3D unshare(CLONE_NEWNET); + if (ret < 0) { + TH_LOG("Child: unshare(CLONE_NEWNET) failed: %s", strerror(errno)); + close(pipe_child_ready[1]); + close(pipe_parent_ready[0]); + exit(1); + } + + TH_LOG("Child: network namespace created successfully"); + + /* Get file handle for the namespace */ + nsfd =3D open("/proc/self/ns/net", O_RDONLY); + if (nsfd < 0) { + TH_LOG("Child: failed to open /proc/self/ns/net: %s", strerror(errno)); + close(pipe_child_ready[1]); + close(pipe_parent_ready[0]); + exit(1); + } + + TH_LOG("Child: opened namespace fd %d", nsfd); + + handle =3D (struct file_handle *)buf; + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(nsfd, "", handle, &mount_id, AT_EMPTY_PATH); + close(nsfd); + + if (ret < 0) { + TH_LOG("Child: name_to_handle_at failed: %s", strerror(errno)); + close(pipe_child_ready[1]); + close(pipe_parent_ready[0]); + exit(1); + } + + TH_LOG("Child: got file handle (bytes=3D%u)", handle->handle_bytes); + + /* Send file handle to parent */ + ret =3D write(pipe_child_ready[1], buf, sizeof(*handle) + handle->handle= _bytes); + TH_LOG("Child: sent %d bytes of file handle to parent", ret); + close(pipe_child_ready[1]); + + /* Wait for parent to open the fd */ + TH_LOG("Child: waiting for parent to open fd"); + ret =3D read(pipe_parent_ready[0], &sync_byte, 1); + close(pipe_parent_ready[0]); + + TH_LOG("Child: parent signaled (read %d bytes), exiting now", ret); + /* Exit - namespace should stay active because parent holds fd */ + exit(0); + } + + /* Parent process */ + close(pipe_child_ready[1]); + close(pipe_parent_ready[0]); + + TH_LOG("Parent: reading file handle from child"); + + /* Read file handle from child */ + ret =3D read(pipe_child_ready[0], buf, sizeof(buf)); + close(pipe_child_ready[0]); + ASSERT_GT(ret, 0); + handle =3D (struct file_handle *)buf; + + TH_LOG("Parent: received %d bytes, handle size=3D%u", ret, handle->handle= _bytes); + + /* Open the child's namespace while it's still alive */ + snprintf(proc_path, sizeof(proc_path), "/proc/%d/ns/net", pid); + TH_LOG("Parent: opening child's namespace at %s", proc_path); + nsfd =3D open(proc_path, O_RDONLY); + if (nsfd < 0) { + TH_LOG("Parent: failed to open %s: %s", proc_path, strerror(errno)); + close(pipe_parent_ready[1]); + kill(pid, SIGKILL); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open child's namespace"); + } + + TH_LOG("Parent: opened child's namespace, got fd %d", nsfd); + + /* Signal child that we have the fd */ + sync_byte =3D 'G'; + write(pipe_parent_ready[1], &sync_byte, 1); + close(pipe_parent_ready[1]); + TH_LOG("Parent: signaled child that we have the fd"); + + /* Wait for child to exit */ + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + close(nsfd); + SKIP(return, "Child failed to create namespace"); + } + + TH_LOG("Child exited, parent holds fd %d to namespace", nsfd); + + /* + * Namespace should still be ACTIVE because we hold an fd. + * We should be able to reopen it via file handle. + */ + TH_LOG("Attempting to reopen namespace via file handle (should succeed - = fd held)"); + int fd2 =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd2 < 0) { + close(nsfd); + TH_LOG("ERROR: Failed to reopen active namespace (fd held): %s (errno=3D= %d)", + strerror(errno), errno); + ASSERT_TRUE(false); + } + + TH_LOG("Successfully reopened namespace via file handle, got fd %d", fd2); + + /* Verify it's the same namespace */ + struct stat st1, st2; + ASSERT_EQ(fstat(nsfd, &st1), 0); + ASSERT_EQ(fstat(fd2, &st2), 0); + TH_LOG("Namespace inodes: nsfd=3D%lu, fd2=3D%lu", st1.st_ino, st2.st_ino); + ASSERT_EQ(st1.st_ino, st2.st_ino); + close(fd2); + + /* Now close the fd - namespace should become inactive */ + TH_LOG("Closing fd %d - namespace should become inactive", nsfd); + close(nsfd); + + /* Now reopening should fail - namespace is inactive */ + TH_LOG("Attempting to reopen namespace via file handle (should fail - ina= ctive)"); + fd2 =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd2 >=3D 0) { + close(fd2); + TH_LOG("ERROR: Namespace still active after closing all fds (fd=3D%d)", = fd2); + } else { + /* Should fail with ENOENT (inactive) or ESTALE (gone) */ + TH_LOG("Reopen failed as expected: %s (errno=3D%d)", strerror(errno), er= rno); + ASSERT_TRUE(errno =3D=3D ENOENT || errno =3D=3D ESTALE); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 03EF5334363; Tue, 21 Oct 2025 11:46:03 +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=1761047164; cv=none; b=qJPAbdnta27j4BC6HaEEnWkRwf7bPZjDu0dICRA7+tEwxNFt57XDxzdCkBGr2Ounay8GrmUQyyV2ievkT3ffHHsDDkvreiVDE1RobACJO+Q+EmrXbqtsN5SfPSrqyTfq3GwrBw0WUzN8qZTvUrjaFbZlDMVxhIXjh1s8659MraA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047164; c=relaxed/simple; bh=U3JxLSa2fcjBw06O9/5jwtS8zf3ICC+ECTB2/eqH3P8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Tnlum+Te9T5PoBPAq/qArkmR+D8tGM9Xqrpu8vqG02MODJAYGTn6Q4dIxChVfR6e798Bvs/DPz92NVvx540t77kOo2s6hU6vDMZmrcoUbu97gBWi3ZoKQWSv/7sX9/vP6SL/6moQ0qnd/tZHAVkkG1FK5ojGxYtOInqMwnuyJPE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hpHkfio1; 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="hpHkfio1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7E2EC4CEF1; Tue, 21 Oct 2025 11:45:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047163; bh=U3JxLSa2fcjBw06O9/5jwtS8zf3ICC+ECTB2/eqH3P8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hpHkfio1WabJfxnOKMQZOBXVRc7azbXC4kkB+1wSsenukirkdL+kAQ6JrcRFkw08/ ZAvugPYQX5hskuVrdXbupffbJv2QIaeYTpc6VetFAFCxMNB3Cdzed0lekbfreZ5zOl IGwSghIz1LZtAPQ5gPqyCiZ0rTDmMP5etOZHVaL7u13COamhMn/WrgYs4i73gTpOx7 vkxE/2c9/WBR05yjx9elgUGYAR+sTMOeUulfZgL/mfgokUgHWuLz90+CMBcQH48dx5 GTGHCCpj3OwEMtVGdq/ObmPk81oAyepztNjhFq5t0b776WTPsXnYsNqtGwyqANZaYg CNBLRyVCpuhRA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:31 +0200 Subject: [PATCH RFC DRAFT 25/50] selftests/namespaces: seventh active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-25-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=9454; i=brauner@kernel.org; h=from:subject:message-id; bh=U3JxLSa2fcjBw06O9/5jwtS8zf3ICC+ECTB2/eqH3P8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y7p4n52GXDw4t7j/y3cVwt4PvIzWjTXfXVb45sF Gvg0Dz3oKOUhUGMi0FWTJHFod0kXG45T8Vmo0wNmDmsTCBDGLg4BWAiWn6MDBuVi7Zde+A/ddOx d2p/lnBOCxP/bnf2sl/AdTbDjICzO1sYGT7Et1ZdLPRlLeb/W3nlZcQF9l+1/y2lfB2iTI++W9y bwgUA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test hierarchical active reference propagation. When a child namespace is active, its owning user namespace should also be active automatically due to hierarchical active reference propagation. This ensures parents are always reachable when children are active. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 242 +++++++++++++++++= ++++ 1 file changed, 242 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index dbb1eb8a04b2..6377f5d72ed9 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -20,6 +20,10 @@ #define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */ #endif =20 +#ifndef FILEID_NSFS +#define FILEID_NSFS 0xf1 +#endif + /* * Test that initial namespaces can be reopened via file handle. * Initial namespaces should have active ref count of 1 from boot. @@ -641,4 +645,242 @@ TEST(ns_fd_keeps_active) } } =20 +/* + * Test hierarchical active reference propagation. + * When a child namespace is active, its owning user namespace should also + * be active automatically due to hierarchical active reference propagatio= n. + * This ensures parents are always reachable when children are active. + */ +TEST(ns_parent_always_reachable) +{ + struct file_handle *parent_handle, *child_handle; + int ret; + int child_nsfd; + int pipefd[2]; + pid_t pid; + int status; + __u64 parent_id, child_id; + char parent_buf[sizeof(*parent_handle) + MAX_HANDLE_SZ]; + char child_buf[sizeof(*child_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + TH_LOG("Child: creating parent user namespace and setting up mappings"); + + /* Create parent user namespace with mappings */ + ret =3D setup_userns(); + if (ret < 0) { + TH_LOG("Child: setup_userns() for parent failed: %s", strerror(errno)); + close(pipefd[1]); + exit(1); + } + + TH_LOG("Child: parent user namespace created, now uid=3D%d gid=3D%d", ge= tuid(), getgid()); + + /* Get namespace ID for parent user namespace */ + int parent_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (parent_fd < 0) { + TH_LOG("Child: failed to open parent /proc/self/ns/user: %s", strerror(= errno)); + close(pipefd[1]); + exit(1); + } + + TH_LOG("Child: opened parent userns fd %d", parent_fd); + + if (ioctl(parent_fd, NS_GET_ID, &parent_id) < 0) { + TH_LOG("Child: NS_GET_ID for parent failed: %s", strerror(errno)); + close(parent_fd); + close(pipefd[1]); + exit(1); + } + close(parent_fd); + + TH_LOG("Child: got parent namespace ID %llu", (unsigned long long)parent= _id); + + /* Create child user namespace within parent */ + TH_LOG("Child: creating nested child user namespace"); + ret =3D setup_userns(); + if (ret < 0) { + TH_LOG("Child: setup_userns() for child failed: %s", strerror(errno)); + close(pipefd[1]); + exit(1); + } + + TH_LOG("Child: nested child user namespace created, uid=3D%d gid=3D%d", = getuid(), getgid()); + + /* Get namespace ID for child user namespace */ + int child_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (child_fd < 0) { + TH_LOG("Child: failed to open child /proc/self/ns/user: %s", strerror(e= rrno)); + close(pipefd[1]); + exit(1); + } + + TH_LOG("Child: opened child userns fd %d", child_fd); + + if (ioctl(child_fd, NS_GET_ID, &child_id) < 0) { + TH_LOG("Child: NS_GET_ID for child failed: %s", strerror(errno)); + close(child_fd); + close(pipefd[1]); + exit(1); + } + close(child_fd); + + TH_LOG("Child: got child namespace ID %llu", (unsigned long long)child_i= d); + + /* Send both namespace IDs to parent */ + TH_LOG("Child: sending both namespace IDs to parent"); + write(pipefd[1], &parent_id, sizeof(parent_id)); + write(pipefd[1], &child_id, sizeof(child_id)); + close(pipefd[1]); + + TH_LOG("Child: exiting - parent userns should become inactive"); + /* Exit - parent user namespace should become inactive */ + exit(0); + } + + /* Parent process */ + close(pipefd[1]); + + TH_LOG("Parent: reading both namespace IDs from child"); + + /* Read both namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &parent_id, sizeof(parent_id)); + if (ret !=3D sizeof(parent_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read parent namespace ID from child"); + } + + ret =3D read(pipefd[0], &child_id, sizeof(child_id)); + close(pipefd[0]); + if (ret !=3D sizeof(child_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read child namespace ID from child"); + } + + TH_LOG("Parent: received parent_id=3D%llu, child_id=3D%llu", + (unsigned long long)parent_id, (unsigned long long)child_id); + + /* Construct file handles from namespace IDs */ + parent_handle =3D (struct file_handle *)parent_buf; + parent_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + parent_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *parent_fh =3D (struct nsfs_file_handle *)parent_= handle->f_handle; + parent_fh->ns_id =3D parent_id; + parent_fh->ns_type =3D 0; + parent_fh->ns_inum =3D 0; + + child_handle =3D (struct file_handle *)child_buf; + child_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + child_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *child_fh =3D (struct nsfs_file_handle *)child_ha= ndle->f_handle; + child_fh->ns_id =3D child_id; + child_fh->ns_type =3D 0; + child_fh->ns_inum =3D 0; + + TH_LOG("Parent: opening child namespace BEFORE child exits"); + + /* Open child namespace while child is still alive to keep it active */ + child_nsfd =3D open_by_handle_at(FD_NSFS_ROOT, child_handle, O_RDONLY); + if (child_nsfd < 0) { + TH_LOG("Failed to open child namespace: %s (errno=3D%d)", strerror(errno= ), errno); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open child namespace"); + } + + TH_LOG("Opened child namespace fd %d", child_nsfd); + + /* Now wait for child to exit */ + TH_LOG("Parent: waiting for child to exit"); + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + close(child_nsfd); + SKIP(return, "Child failed to create namespaces"); + } + + TH_LOG("Child process exited, parent holds fd to child namespace"); + + /* + * With hierarchical active reference propagation: + * Since the child namespace is active (parent process holds fd), + * the parent user namespace should ALSO be active automatically. + * This is because when we took an active reference on the child, + * it propagated up to the owning user namespace. + */ + TH_LOG("Attempting to reopen parent namespace (should SUCCEED - hierarchi= cal propagation)"); + int parent_fd =3D open_by_handle_at(FD_NSFS_ROOT, parent_handle, O_RDONLY= ); + if (parent_fd < 0) { + close(child_nsfd); + TH_LOG("ERROR: Parent namespace inactive despite active child: %s (errno= =3D%d)", + strerror(errno), errno); + TH_LOG("This indicates hierarchical active reference propagation is not = working!"); + ASSERT_TRUE(false); + } + + TH_LOG("SUCCESS: Parent namespace is active (fd=3D%d) due to active child= ", parent_fd); + + /* Verify we can also get parent via NS_GET_USERNS */ + TH_LOG("Verifying NS_GET_USERNS also works"); + int parent_fd2 =3D ioctl(child_nsfd, NS_GET_USERNS); + if (parent_fd2 < 0) { + close(parent_fd); + close(child_nsfd); + TH_LOG("NS_GET_USERNS failed: %s (errno=3D%d)", strerror(errno), errno); + SKIP(return, "NS_GET_USERNS not supported or failed"); + } + + TH_LOG("NS_GET_USERNS succeeded, got parent fd %d", parent_fd2); + + /* Verify both methods give us the same namespace */ + struct stat st1, st2; + ASSERT_EQ(fstat(parent_fd, &st1), 0); + ASSERT_EQ(fstat(parent_fd2, &st2), 0); + TH_LOG("Parent namespace inodes: parent_fd=3D%lu, parent_fd2=3D%lu", st1.= st_ino, st2.st_ino); + ASSERT_EQ(st1.st_ino, st2.st_ino); + + /* + * Close child fd - parent should remain active because we still + * hold direct references to it (parent_fd and parent_fd2). + */ + TH_LOG("Closing child fd - parent should remain active (direct refs held)= "); + close(child_nsfd); + + /* Parent should still be openable */ + TH_LOG("Verifying parent still active via file handle"); + int parent_fd3 =3D open_by_handle_at(FD_NSFS_ROOT, parent_handle, O_RDONL= Y); + if (parent_fd3 < 0) { + close(parent_fd); + close(parent_fd2); + TH_LOG("ERROR: Parent became inactive despite holding fds: %s (errno=3D%= d)", + strerror(errno), errno); + ASSERT_TRUE(false); + } + close(parent_fd3); + + TH_LOG("Closing all fds to parent namespace"); + close(parent_fd); + close(parent_fd2); + + /* Both should now be inactive */ + TH_LOG("Attempting to reopen parent (should fail - inactive, no refs)"); + parent_fd =3D open_by_handle_at(FD_NSFS_ROOT, parent_handle, O_RDONLY); + if (parent_fd >=3D 0) { + close(parent_fd); + TH_LOG("ERROR: Parent namespace still active after closing all fds (fd= =3D%d)", parent_fd); + } else { + TH_LOG("Parent inactive as expected: %s (errno=3D%d)", strerror(errno), = errno); + ASSERT_TRUE(errno =3D=3D ENOENT || errno =3D=3D ESTALE); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 D8255334363; Tue, 21 Oct 2025 11:46:08 +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=1761047169; cv=none; b=hnThhumBJ2pvS5cV7EXSZZRlzLYBoqeN/4+uJ0Luem8xrTLaQvAMvvN43soNc7+DZEx64wtajQuHT1MKIkMPPUNgJorvMWTf9SKeXwA9mOFeVQFObRUJ/jrWW4lXA/IIZ/1ZgQcyQTHHFCc5Y6v3Ns+XknUwi26iwwAn7vj8mmI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047169; c=relaxed/simple; bh=2l+rS6eqHz2E2xHEBSJ9zjxwvPPCR3H2Nll2sPPrQIg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WlKJ70fSljOIY/X32ZCmv+snysK3yAKYO8nldxq+NRc1b6VVRVZet4YAxuUtnHlw/pjHOEgc2Vc4KXcWrTIsX2QSPHdxUPxKMN3zXo4RwE5WtY1z03rlvAYrJlD7QEnK6gU1sbnRM17hT8f7U0bqqrMVKkEOv32y/uNY7Puj6Wg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YB888je/; 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="YB888je/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A4F0C4CEFF; Tue, 21 Oct 2025 11:46:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047168; bh=2l+rS6eqHz2E2xHEBSJ9zjxwvPPCR3H2Nll2sPPrQIg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YB888je/n0nSaig0UssLUNIRmHYHZ3+rKCm4OEaoNjsNLGTSB/CkJ/hg2Qk47L4+D jxmqjP5W33AzBMvdSbWLgD/2395FPX8VfVLAFJ2HvmocrCOz9Wl/JAQIs3VBLJj/9J 7hyksnCCdCOAZvpHHKmrgvuOd1cPBOUdD+l2T/CvhE0jxvqWMgFDkw4FkCekJfOoBp Tn7iqb//kAn7termz5iQ1gPdZtBaqZM0IlB1hVTvz+nk4tZuRSm2JdFL4Jrw+DtiXm xf8a2XGwhFzVtOj7E1ge+0PmbLKCBF4sxOtU0s7mfQLpLMEf9/UEpgKZUdr54FW+s6 acjiyEf8vpoqw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:32 +0200 Subject: [PATCH RFC DRAFT 26/50] selftests/namespaces: eigth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-26-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3580; i=brauner@kernel.org; h=from:subject:message-id; bh=2l+rS6eqHz2E2xHEBSJ9zjxwvPPCR3H2Nll2sPPrQIg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zb9c2l/6HNZsZyjieKd3+VbK6+H7+FI9Txsdrnl eu2fT3W1FHKwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjCRKF1GhgkyvraPiyZXMYuu +aarl685Z3trNq8d7z2n3c8Xr9FUrWb4p8Aguaew/mheVfP2c51/JE4UpGm5267kTC47zKI9SyO LCwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that bind mounts keep namespaces in the tree even when inactive Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 126 +++++++++++++++++= ++++ 1 file changed, 126 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 6377f5d72ed9..66c9908d4977 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -883,4 +883,130 @@ TEST(ns_parent_always_reachable) } } =20 +/* + * Test that bind mounts keep namespaces in the tree even when inactive + */ +TEST(ns_bind_mount_keeps_in_tree) +{ + struct file_handle *handle; + int mount_id; + int ret; + int fd; + int pipefd[2]; + pid_t pid; + int status; + char buf[sizeof(*handle) + MAX_HANDLE_SZ]; + char tmpfile[] =3D "/tmp/ns-test-XXXXXX"; + int tmpfd; + + /* Create temporary file for bind mount */ + tmpfd =3D mkstemp(tmpfile); + if (tmpfd < 0) { + SKIP(return, "Cannot create temporary file"); + } + close(tmpfd); + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + /* Child process */ + close(pipefd[0]); + + /* Unshare mount namespace and make mounts private to avoid propagation = */ + ret =3D unshare(CLONE_NEWNS); + if (ret < 0) { + close(pipefd[1]); + unlink(tmpfile); + exit(1); + } + ret =3D mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL); + if (ret < 0) { + close(pipefd[1]); + unlink(tmpfile); + exit(1); + } + + /* Create new network namespace */ + ret =3D unshare(CLONE_NEWNET); + if (ret < 0) { + close(pipefd[1]); + unlink(tmpfile); + exit(1); + } + + /* Bind mount the namespace */ + ret =3D mount("/proc/self/ns/net", tmpfile, NULL, MS_BIND, NULL); + if (ret < 0) { + close(pipefd[1]); + unlink(tmpfile); + exit(1); + } + + /* Get file handle */ + fd =3D open("/proc/self/ns/net", O_RDONLY); + if (fd < 0) { + umount(tmpfile); + close(pipefd[1]); + unlink(tmpfile); + exit(1); + } + + handle =3D (struct file_handle *)buf; + handle->handle_bytes =3D MAX_HANDLE_SZ; + ret =3D name_to_handle_at(fd, "", handle, &mount_id, AT_EMPTY_PATH); + close(fd); + + if (ret < 0) { + umount(tmpfile); + close(pipefd[1]); + unlink(tmpfile); + exit(1); + } + + /* Send handle to parent */ + write(pipefd[1], buf, sizeof(*handle) + handle->handle_bytes); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + ret =3D read(pipefd[0], buf, sizeof(buf)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + unlink(tmpfile); + SKIP(return, "Child failed to create namespace or bind mount"); + } + + ASSERT_GT(ret, 0); + handle =3D (struct file_handle *)buf; + + /* + * Namespace should be inactive but still in tree due to bind mount. + * Reopening should fail with ENOENT (inactive) not ESTALE (not in tree). + */ + fd =3D open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); + if (fd >=3D 0) { + /* Unexpected - namespace shouldn't be active */ + close(fd); + TH_LOG("Warning: Namespace still active"); + } else { + /* Should be ENOENT (inactive) since bind mount keeps it in tree */ + if (errno !=3D ENOENT && errno !=3D ESTALE) { + TH_LOG("Unexpected error: %d", errno); + } + } + + /* Cleanup */ + umount(tmpfile); + unlink(tmpfile); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 73A2B343D63; Tue, 21 Oct 2025 11:46:14 +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=1761047174; cv=none; b=AGloWHbJ9+KqQPlu+zAaZePA8WJ1jSRz3eI0HWVBGUiHydgTMEfj2nFGGaaqF2DPnF1jnI496OEHXPm6beAED/fwQ9vdUZ5f+LVVQzBJZwBOy/MmIX6jfKr6OdoQJuxejlXcJkdZJY5eGLuvj6TSQYkmZaXIxBm0cSDNFTV5V9Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047174; c=relaxed/simple; bh=BymNUOybDFEecH4odJXIxHYLUKctxSR2IXDi+nRlDH8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n1o7n5ReoesHERybtBME9rn2IjEyOozVrWrd0PiFDmQTJLt5NqlZXrQsyhSneKfNUsdzH50JzZQjH2S8C3dA1OuS+ZQUbXyVufdBit6YP1jy91xpe/QHGYN3ft1VX/eqZvujxr7Bhtyt/+E5G966xq/nDMiJqAXbNLKG2Aiz2Nk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hOwcZElD; 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="hOwcZElD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73977C4CEF1; Tue, 21 Oct 2025 11:46:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047174; bh=BymNUOybDFEecH4odJXIxHYLUKctxSR2IXDi+nRlDH8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hOwcZElDzqPyNcnmTlcbsm2wWWgjXEFleR0p6wKfdXIf172JV1dNFjgtgDVbp7qA3 3TDsi9XwiQVvuQ399prEDFUxwOpKrgVRrN2SzfOD7Uj6dOmZzq/NVDjUh+c/Pa6tz0 1G8Z/pzYJzS8libP/FOrqfRaDTjTbm5dIeCDntHrp+R3qWoPKeeRi6tU/jBgkn6gI0 zmToXsOoHorKU0PK95oJL1cz28Q08tjOOq9vmTC/jWaHmhiMsyK9yTkxSH8Py/YrNO b5/O3jeHl3S6Gv/9f2sFAS9x13dWtBnJeENhALVsWExY/LXrb8JRWUHx0sZbdN4BdU E0iUl1ZQJL1OQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:33 +0200 Subject: [PATCH RFC DRAFT 27/50] selftests/namespaces: ninth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-27-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=5259; i=brauner@kernel.org; h=from:subject:message-id; bh=BymNUOybDFEecH4odJXIxHYLUKctxSR2IXDi+nRlDH8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3x7Yc3ijaUMSu2JnwRq9042fbTGJcNIpi5hWcblK yvqNByYO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACbytYDhf8WWJ6ylpioHLHZL tb1J2pAwbcdclj/SJRUR92uLfWbLMDIyTNNROuHH/cTyecyhmcyrruYGXGdfdvqUertBJMc5re9 O/AA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test multi-level hierarchy (3+ levels deep). Grandparent =E2=86=92 Parent =E2=86=92 Child When child is active, both parent AND grandparent should be active. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 167 +++++++++++++++++= ++++ 1 file changed, 167 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 66c9908d4977..87b435b64b45 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -1009,4 +1009,171 @@ TEST(ns_bind_mount_keeps_in_tree) unlink(tmpfile); } =20 +/* + * Test multi-level hierarchy (3+ levels deep). + * Grandparent =E2=86=92 Parent =E2=86=92 Child + * When child is active, both parent AND grandparent should be active. + */ +TEST(ns_multilevel_hierarchy) +{ + struct file_handle *gp_handle, *p_handle, *c_handle; + int ret, pipefd[2]; + pid_t pid; + int status; + __u64 gp_id, p_id, c_id; + char gp_buf[sizeof(*gp_handle) + MAX_HANDLE_SZ]; + char p_buf[sizeof(*p_handle) + MAX_HANDLE_SZ]; + char c_buf[sizeof(*c_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + + /* Create grandparent user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int gp_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (gp_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(gp_fd, NS_GET_ID, &gp_id) < 0) { + close(gp_fd); + close(pipefd[1]); + exit(1); + } + close(gp_fd); + + /* Create parent user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int p_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (p_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(p_fd, NS_GET_ID, &p_id) < 0) { + close(p_fd); + close(pipefd[1]); + exit(1); + } + close(p_fd); + + /* Create child user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int c_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (c_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(c_fd, NS_GET_ID, &c_id) < 0) { + close(c_fd); + close(pipefd[1]); + exit(1); + } + close(c_fd); + + /* Send all three namespace IDs */ + write(pipefd[1], &gp_id, sizeof(gp_id)); + write(pipefd[1], &p_id, sizeof(p_id)); + write(pipefd[1], &c_id, sizeof(c_id)); + close(pipefd[1]); + exit(0); + } + + close(pipefd[1]); + + /* Read all three namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &gp_id, sizeof(gp_id)); + if (ret !=3D sizeof(gp_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read grandparent namespace ID from child"); + } + + ret =3D read(pipefd[0], &p_id, sizeof(p_id)); + if (ret !=3D sizeof(p_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read parent namespace ID from child"); + } + + ret =3D read(pipefd[0], &c_id, sizeof(c_id)); + close(pipefd[0]); + if (ret !=3D sizeof(c_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read child namespace ID from child"); + } + + /* Construct file handles from namespace IDs */ + gp_handle =3D (struct file_handle *)gp_buf; + gp_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + gp_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *gp_fh =3D (struct nsfs_file_handle *)gp_handle->= f_handle; + gp_fh->ns_id =3D gp_id; + gp_fh->ns_type =3D 0; + gp_fh->ns_inum =3D 0; + + p_handle =3D (struct file_handle *)p_buf; + p_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + p_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *p_fh =3D (struct nsfs_file_handle *)p_handle->f_= handle; + p_fh->ns_id =3D p_id; + p_fh->ns_type =3D 0; + p_fh->ns_inum =3D 0; + + c_handle =3D (struct file_handle *)c_buf; + c_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + c_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *c_fh =3D (struct nsfs_file_handle *)c_handle->f_= handle; + c_fh->ns_id =3D c_id; + c_fh->ns_type =3D 0; + c_fh->ns_inum =3D 0; + + /* Open child before process exits */ + int c_fd =3D open_by_handle_at(FD_NSFS_ROOT, c_handle, O_RDONLY); + if (c_fd < 0) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open child namespace"); + } + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(c_fd); + SKIP(return, "Child failed"); + } + + /* + * With 3-level hierarchy and child active: + * - Child is active (we hold fd) + * - Parent should be active (propagated from child) + * - Grandparent should be active (propagated from parent) + */ + TH_LOG("Testing parent active when child is active"); + int p_fd =3D open_by_handle_at(FD_NSFS_ROOT, p_handle, O_RDONLY); + ASSERT_GE(p_fd, 0); + + TH_LOG("Testing grandparent active when child is active"); + int gp_fd =3D open_by_handle_at(FD_NSFS_ROOT, gp_handle, O_RDONLY); + ASSERT_GE(gp_fd, 0); + + close(c_fd); + close(p_fd); + close(gp_fd); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 64D3F32ED20; Tue, 21 Oct 2025 11:46:19 +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=1761047180; cv=none; b=FzBbWfJLDUnOY2/jeG9B4P5DvDS8m9dVfo2HGecsBYA3aG6cXSB+8WDcDKHtu5oBntsrmrLkPvQd4TE7mYDxwZmmc0fC6UodfVNQRt4GGxaJaB+tdPCTRacMFZ4pNvYu5KPneSSLHbLvtQJMjCiUNdzEZUshqdmlEObsXFERYQs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047180; c=relaxed/simple; bh=I1mnXxN1C6AOW3tyeK+RAqokVAFrl2UVgQuyKj9qhRM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a2yZQjdsEGMt3/OeJNidsOi6Ixn9/AJZ3CEybpBLivpAqHYIBARAkEaoMrksfL0T6KKKaJsx6bQgEkFjO+nYH80jioVg0iReAORdalV7yDVbPnPeBvrtxQ+AJY99U2wWM0n39Z6093MTXoExUsQlJUSlDXTdCw2e5AqTLsSBGEE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F49M6U7K; 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="F49M6U7K" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2FF0C4CEF1; Tue, 21 Oct 2025 11:46:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047179; bh=I1mnXxN1C6AOW3tyeK+RAqokVAFrl2UVgQuyKj9qhRM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=F49M6U7K70BJ/lsXTPa41Jvp3gJgolyvA+ePtLWkR9TZy3+4diLuQ1OnigPsTA+C2 ustM9dCbhZbVM6KRqRcwRriRavqKJg3ReIjdOtvJb7k7tcbKXosoxoxLDIrvI0zYrE GuzcuZUIKt+ETtyqTACpEgt2OXdRW8Tm2pM0X19YL0mmm0jBg+Y62t8cM52R0L7RNL vCDz4/eYUNj0JzA8DsE7mSVSQ2991hv30ge7I6BRXRMnvHHbdF0upG2ZgNwmy2mMny KS+9pDiLEwciowQimws4avldG5ltiRoEbyPNCfYhS0LObqGjm/UIivQIxif70iBK+L tNsbjMoQy+Hbg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:34 +0200 Subject: [PATCH RFC DRAFT 28/50] selftests/namespaces: tenth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-28-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=5731; i=brauner@kernel.org; h=from:subject:message-id; bh=I1mnXxN1C6AOW3tyeK+RAqokVAFrl2UVgQuyKj9qhRM=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zX/2mvTcue3cXVBTLJN1vKmSa0Mou+f/y3+2rwm uKwJytiO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACaylZeR4dW+c4qTz5UcCzp/ 4XbHupd/57XVP205Mb0tclntr41TLtxl+O+/4U/wEt7sYPc+1z+KL7OkIx+zd7R2/JGLs86xqvh 6jRsA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test multiple children sharing same parent. Parent should stay active as long as ANY child is active. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 177 +++++++++++++++++= ++++ 1 file changed, 177 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 87b435b64b45..15d001df981c 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -1176,4 +1176,181 @@ TEST(ns_multilevel_hierarchy) close(gp_fd); } =20 +/* + * Test multiple children sharing same parent. + * Parent should stay active as long as ANY child is active. + */ +TEST(ns_multiple_children_same_parent) +{ + struct file_handle *p_handle, *c1_handle, *c2_handle; + int ret, pipefd[2]; + pid_t pid; + int status; + __u64 p_id, c1_id, c2_id; + char p_buf[sizeof(*p_handle) + MAX_HANDLE_SZ]; + char c1_buf[sizeof(*c1_handle) + MAX_HANDLE_SZ]; + char c2_buf[sizeof(*c2_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + + /* Create parent user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int p_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (p_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(p_fd, NS_GET_ID, &p_id) < 0) { + close(p_fd); + close(pipefd[1]); + exit(1); + } + close(p_fd); + + /* Create first child user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int c1_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (c1_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(c1_fd, NS_GET_ID, &c1_id) < 0) { + close(c1_fd); + close(pipefd[1]); + exit(1); + } + close(c1_fd); + + /* Return to parent user namespace and create second child */ + /* We can't actually do this easily, so let's create a sibling namespace + * by creating a network namespace instead */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + int c2_fd =3D open("/proc/self/ns/net", O_RDONLY); + if (c2_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(c2_fd, NS_GET_ID, &c2_id) < 0) { + close(c2_fd); + close(pipefd[1]); + exit(1); + } + close(c2_fd); + + /* Send all namespace IDs */ + write(pipefd[1], &p_id, sizeof(p_id)); + write(pipefd[1], &c1_id, sizeof(c1_id)); + write(pipefd[1], &c2_id, sizeof(c2_id)); + close(pipefd[1]); + exit(0); + } + + close(pipefd[1]); + + /* Read all three namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &p_id, sizeof(p_id)); + if (ret !=3D sizeof(p_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read parent namespace ID"); + } + + ret =3D read(pipefd[0], &c1_id, sizeof(c1_id)); + if (ret !=3D sizeof(c1_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read first child namespace ID"); + } + + ret =3D read(pipefd[0], &c2_id, sizeof(c2_id)); + close(pipefd[0]); + if (ret !=3D sizeof(c2_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read second child namespace ID"); + } + + /* Construct file handles from namespace IDs */ + p_handle =3D (struct file_handle *)p_buf; + p_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + p_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *p_fh =3D (struct nsfs_file_handle *)p_handle->f_= handle; + p_fh->ns_id =3D p_id; + p_fh->ns_type =3D 0; + p_fh->ns_inum =3D 0; + + c1_handle =3D (struct file_handle *)c1_buf; + c1_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + c1_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *c1_fh =3D (struct nsfs_file_handle *)c1_handle->= f_handle; + c1_fh->ns_id =3D c1_id; + c1_fh->ns_type =3D 0; + c1_fh->ns_inum =3D 0; + + c2_handle =3D (struct file_handle *)c2_buf; + c2_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + c2_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *c2_fh =3D (struct nsfs_file_handle *)c2_handle->= f_handle; + c2_fh->ns_id =3D c2_id; + c2_fh->ns_type =3D 0; + c2_fh->ns_inum =3D 0; + + /* Open both children before process exits */ + int c1_fd =3D open_by_handle_at(FD_NSFS_ROOT, c1_handle, O_RDONLY); + int c2_fd =3D open_by_handle_at(FD_NSFS_ROOT, c2_handle, O_RDONLY); + + if (c1_fd < 0 || c2_fd < 0) { + if (c1_fd >=3D 0) close(c1_fd); + if (c2_fd >=3D 0) close(c2_fd); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open child namespaces"); + } + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(c1_fd); + close(c2_fd); + SKIP(return, "Child failed"); + } + + /* Parent should be active (both children active) */ + TH_LOG("Both children active - parent should be active"); + int p_fd =3D open_by_handle_at(FD_NSFS_ROOT, p_handle, O_RDONLY); + ASSERT_GE(p_fd, 0); + close(p_fd); + + /* Close first child - parent should STILL be active */ + TH_LOG("Closing first child - parent should still be active"); + close(c1_fd); + p_fd =3D open_by_handle_at(FD_NSFS_ROOT, p_handle, O_RDONLY); + ASSERT_GE(p_fd, 0); + close(p_fd); + + /* Close second child - NOW parent should become inactive */ + TH_LOG("Closing second child - parent should become inactive"); + close(c2_fd); + p_fd =3D open_by_handle_at(FD_NSFS_ROOT, p_handle, O_RDONLY); + if (p_fd >=3D 0) { + close(p_fd); + TH_LOG("Warning: Parent still active after all children inactive"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 70C9A334C3B; Tue, 21 Oct 2025 11:46:25 +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=1761047185; cv=none; b=AX3l9iREQZ+3LA71AcLSWgNgKMps7gwZZowMLJ1tVFs6Jpka+3FWrhs5OfII6ewal1saFBIOL9LQ/iTkaXz+XHz1/b7ek6+OEfurUVgROtVs3jsYQ9waOBICmxSH6p4pMci+GvE8sH3ZTpuAKkrezjfainVG4+Yl24kEEfmKxx4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047185; c=relaxed/simple; bh=H4jWaPD3RLb43DWhIT3tk1IDFLr01dcU/60jks3O+nc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m77DLl+rnFNK6i/5yiqzK9l3uXhIvlkkuFHAfSk8A7p+GjKN6B7dnFIOt7JAgGLDp6++T5XxhBK1+lQQYdt6gby2Jm2U0lYAssSPOYfqQr9r1ugd90wxg0CVZqCy4u/wua05EuepsJEoBRTJwbINCBdeifbMQYre7T5sY+6zaqs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gXI7Piad; 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="gXI7Piad" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 409A1C4CEF5; Tue, 21 Oct 2025 11:46:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047185; bh=H4jWaPD3RLb43DWhIT3tk1IDFLr01dcU/60jks3O+nc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gXI7PiadrMkoPHhhut2K7rBcSSSz/LBr8vskKm9bgshZtEiQn3l9TmGeX3YZs2/ke y7jmxxZc7ftLsyUYi7lqxYz82AxI6x3ueytBrTANqwf8SfpQP0mwu9sgqpUExS0hNn of/4JD4u+FxJfk965g1Mg2MOrMjHu85jT4PNs4WIiO3pKeDOQYbA3ih7D9SSV87fes 8cXDsmCMTdXKcAKZv0I4q+BmVGxAe2vPfmhmz6rFPKNkyjAciCViHSJ5ydx4+ukJ8k /kxQ3oxmA2NTMM+iRwEcT4Gs0DIEBUVX0nXGZzvUlsrzlHJHyQka7tfE7q7a9Rx2US fA5Gl7n4itOCw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:35 +0200 Subject: [PATCH RFC DRAFT 29/50] selftests/namespaces: eleventh active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-29-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=5721; i=brauner@kernel.org; h=from:subject:message-id; bh=H4jWaPD3RLb43DWhIT3tk1IDFLr01dcU/60jks3O+nc=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zHHRSikcVhUhmhEv2FaXoSj1SW6IcJJUHVXkss0 +1mzynoKGVhEONikBVTZHFoNwmXW85TsdkoUwNmDisTyBAGLk4BmEjxIkaGZZ2TuFasfigV++fF 3czbPbc/T3uv6iJnNu/lwaONO32EkxgZFl3JqNMy5WVKO8nhHzRLYoJontyaJU6TO3LiTzWc2KT GBQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that different namespace types with same owner all contribute active references to the owning user namespace. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 178 +++++++++++++++++= ++++ 1 file changed, 178 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 15d001df981c..3c2f99b25067 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -1353,4 +1353,182 @@ TEST(ns_multiple_children_same_parent) } } =20 +/* + * Test that different namespace types with same owner all contribute + * active references to the owning user namespace. + */ +TEST(ns_different_types_same_owner) +{ + struct file_handle *u_handle, *n_handle, *ut_handle; + int ret, pipefd[2]; + pid_t pid; + int status; + __u64 u_id, n_id, ut_id; + char u_buf[sizeof(*u_handle) + MAX_HANDLE_SZ]; + char n_buf[sizeof(*n_handle) + MAX_HANDLE_SZ]; + char ut_buf[sizeof(*ut_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + + /* Create user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int u_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (u_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(u_fd, NS_GET_ID, &u_id) < 0) { + close(u_fd); + close(pipefd[1]); + exit(1); + } + close(u_fd); + + /* Create network namespace (owned by user namespace) */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + int n_fd =3D open("/proc/self/ns/net", O_RDONLY); + if (n_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(n_fd, NS_GET_ID, &n_id) < 0) { + close(n_fd); + close(pipefd[1]); + exit(1); + } + close(n_fd); + + /* Create UTS namespace (also owned by user namespace) */ + if (unshare(CLONE_NEWUTS) < 0) { + close(pipefd[1]); + exit(1); + } + + int ut_fd =3D open("/proc/self/ns/uts", O_RDONLY); + if (ut_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(ut_fd, NS_GET_ID, &ut_id) < 0) { + close(ut_fd); + close(pipefd[1]); + exit(1); + } + close(ut_fd); + + /* Send all namespace IDs */ + write(pipefd[1], &u_id, sizeof(u_id)); + write(pipefd[1], &n_id, sizeof(n_id)); + write(pipefd[1], &ut_id, sizeof(ut_id)); + close(pipefd[1]); + exit(0); + } + + close(pipefd[1]); + + /* Read all three namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &u_id, sizeof(u_id)); + if (ret !=3D sizeof(u_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read user namespace ID"); + } + + ret =3D read(pipefd[0], &n_id, sizeof(n_id)); + if (ret !=3D sizeof(n_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read network namespace ID"); + } + + ret =3D read(pipefd[0], &ut_id, sizeof(ut_id)); + close(pipefd[0]); + if (ret !=3D sizeof(ut_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read UTS namespace ID"); + } + + /* Construct file handles from namespace IDs */ + u_handle =3D (struct file_handle *)u_buf; + u_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + u_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *u_fh =3D (struct nsfs_file_handle *)u_handle->f_= handle; + u_fh->ns_id =3D u_id; + u_fh->ns_type =3D 0; + u_fh->ns_inum =3D 0; + + n_handle =3D (struct file_handle *)n_buf; + n_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + n_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *n_fh =3D (struct nsfs_file_handle *)n_handle->f_= handle; + n_fh->ns_id =3D n_id; + n_fh->ns_type =3D 0; + n_fh->ns_inum =3D 0; + + ut_handle =3D (struct file_handle *)ut_buf; + ut_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + ut_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *ut_fh =3D (struct nsfs_file_handle *)ut_handle->= f_handle; + ut_fh->ns_id =3D ut_id; + ut_fh->ns_type =3D 0; + ut_fh->ns_inum =3D 0; + + /* Open both non-user namespaces before process exits */ + int n_fd =3D open_by_handle_at(FD_NSFS_ROOT, n_handle, O_RDONLY); + int ut_fd =3D open_by_handle_at(FD_NSFS_ROOT, ut_handle, O_RDONLY); + + if (n_fd < 0 || ut_fd < 0) { + if (n_fd >=3D 0) close(n_fd); + if (ut_fd >=3D 0) close(ut_fd); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open namespaces"); + } + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(n_fd); + close(ut_fd); + SKIP(return, "Child failed"); + } + + /* + * Both network and UTS namespaces are active. + * User namespace should be active (gets 2 active refs). + */ + TH_LOG("Both net and uts active - user namespace should be active"); + int u_fd =3D open_by_handle_at(FD_NSFS_ROOT, u_handle, O_RDONLY); + ASSERT_GE(u_fd, 0); + close(u_fd); + + /* Close network namespace - user namespace should STILL be active */ + TH_LOG("Closing network ns - user ns should still be active (uts still ac= tive)"); + close(n_fd); + u_fd =3D open_by_handle_at(FD_NSFS_ROOT, u_handle, O_RDONLY); + ASSERT_GE(u_fd, 0); + close(u_fd); + + /* Close UTS namespace - user namespace should become inactive */ + TH_LOG("Closing uts ns - user ns should become inactive"); + close(ut_fd); + u_fd =3D open_by_handle_at(FD_NSFS_ROOT, u_handle, O_RDONLY); + if (u_fd >=3D 0) { + close(u_fd); + TH_LOG("Warning: User namespace still active after all owned namespaces = inactive"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 9E7912F3612; Tue, 21 Oct 2025 11:46:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047190; cv=none; b=YtJ0RM93EVdZdZcP7XrQmVPJI66zxISHzOL8sJwA3VU/u/T1+15Wb0gvPqbmbkLuAyrIsNsk3H1jjEfmnaZoC5UCql7n5VXehtk9dl40STZPXWnXRG3DWpnEAcp21qPoMuxFvVL74p7U/i+LUJIG0co6JlUXXgl6XXpxqHb3z0Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047190; c=relaxed/simple; bh=YF6LlFsedC0FcPBAnpIIRxVh8Wv/PCUOI1UuPciGHmg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W+20MMGii17wD9GX26ok5iW18jVt28RWm0lpexLJmytAftS91vEOBQ6mEYaq9X0JN8Po43n9lJhwrWAoSEQK+XayYvm+4CCxezSr6wT4SaiM3/ZX6qHH34+h5R03tAYhapar9+ktdGbBVhzzFQu1DaFHLLQt5GUEytwsgxmoDJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gvuQdzP3; 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="gvuQdzP3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6D0A9C4CEF1; Tue, 21 Oct 2025 11:46:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047190; bh=YF6LlFsedC0FcPBAnpIIRxVh8Wv/PCUOI1UuPciGHmg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gvuQdzP3O6onZGZ2uks/a7670YhGCYn2Ww3qADjVidHUTfcmhRRJnRoTQkPLOhfZP L1XplKSubRAWwR5ACHadA5YFslWHzet99LxfXNJFYi7mlawfGSJVSWKPf9fNp3EX8E 0ZigP8mynC73RDuU51Y0cAoCasxuQEzfwjkCq/q5RIN7HtiPGw5fSryz85d7iyneel TEY64C3AOCzra6No2XqIZBDLbeX1ncAYK1hsVpEYKsfLv0LquGhuUPJRVdq+lim6wQ 2cxGY0RL/WLoIBfUod9sQTJDlVXbMUmTDM+OnT//wq47ianRfl07TyFYyBKYn8KH38 mpoblDgWLVEHg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:36 +0200 Subject: [PATCH RFC DRAFT 30/50] selftests/namespaces: twelth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-30-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=6173; i=brauner@kernel.org; h=from:subject:message-id; bh=YF6LlFsedC0FcPBAnpIIRxVh8Wv/PCUOI1UuPciGHmg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3x38YJ3rXvRxSU3L9XL6GW6zvxb8MTLP9GQc228S UxBm6BNRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwESsPjEyfOB4o+/+ev7fNUFe v+4yeWxfnxHvfGLp5s4U2fDnl8rj8hkZrpQEXWuaqGr3YKHCGY7vjIf/ikmI3LigrX8jvOB69aY FfAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test hierarchical propagation with deep namespace hierarchy. Create: init_user_ns -> user_A -> user_B -> net_ns When net_ns is active, both user_A and user_B should be active. This verifies the conditional recursion in __ns_ref_active_put() works. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 182 +++++++++++++++++= ++++ 1 file changed, 182 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 3c2f99b25067..63cc88fe5cc1 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -1531,4 +1531,186 @@ TEST(ns_different_types_same_owner) } } =20 +/* + * Test hierarchical propagation with deep namespace hierarchy. + * Create: init_user_ns -> user_A -> user_B -> net_ns + * When net_ns is active, both user_A and user_B should be active. + * This verifies the conditional recursion in __ns_ref_active_put() works. + */ +TEST(ns_deep_hierarchy_propagation) +{ + struct file_handle *ua_handle, *ub_handle, *net_handle; + int ret, pipefd[2]; + pid_t pid; + int status; + __u64 ua_id, ub_id, net_id; + char ua_buf[sizeof(*ua_handle) + MAX_HANDLE_SZ]; + char ub_buf[sizeof(*ub_handle) + MAX_HANDLE_SZ]; + char net_buf[sizeof(*net_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + + /* Create user_A -> user_B -> net hierarchy */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int ua_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (ua_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(ua_fd, NS_GET_ID, &ua_id) < 0) { + close(ua_fd); + close(pipefd[1]); + exit(1); + } + close(ua_fd); + + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int ub_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (ub_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(ub_fd, NS_GET_ID, &ub_id) < 0) { + close(ub_fd); + close(pipefd[1]); + exit(1); + } + close(ub_fd); + + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + int net_fd =3D open("/proc/self/ns/net", O_RDONLY); + if (net_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(net_fd, NS_GET_ID, &net_id) < 0) { + close(net_fd); + close(pipefd[1]); + exit(1); + } + close(net_fd); + + /* Send all three namespace IDs */ + write(pipefd[1], &ua_id, sizeof(ua_id)); + write(pipefd[1], &ub_id, sizeof(ub_id)); + write(pipefd[1], &net_id, sizeof(net_id)); + close(pipefd[1]); + exit(0); + } + + close(pipefd[1]); + + /* Read all three namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &ua_id, sizeof(ua_id)); + if (ret !=3D sizeof(ua_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read user_A namespace ID"); + } + + ret =3D read(pipefd[0], &ub_id, sizeof(ub_id)); + if (ret !=3D sizeof(ub_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read user_B namespace ID"); + } + + ret =3D read(pipefd[0], &net_id, sizeof(net_id)); + close(pipefd[0]); + if (ret !=3D sizeof(net_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read network namespace ID"); + } + + /* Construct file handles from namespace IDs */ + ua_handle =3D (struct file_handle *)ua_buf; + ua_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + ua_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *ua_fh =3D (struct nsfs_file_handle *)ua_handle->= f_handle; + ua_fh->ns_id =3D ua_id; + ua_fh->ns_type =3D 0; + ua_fh->ns_inum =3D 0; + + ub_handle =3D (struct file_handle *)ub_buf; + ub_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + ub_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *ub_fh =3D (struct nsfs_file_handle *)ub_handle->= f_handle; + ub_fh->ns_id =3D ub_id; + ub_fh->ns_type =3D 0; + ub_fh->ns_inum =3D 0; + + net_handle =3D (struct file_handle *)net_buf; + net_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + net_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *net_fh =3D (struct nsfs_file_handle *)net_handle= ->f_handle; + net_fh->ns_id =3D net_id; + net_fh->ns_type =3D 0; + net_fh->ns_inum =3D 0; + + /* Open net_ns before child exits to keep it active */ + int net_fd =3D open_by_handle_at(FD_NSFS_ROOT, net_handle, O_RDONLY); + if (net_fd < 0) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open network namespace"); + } + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(net_fd); + SKIP(return, "Child failed"); + } + + /* With net_ns active, both user_A and user_B should be active */ + TH_LOG("Testing user_B active (net_ns active causes propagation)"); + int ub_fd =3D open_by_handle_at(FD_NSFS_ROOT, ub_handle, O_RDONLY); + ASSERT_GE(ub_fd, 0); + + TH_LOG("Testing user_A active (propagated through user_B)"); + int ua_fd =3D open_by_handle_at(FD_NSFS_ROOT, ua_handle, O_RDONLY); + ASSERT_GE(ua_fd, 0); + + /* Close net_ns - user_B should stay active (we hold direct ref) */ + TH_LOG("Closing net_ns, user_B should remain active (direct ref held)"); + close(net_fd); + int ub_fd2 =3D open_by_handle_at(FD_NSFS_ROOT, ub_handle, O_RDONLY); + ASSERT_GE(ub_fd2, 0); + close(ub_fd2); + + /* Close user_B - user_A should stay active (we hold direct ref) */ + TH_LOG("Closing user_B, user_A should remain active (direct ref held)"); + close(ub_fd); + int ua_fd2 =3D open_by_handle_at(FD_NSFS_ROOT, ua_handle, O_RDONLY); + ASSERT_GE(ua_fd2, 0); + close(ua_fd2); + + /* Close user_A - everything should become inactive */ + TH_LOG("Closing user_A, all should become inactive"); + close(ua_fd); + + /* All should now be inactive */ + ua_fd =3D open_by_handle_at(FD_NSFS_ROOT, ua_handle, O_RDONLY); + if (ua_fd >=3D 0) { + close(ua_fd); + TH_LOG("Warning: user_A still active"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 B61AE336EC3; Tue, 21 Oct 2025 11:46: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=1761047195; cv=none; b=OX+K6clmC+hHG5Qn4GURu29daGhHs1O+bVAZVVsM32OFWg1dIJbss/W9Zty93Bs7yP1BiB+IIlLfbIHRXivZuGyvbWfc8OwJc02MszUPea8I3KqNGO9E9Ef8VbYKcRjDXVqRXw6pHKnzHOQUiH/eQTX+iZIF7yll6aVL+MzqSIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047195; c=relaxed/simple; bh=vsrRT4zqgD+nKit9MH7tv6SchshKJx7ljsx1OLBVRIQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C1lc0BAro4JE4aPK5URuKM85qqq+xBNauw0X5z6/U4YQNdcLJt6AnUVmY+fb5YcGVPwCppTBYN43nwXOdXDuclAAjoRmaK8M4Xo/pp4rXx8AJKe3hnWLwluqVRkbWBNEpwfjA+x3za62f1JTodMLX3P+zYHtPvQmjGMWLFL8i8o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PDH+S8FP; 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="PDH+S8FP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC478C4CEF5; Tue, 21 Oct 2025 11:46:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047195; bh=vsrRT4zqgD+nKit9MH7tv6SchshKJx7ljsx1OLBVRIQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PDH+S8FPzgBF9Rwe2WwCrGlUq9wjqX0XhR+nLD8+SLeZJcCJ6R9UZ4LJVXGWPtel7 U9QqLl+JAN5qEyVfjOiQNu6ACmGoso3DQg/QBBVoJl+A4ib0lAepjfzkbcrDMUmNZb bbrwHGYNSEFj4uIz+3RryHBV8lp8abHjAGG7fFP0XKLPKV5MMngltjSOWEX9piO+IX aT6UZRnyDkuqPeL2Lsjt6N+jfKvwHI6YqBDYUncLuP+DBz1FV3XWLPnpuls0b3ajKn KGq91WYhh2xxCm3HpOl6A2E13HU+j+RbDUiQJaDzXVqNGVDWmRiNlPw38/x9v+tgBg Xyqeb2CHejNiQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:37 +0200 Subject: [PATCH RFC DRAFT 31/50] selftests/namespaces: thirteenth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-31-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=6611; i=brauner@kernel.org; h=from:subject:message-id; bh=vsrRT4zqgD+nKit9MH7tv6SchshKJx7ljsx1OLBVRIQ=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xX0/OjcbfbootK/Z86rb9tytUJ1r7X++Zo+40e7 g9ePX7eHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABM5G87IcPPwidVnK+dmhHWm BMzjMQ+z2PL8d5WoplXwCg6nu/0sxxn+2QlcE2QUXLzDRLc/8fMbIf/3q/Yf6pS0O9E9cQl36R8 5JgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that parent stays active as long as ANY child is active. Create parent user namespace with two child net namespaces. Parent should remain active until BOTH children are inactive. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 201 +++++++++++++++++= ++++ 1 file changed, 201 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 63cc88fe5cc1..4c077223b05c 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -1713,4 +1713,205 @@ TEST(ns_deep_hierarchy_propagation) } } =20 +/* + * Test that parent stays active as long as ANY child is active. + * Create parent user namespace with two child net namespaces. + * Parent should remain active until BOTH children are inactive. + */ +TEST(ns_parent_multiple_children_refcount) +{ + struct file_handle *parent_handle, *net1_handle, *net2_handle; + int ret, pipefd[2], syncpipe[2]; + pid_t pid; + int status; + __u64 p_id, n1_id, n2_id; + char p_buf[sizeof(*parent_handle) + MAX_HANDLE_SZ]; + char n1_buf[sizeof(*net1_handle) + MAX_HANDLE_SZ]; + char n2_buf[sizeof(*net2_handle) + MAX_HANDLE_SZ]; + char sync_byte; + + ASSERT_EQ(pipe(pipefd), 0); + ASSERT_EQ(pipe(syncpipe), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + close(syncpipe[1]); + + /* Create parent user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int p_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (p_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(p_fd, NS_GET_ID, &p_id) < 0) { + close(p_fd); + close(pipefd[1]); + exit(1); + } + close(p_fd); + + /* Create first network namespace */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + + int n1_fd =3D open("/proc/self/ns/net", O_RDONLY); + if (n1_fd < 0) { + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + if (ioctl(n1_fd, NS_GET_ID, &n1_id) < 0) { + close(n1_fd); + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + /* Keep n1_fd open so first namespace stays active */ + + /* Create second network namespace */ + if (unshare(CLONE_NEWNET) < 0) { + close(n1_fd); + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + + int n2_fd =3D open("/proc/self/ns/net", O_RDONLY); + if (n2_fd < 0) { + close(n1_fd); + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + if (ioctl(n2_fd, NS_GET_ID, &n2_id) < 0) { + close(n1_fd); + close(n2_fd); + close(pipefd[1]); + close(syncpipe[0]); + exit(1); + } + /* Keep both n1_fd and n2_fd open */ + + /* Send all namespace IDs */ + write(pipefd[1], &p_id, sizeof(p_id)); + write(pipefd[1], &n1_id, sizeof(n1_id)); + write(pipefd[1], &n2_id, sizeof(n2_id)); + close(pipefd[1]); + + /* Wait for parent to signal before exiting */ + read(syncpipe[0], &sync_byte, 1); + close(syncpipe[0]); + exit(0); + } + + close(pipefd[1]); + close(syncpipe[0]); + + /* Read all three namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &p_id, sizeof(p_id)); + if (ret !=3D sizeof(p_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read parent namespace ID"); + } + + ret =3D read(pipefd[0], &n1_id, sizeof(n1_id)); + if (ret !=3D sizeof(n1_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read first network namespace ID"); + } + + ret =3D read(pipefd[0], &n2_id, sizeof(n2_id)); + close(pipefd[0]); + if (ret !=3D sizeof(n2_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read second network namespace ID"); + } + + /* Construct file handles from namespace IDs */ + parent_handle =3D (struct file_handle *)p_buf; + parent_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + parent_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *p_fh =3D (struct nsfs_file_handle *)parent_handl= e->f_handle; + p_fh->ns_id =3D p_id; + p_fh->ns_type =3D 0; + p_fh->ns_inum =3D 0; + + net1_handle =3D (struct file_handle *)n1_buf; + net1_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + net1_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *n1_fh =3D (struct nsfs_file_handle *)net1_handle= ->f_handle; + n1_fh->ns_id =3D n1_id; + n1_fh->ns_type =3D 0; + n1_fh->ns_inum =3D 0; + + net2_handle =3D (struct file_handle *)n2_buf; + net2_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + net2_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *n2_fh =3D (struct nsfs_file_handle *)net2_handle= ->f_handle; + n2_fh->ns_id =3D n2_id; + n2_fh->ns_type =3D 0; + n2_fh->ns_inum =3D 0; + + /* Open both net namespaces while child is still alive */ + int n1_fd =3D open_by_handle_at(FD_NSFS_ROOT, net1_handle, O_RDONLY); + int n2_fd =3D open_by_handle_at(FD_NSFS_ROOT, net2_handle, O_RDONLY); + if (n1_fd < 0 || n2_fd < 0) { + if (n1_fd >=3D 0) close(n1_fd); + if (n2_fd >=3D 0) close(n2_fd); + sync_byte =3D 'G'; + write(syncpipe[1], &sync_byte, 1); + close(syncpipe[1]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open net namespaces"); + } + + /* Signal child that we have opened the namespaces */ + sync_byte =3D 'G'; + write(syncpipe[1], &sync_byte, 1); + close(syncpipe[1]); + + /* Wait for child to exit */ + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(n1_fd); + close(n2_fd); + SKIP(return, "Child failed"); + } + + /* Parent should be active (has 2 active children) */ + TH_LOG("Both net namespaces active - parent should be active"); + int p_fd =3D open_by_handle_at(FD_NSFS_ROOT, parent_handle, O_RDONLY); + ASSERT_GE(p_fd, 0); + close(p_fd); + + /* Close first net namespace - parent should STILL be active */ + TH_LOG("Closing first net ns - parent should still be active"); + close(n1_fd); + p_fd =3D open_by_handle_at(FD_NSFS_ROOT, parent_handle, O_RDONLY); + ASSERT_GE(p_fd, 0); + close(p_fd); + + /* Close second net namespace - parent should become inactive */ + TH_LOG("Closing second net ns - parent should become inactive"); + close(n2_fd); + p_fd =3D open_by_handle_at(FD_NSFS_ROOT, parent_handle, O_RDONLY); + if (p_fd >=3D 0) { + close(p_fd); + TH_LOG("Warning: Parent still active after all children inactive"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 C708C34677C; Tue, 21 Oct 2025 11:46:40 +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=1761047200; cv=none; b=nYFZzTpBjEgQMcybXT5PIjtg8PK/RArlnJgWI04+VobFq3Z6d7KuR6HYSkbQWdpuYi9bnxejWOrgUnpV4ginGjUjSQWerox25XE2ifwVkSdMB7U/ZFyAc/NxBJVVN4rMHAzeAB/HltpVKbQoR3D0AvU9G3C2v1nQQKF0RbbtKr0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047200; c=relaxed/simple; bh=fdHj1hsijB+BXri97N5cswYO4dlb02Ygb6q9aUmDKdA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WANbBim0GYXMkEReOMA9YjBTtgx/GVNQ9imunjYruMzcC/OEDCYvzBLYmx3e6q8x/2FPdaO12FQ0skYfoR22HDn2WG2FtySxlGkpleKqStJPp3FpHyDTIyVvYikoCGSRTcsdQZChYzfcE0UmaMucsIupd8rdA6ew3IhSq+XYBYM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oi19gwlJ; 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="oi19gwlJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7E4CC4CEFD; Tue, 21 Oct 2025 11:46:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047200; bh=fdHj1hsijB+BXri97N5cswYO4dlb02Ygb6q9aUmDKdA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oi19gwlJDUVhq5kUDd2QIp9gj8Ozagb2CCM0FG9NP6s6XVp2mk7P89DDN0eAWUBtc LjvB9vnrVgqud9FLgUISHHaU2rIUAJEiTwgBpnrpqlvooJbOotEim4VMSgFID9B8oj gaiCiGKswkoQ1VU01OjYSokTpG9NZzTetraQpfC6A8NpLfa/4pJgRc9z8p5g6ik/hi fWqVaYE7I38MjhI2aAvvZZ95ftK7khleYq0phGL0ZmqYC+PETek/NFLuUrLdWLl2h9 NeHsVOHdggxVjrSGP5UEpKHo8miN7qBob8e7NODs/c0/aWd8KUB12u1EcFfq13UUa1 3/P8cR5gMdMHA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:38 +0200 Subject: [PATCH RFC DRAFT 32/50] selftests/namespaces: fourteenth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-32-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=4527; i=brauner@kernel.org; h=from:subject:message-id; bh=fdHj1hsijB+BXri97N5cswYO4dlb02Ygb6q9aUmDKdA=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zHnPpjlhT3rxaDCDvFE8fW83ydeO3TmYfMnGU+r 5Omnlzk21HKwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjCRZAOG/yHO/lwv6o7PNvTm D3n7wiQpo3rZ3alBD+eq2KeI9XrkZTAyPDz9i9PNxqCLaYOW7b77z7hszvdIRSt1FgSztcmUFEZ yAgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that user namespace as a child also propagates correctly. Create user_A -> user_B, verify when user_B is active that user_A is also active. This is different from non-user namespace children. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 138 +++++++++++++++++= ++++ 1 file changed, 138 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 4c077223b05c..1eb4dc07e924 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -1914,4 +1914,142 @@ TEST(ns_parent_multiple_children_refcount) } } =20 +/* + * Test that user namespace as a child also propagates correctly. + * Create user_A -> user_B, verify when user_B is active that user_A + * is also active. This is different from non-user namespace children. + */ +TEST(ns_userns_child_propagation) +{ + struct file_handle *ua_handle, *ub_handle; + int ret, pipefd[2]; + pid_t pid; + int status; + __u64 ua_id, ub_id; + char ua_buf[sizeof(*ua_handle) + MAX_HANDLE_SZ]; + char ub_buf[sizeof(*ub_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + + /* Create user_A */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int ua_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (ua_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(ua_fd, NS_GET_ID, &ua_id) < 0) { + close(ua_fd); + close(pipefd[1]); + exit(1); + } + close(ua_fd); + + /* Create user_B (child of user_A) */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int ub_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (ub_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(ub_fd, NS_GET_ID, &ub_id) < 0) { + close(ub_fd); + close(pipefd[1]); + exit(1); + } + close(ub_fd); + + /* Send both namespace IDs */ + write(pipefd[1], &ua_id, sizeof(ua_id)); + write(pipefd[1], &ub_id, sizeof(ub_id)); + close(pipefd[1]); + exit(0); + } + + close(pipefd[1]); + + /* Read both namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &ua_id, sizeof(ua_id)); + if (ret !=3D sizeof(ua_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read user_A namespace ID"); + } + + ret =3D read(pipefd[0], &ub_id, sizeof(ub_id)); + close(pipefd[0]); + if (ret !=3D sizeof(ub_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read user_B namespace ID"); + } + + /* Construct file handles from namespace IDs */ + ua_handle =3D (struct file_handle *)ua_buf; + ua_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + ua_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *ua_fh =3D (struct nsfs_file_handle *)ua_handle->= f_handle; + ua_fh->ns_id =3D ua_id; + ua_fh->ns_type =3D 0; + ua_fh->ns_inum =3D 0; + + ub_handle =3D (struct file_handle *)ub_buf; + ub_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + ub_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *ub_fh =3D (struct nsfs_file_handle *)ub_handle->= f_handle; + ub_fh->ns_id =3D ub_id; + ub_fh->ns_type =3D 0; + ub_fh->ns_inum =3D 0; + + /* Open user_B before child exits */ + int ub_fd =3D open_by_handle_at(FD_NSFS_ROOT, ub_handle, O_RDONLY); + if (ub_fd < 0) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open user_B"); + } + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(ub_fd); + SKIP(return, "Child failed"); + } + + /* With user_B active, user_A should also be active */ + TH_LOG("Testing user_A active when child user_B is active"); + int ua_fd =3D open_by_handle_at(FD_NSFS_ROOT, ua_handle, O_RDONLY); + ASSERT_GE(ua_fd, 0); + + /* Close user_B */ + TH_LOG("Closing user_B"); + close(ub_fd); + + /* user_A should remain active (we hold direct ref) */ + int ua_fd2 =3D open_by_handle_at(FD_NSFS_ROOT, ua_handle, O_RDONLY); + ASSERT_GE(ua_fd2, 0); + close(ua_fd2); + + /* Close user_A - should become inactive */ + TH_LOG("Closing user_A - should become inactive"); + close(ua_fd); + + ua_fd =3D open_by_handle_at(FD_NSFS_ROOT, ua_handle, O_RDONLY); + if (ua_fd >=3D 0) { + close(ua_fd); + TH_LOG("Warning: user_A still active"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 B14C032F76F; Tue, 21 Oct 2025 11:46:45 +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=1761047205; cv=none; b=o81T0F+6CFUJr2JK9ibTQTxCPRWWpn3vnyMfT7wbpTGdCsMUIvBjwa7NEksbJg5bqbdAuTRJcaXn1ABwAfyWOTFL9BD/+PR8N7Hez2FKMRjb/2QDJ7Xw2XeRpaBR9Ew2NrcXC9mPWIgtWmjz/Mgo6PJo2MRjXAH+0+wfF+0b+OU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047205; c=relaxed/simple; bh=elfrUH3DfTC46qvkbhHf42IekzBPgA/k+oqQpuntS3A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RLRdPocwcAbN0cv7v+7VS8kvYxGd1AT8dsJtkYchmQxUhZXQdnHPU/lvj0PqkKj24Ki0gzqs5oVCONHh7X0M5oyxZRzW997DlyoB0p1kUCly0k6zCN4ELl1EM1yMpOyWKLV6o7MZYt9ehkmiEpauzPNjfL3IyhXUcLmUlKf6vuY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K96nrx9i; 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="K96nrx9i" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C3332C4CEF1; Tue, 21 Oct 2025 11:46:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047205; bh=elfrUH3DfTC46qvkbhHf42IekzBPgA/k+oqQpuntS3A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=K96nrx9iRRnUGTehuxNYsZGfuis5YRpdPUhmvFazK5iOROI0WTD+z0SMfd4zXY/YC GdQeBKbn7arTSykFAo18wlpv+lCNwnnd8EpiUTyFCGz0c9hB7cHUqw9K/rCoxb9/Dt YeMzQwPDRJLlMtmvpoM3xbvd/tFesEcXsTCKoZiQtNZRSdHSEBFUVGkHsKPnFypqWp 9kHZRXIb4h55nopOZuXfbSGj62mqCKVIB5ym4LDJxmQ4de5r//c8LwG94v1+UDUmK2 6DEcnqInL2OTeYuzMmJiwZGdLeWGkaQZRj4g2dk+vvG0d7wSFGuFfsQkuKefQ/7llc Bp/6NbkhsR53Q== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:39 +0200 Subject: [PATCH RFC DRAFT 33/50] selftests/namespaces: fifteenth active reference count tests 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: <20251021-work-namespace-nstree-listns-v1-33-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=5425; i=brauner@kernel.org; h=from:subject:message-id; bh=elfrUH3DfTC46qvkbhHf42IekzBPgA/k+oqQpuntS3A=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3z3KeqKn7CHwL7UJ9UxTOqmewvk7gt9vSZ1ftF33 bPL1G/M7ShlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZiI805Ghvnat++UHHXm//hD y0x7dr1hX2v5ai8m5lh9UWf+VzdkXjAyPC4Jmeq3v37VIv8zi87tnZGZnPqlwaXNaml25wNDy63 qrAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test different namespace types (net, uts, ipc) all contributing active references to the same owning user namespace. Signed-off-by: Christian Brauner --- .../selftests/namespaces/ns_active_ref_test.c | 171 +++++++++++++++++= ++++ 1 file changed, 171 insertions(+) diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tool= s/testing/selftests/namespaces/ns_active_ref_test.c index 1eb4dc07e924..8b1553be6881 100644 --- a/tools/testing/selftests/namespaces/ns_active_ref_test.c +++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c @@ -2052,4 +2052,175 @@ TEST(ns_userns_child_propagation) } } =20 +/* + * Test different namespace types (net, uts, ipc) all contributing + * active references to the same owning user namespace. + */ +TEST(ns_mixed_types_same_owner) +{ + struct file_handle *user_handle, *net_handle, *uts_handle; + int ret, pipefd[2]; + pid_t pid; + int status; + __u64 u_id, n_id, ut_id; + char u_buf[sizeof(*user_handle) + MAX_HANDLE_SZ]; + char n_buf[sizeof(*net_handle) + MAX_HANDLE_SZ]; + char ut_buf[sizeof(*uts_handle) + MAX_HANDLE_SZ]; + + ASSERT_EQ(pipe(pipefd), 0); + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + close(pipefd[0]); + + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + int u_fd =3D open("/proc/self/ns/user", O_RDONLY); + if (u_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(u_fd, NS_GET_ID, &u_id) < 0) { + close(u_fd); + close(pipefd[1]); + exit(1); + } + close(u_fd); + + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + int n_fd =3D open("/proc/self/ns/net", O_RDONLY); + if (n_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(n_fd, NS_GET_ID, &n_id) < 0) { + close(n_fd); + close(pipefd[1]); + exit(1); + } + close(n_fd); + + if (unshare(CLONE_NEWUTS) < 0) { + close(pipefd[1]); + exit(1); + } + + int ut_fd =3D open("/proc/self/ns/uts", O_RDONLY); + if (ut_fd < 0) { + close(pipefd[1]); + exit(1); + } + if (ioctl(ut_fd, NS_GET_ID, &ut_id) < 0) { + close(ut_fd); + close(pipefd[1]); + exit(1); + } + close(ut_fd); + + /* Send all namespace IDs */ + write(pipefd[1], &u_id, sizeof(u_id)); + write(pipefd[1], &n_id, sizeof(n_id)); + write(pipefd[1], &ut_id, sizeof(ut_id)); + close(pipefd[1]); + exit(0); + } + + close(pipefd[1]); + + /* Read all three namespace IDs - fixed size, no parsing needed */ + ret =3D read(pipefd[0], &u_id, sizeof(u_id)); + if (ret !=3D sizeof(u_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read user namespace ID"); + } + + ret =3D read(pipefd[0], &n_id, sizeof(n_id)); + if (ret !=3D sizeof(n_id)) { + close(pipefd[0]); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read network namespace ID"); + } + + ret =3D read(pipefd[0], &ut_id, sizeof(ut_id)); + close(pipefd[0]); + if (ret !=3D sizeof(ut_id)) { + waitpid(pid, NULL, 0); + SKIP(return, "Failed to read UTS namespace ID"); + } + + /* Construct file handles from namespace IDs */ + user_handle =3D (struct file_handle *)u_buf; + user_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + user_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *u_fh =3D (struct nsfs_file_handle *)user_handle-= >f_handle; + u_fh->ns_id =3D u_id; + u_fh->ns_type =3D 0; + u_fh->ns_inum =3D 0; + + net_handle =3D (struct file_handle *)n_buf; + net_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + net_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *n_fh =3D (struct nsfs_file_handle *)net_handle->= f_handle; + n_fh->ns_id =3D n_id; + n_fh->ns_type =3D 0; + n_fh->ns_inum =3D 0; + + uts_handle =3D (struct file_handle *)ut_buf; + uts_handle->handle_bytes =3D sizeof(struct nsfs_file_handle); + uts_handle->handle_type =3D FILEID_NSFS; + struct nsfs_file_handle *ut_fh =3D (struct nsfs_file_handle *)uts_handle-= >f_handle; + ut_fh->ns_id =3D ut_id; + ut_fh->ns_type =3D 0; + ut_fh->ns_inum =3D 0; + + /* Open both non-user namespaces */ + int n_fd =3D open_by_handle_at(FD_NSFS_ROOT, net_handle, O_RDONLY); + int ut_fd =3D open_by_handle_at(FD_NSFS_ROOT, uts_handle, O_RDONLY); + if (n_fd < 0 || ut_fd < 0) { + if (n_fd >=3D 0) close(n_fd); + if (ut_fd >=3D 0) close(ut_fd); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to open namespaces"); + } + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + if (WEXITSTATUS(status) !=3D 0) { + close(n_fd); + close(ut_fd); + SKIP(return, "Child failed"); + } + + /* User namespace should be active (2 active children) */ + TH_LOG("Both net and uts active - user ns should be active"); + int u_fd =3D open_by_handle_at(FD_NSFS_ROOT, user_handle, O_RDONLY); + ASSERT_GE(u_fd, 0); + close(u_fd); + + /* Close net - user ns should STILL be active (uts still active) */ + TH_LOG("Closing net - user ns should still be active"); + close(n_fd); + u_fd =3D open_by_handle_at(FD_NSFS_ROOT, user_handle, O_RDONLY); + ASSERT_GE(u_fd, 0); + close(u_fd); + + /* Close uts - user ns should become inactive */ + TH_LOG("Closing uts - user ns should become inactive"); + close(ut_fd); + u_fd =3D open_by_handle_at(FD_NSFS_ROOT, user_handle, O_RDONLY); + if (u_fd >=3D 0) { + close(u_fd); + TH_LOG("Warning: User ns still active"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 4C95132F76F; Tue, 21 Oct 2025 11:46:50 +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=1761047211; cv=none; b=R3c5ZNRI6GE+Y0FMJhIdIN4cUnT7WLFHD6ZQvLik5FeYjbGEm23SHBuf87SgcAJGmxTpySeUIiK5izSLgo2hh7JXlBFAV/A879rW1dCCltS03VppCNpVDc3Mi9W9RBM0QV4C3LmJAVOcVMb5DR98c+29M5uq9iMCai+Kd6OPXvQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047211; c=relaxed/simple; bh=WU3OpDiHSBOB5eonlPoaP8MJGbmszqupW5dQlbeASiQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YXywNXrYRDfw5Y+gX0MfcAhYSIdQozGgT2XBzItlzSlvupEuBELi3Zm7PtcODdCJ9lzEvZyz78A15IMgntAdnNmHOPzaPl2r+s74yslcwcHDX6wd0GNuXEk+H8qZtBprTiPy/e6ywmnOUjxdeFzLVPdTEqsnB06Gz3AjRRu5zBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R+fux4gZ; 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="R+fux4gZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0C19CC4CEF1; Tue, 21 Oct 2025 11:46:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047210; bh=WU3OpDiHSBOB5eonlPoaP8MJGbmszqupW5dQlbeASiQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=R+fux4gZGrE0eeTJwEv601jLFgtJ5sHhYyPEXEZ52Nsx7bKXM95tGjSI75ndyNtl8 hjx1gNLTcONiC8gGPSoNrwLK8ArglmET+G3JonAOc2p5qoECjyAlJqwbJgG0m0DIdH sT2ui+JJ+fMuZwdQPMPW6t6k3jYUCuJsM5tsocI72ENXrOhLEZ+lHVL4pWYMps71ip r+xQmnpEclJs5QVBmAlzIJrPnF85WGImN3pNZV76rt80YThtQ0YrhQDYH0IDJLW7+N pPMBn+VEcRlzA9qKjk7gFWqSmKYcMUh4fflPmLBCQ7Xls14CuAio9lrdJz1zExSJQu f2Mj0GrQUrTRg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:40 +0200 Subject: [PATCH RFC DRAFT 34/50] selftests/namespaces: add listns() wrapper 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: <20251021-work-namespace-nstree-listns-v1-34-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1405; i=brauner@kernel.org; h=from:subject:message-id; bh=WU3OpDiHSBOB5eonlPoaP8MJGbmszqupW5dQlbeASiQ=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3wnulyI9cu5nVPmeqhfyj6d8v7bdKmc2XLyO3MmV C89v2FuRUcpC4MYF4OsmCKLQ7tJuNxynorNRpkaMHNYmUCGMHBxCsBE9p9n+Cvxynb7lp2qlw1a uGb+jJmsmnLqv/NBu8P7ps2Rm37JbU8Lwz/jnyz/nVhVlYQTkz6FfOIOK66b5SPKHZLT8XNuYuG Vw7wA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a wrapper for the listns() system call. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/wrappers.h | 35 +++++++++++++++++++++++= ++++ 1 file changed, 35 insertions(+) diff --git a/tools/testing/selftests/namespaces/wrappers.h b/tools/testing/= selftests/namespaces/wrappers.h new file mode 100644 index 000000000000..9741a64a5b1d --- /dev/null +++ b/tools/testing/selftests/namespaces/wrappers.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include + +#ifndef __SELFTESTS_NAMESPACES_WRAPPERS_H__ +#define __SELFTESTS_NAMESPACES_WRAPPERS_H__ + +#ifndef __NR_listns + #if defined __alpha__ + #define __NR_listns 580 + #elif defined _MIPS_SIM + #if _MIPS_SIM =3D=3D _MIPS_SIM_ABI32 /* o32 */ + #define __NR_listns 4470 + #endif + #if _MIPS_SIM =3D=3D _MIPS_SIM_NABI32 /* n32 */ + #define __NR_listns 6470 + #endif + #if _MIPS_SIM =3D=3D _MIPS_SIM_ABI64 /* n64 */ + #define __NR_listns 5470 + #endif + #else + #define __NR_listns 470 + #endif +#endif + +static inline int sys_listns(const struct ns_id_req *req, __u64 *ns_ids, + size_t nr_ns_ids, unsigned int flags) +{ + return syscall(__NR_listns, req, ns_ids, nr_ns_ids, flags); +} + +#endif /* __SELFTESTS_NAMESPACES_WRAPPERS_H__ */ --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 0FDD62F260B; Tue, 21 Oct 2025 11:46:56 +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=1761047216; cv=none; b=OMQL3NZxHXftl6Ym8mnWCN9w1aFlKQ080FMHiRN5R+zjeM/XkktLR4GUffxFLTZqope+oI4nkugefzrbVl2jRLjIhJWCiLL9mH1AkV5mphc45efBL4c7ZkpQ+af9YO2G99tzj6n5+odOghSKMmH3jcvHdDtgGR50vxP1BS9lz3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047216; c=relaxed/simple; bh=NAhtGlBVfCqrlTfWbGN1zDMklE1n7EKY3e8ekT2vQ0Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SZZhTDutU7Qt8Jcfy3EpUoebdGnFetYkyyiE5jSta+LnHZ23pPcCzoXaKRUgzkKGOvrF2H/9XXQfzRHgM0upZnt91kiSdxMRVnXkOYytQ4azR3oPPjv/EfmwicXRWQXHuvoRGufKvhVlyOkuMLhpEgURI7ksDqjZ7nV6DcAcMQo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tWyts7lh; 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="tWyts7lh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44049C4CEF5; Tue, 21 Oct 2025 11:46:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047215; bh=NAhtGlBVfCqrlTfWbGN1zDMklE1n7EKY3e8ekT2vQ0Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tWyts7lhRJiIhmC8lpxqxClUdh9f1ARDoMC9DTctZogcSEPpaczLihkBeuF4yHnxl OG11exn1M6mwVUjxqtf3GV9fkxG0nqd4VQhiOE5m8s/xObR8Gc7k/9vgtWyD5qZlVH aAn+mzZp0K3pyshJ74Tw8etgJK+XOXPCt21/VG8HdxiIz5/FZJlu+i8tBBaJn0KZfs o+PrS4qQjm2PJhnDq2DmwScJsR64QLcXGI1tOOk/5kylq860zVPMEunqJi4lnAeot+ 4Eg0CjioasPZKd9F/mtfhj9Djy8Tem81DyqfqelRPi4zGhrA/iR5qCpFpR6ljJ/Zr6 hYK5DJEURQKKg== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:41 +0200 Subject: [PATCH RFC DRAFT 35/50] selftests/namespaces: first listns() test 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: <20251021-work-namespace-nstree-listns-v1-35-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3148; i=brauner@kernel.org; h=from:subject:message-id; bh=NAhtGlBVfCqrlTfWbGN1zDMklE1n7EKY3e8ekT2vQ0Y=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3z3fqrIBqXNV6+v2Blg7BkcbDrZ9XX9r/aXDltaf Hij+l0edZSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExEIo2R4W/P7moNrsM1SjGW 5emM7KxrVwU/eLRU/O20LPWPXVpHNRkZ3mSoy6ZGf5t0YN0vB2mfkJ0qHcsucrvHqsnNOJ89bYY nLwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test basic listns() functionality with the unified namespace tree. List all active namespaces globally. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/.gitignore | 1 + tools/testing/selftests/namespaces/Makefile | 3 +- tools/testing/selftests/namespaces/listns_test.c | 57 ++++++++++++++++++++= ++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/namespaces/.gitignore b/tools/testing/= selftests/namespaces/.gitignore index 100cc5bfef04..5065f07e92c9 100644 --- a/tools/testing/selftests/namespaces/.gitignore +++ b/tools/testing/selftests/namespaces/.gitignore @@ -2,3 +2,4 @@ nsid_test file_handle_test init_ino_test ns_active_ref_test +listns_test diff --git a/tools/testing/selftests/namespaces/Makefile b/tools/testing/se= lftests/namespaces/Makefile index 5cea938cdde8..de708f4df159 100644 --- a/tools/testing/selftests/namespaces/Makefile +++ b/tools/testing/selftests/namespaces/Makefile @@ -2,9 +2,10 @@ CFLAGS +=3D -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) LDLIBS +=3D -lcap =20 -TEST_GEN_PROGS :=3D nsid_test file_handle_test init_ino_test ns_active_ref= _test +TEST_GEN_PROGS :=3D nsid_test file_handle_test init_ino_test ns_active_ref= _test listns_test =20 include ../lib.mk =20 $(OUTPUT)/ns_active_ref_test: ../filesystems/utils.c +$(OUTPUT)/listns_test: ../filesystems/utils.c =20 diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c new file mode 100644 index 000000000000..cb42827d3dfe --- /dev/null +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -0,0 +1,57 @@ +// 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" +#include "../filesystems/utils.h" +#include "wrappers.h" + +/* + * Test basic listns() functionality with the unified namespace tree. + * List all active namespaces globally. + */ +TEST(listns_basic_unified) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, /* All types */ + .spare2 =3D 0, + .user_ns_id =3D 0, /* Global listing */ + }; + __u64 ns_ids[100]; + ssize_t ret; + + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret < 0) { + if (errno =3D=3D ENOSYS) + SKIP(return, "listns() not supported"); + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + ASSERT_TRUE(false); + } + + /* Should find at least the initial namespaces */ + ASSERT_GT(ret, 0); + TH_LOG("Found %zd active namespaces", ret); + + /* Verify all returned IDs are non-zero */ + for (ssize_t i =3D 0; i < ret; i++) { + ASSERT_NE(ns_ids[i], 0); + TH_LOG(" [%zd] ns_id: %llu", i, (unsigned long long)ns_ids[i]); + } +} + +TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 6C28532F764; Tue, 21 Oct 2025 11:47:01 +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=1761047221; cv=none; b=rARYKeZAlSzPZ/EmcBFk/sxNlyFbpM3LOaUOdO/CpN2Ia11oOQvw4ufFNmo/1tgAufpL78WDyXGakromYtQGuPYqJGlV0z9NLvtNhcc2UmMWkpmLP0LoUrjh2IJnElN945nlzQucMHC3woiXxZxc5HCMJdxuf+2Q1YXzjL1SgtU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047221; c=relaxed/simple; bh=gPBGu8BceJ6oHRtyp7iwBf16DUj5zY+HNikOeiNBVYw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tgXMQwmFkKod0km5XAUmpQbRuE7MyplmC7VHz84/Bier62aV9Xj8qfrwaZS+UCQeU0MJMPJwRiStjcOw6+jwa7nWTkTxEI/Rzibox0gudYG7QMlsIcovuSXmmB4+q1wQ7+WKqPzGqMRDoOL0OEi82lXatqFQuVUzz83Cr/BADeo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YfSG10s5; 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="YfSG10s5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5EDB9C4CEFD; Tue, 21 Oct 2025 11:46:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047221; bh=gPBGu8BceJ6oHRtyp7iwBf16DUj5zY+HNikOeiNBVYw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YfSG10s54jEggowkAvAe3GoaDOF7OpbN00+tcxBwbAj48co3u766V2hu9wwiUsXxe KZI/CNLq6D8/78/60R/XWk8V9WMyKWSvPzve7+y3e7cEFMOn9MNHds3UkntZmm5CwB 81R+3CbtXqTVOJuYM37zqm/pTfehZeMlOMMK+tsjDCcJl+pivKolSu5oEJLaw60Zrf pq1y0ArUeNO3Q0ButOz4uTmJCU7LzRYQP58uIZGkKNIQWJANlwzdRtBgKlrwByzpTz EykmZxb4TKaSNrZSeJ9+FJoCHZTliY7ghD1hn8c81Y8E3VFtVa69ulVlKQsE05zL+u Dwl0pbflP2aYA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:42 +0200 Subject: [PATCH RFC DRAFT 36/50] selftests/namespaces: second listns() test 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: <20251021-work-namespace-nstree-listns-v1-36-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2143; i=brauner@kernel.org; h=from:subject:message-id; bh=gPBGu8BceJ6oHRtyp7iwBf16DUj5zY+HNikOeiNBVYw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xXI3dvV9KpCbzKy9l+zJtwTs307szbGm1X14v/q 9vc5zTzckcpC4MYF4OsmCKLQ7tJuNxynorNRpkaMHNYmUCGMHBxCsBEqg8y/A9PSv/y7mLeg+BX SWqLEgW65Cb/mGzr/vH4+ZjvZ87MthNgZNgncH/iYWXe4ohG1lnNj+Zrf21VdysUvL1GeJH3+2t talwA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 test listns() with type filtering. List only network namespaces. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 61 ++++++++++++++++++++= ++++ 1 file changed, 61 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index cb42827d3dfe..64249502ac49 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -54,4 +54,65 @@ TEST(listns_basic_unified) } } =20 +/* + * Test listns() with type filtering. + * List only network namespaces. + */ +TEST(listns_filter_by_type) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWNET, /* Only network namespaces */ + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 ns_ids[100]; + ssize_t ret; + + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret < 0) { + if (errno =3D=3D ENOSYS) + SKIP(return, "listns() not supported"); + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + ASSERT_TRUE(false); + } + ASSERT_GE(ret, 0); + + /* Should find at least init_net */ + ASSERT_GT(ret, 0); + TH_LOG("Found %zd active network namespaces", ret); + + /* Verify we can open each namespace and it's actually a network namespac= e */ + for (ssize_t i =3D 0; i < ret && i < 5; i++) { + struct nsfs_file_handle nsfh =3D { + .ns_id =3D ns_ids[i], + .ns_type =3D CLONE_NEWNET, + .ns_inum =3D 0, + }; + struct file_handle *fh; + int fd; + + fh =3D (struct file_handle *)malloc(sizeof(*fh) + sizeof(nsfh)); + ASSERT_NE(fh, NULL); + fh->handle_bytes =3D sizeof(nsfh); + fh->handle_type =3D 0; + memcpy(fh->f_handle, &nsfh, sizeof(nsfh)); + + fd =3D open_by_handle_at(-10003, fh, O_RDONLY); + free(fh); + + if (fd >=3D 0) { + int ns_type; + /* Verify it's a network namespace via ioctl */ + ns_type =3D ioctl(fd, NS_GET_NSTYPE); + if (ns_type >=3D 0) { + ASSERT_EQ(ns_type, CLONE_NEWNET); + } + close(fd); + } + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 A99FA336EF8; Tue, 21 Oct 2025 11:47:06 +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=1761047226; cv=none; b=TUjhINvofjZAnjkLys2tY6BHXLrhyMbHLEkjo9lNXTeYB5QglpN/LnL3OzrkdFwm/Wzq3eASdaT6h6lCgQiL3fJyaOTT/hhL9BoQtJIOvkgUeQe4qF2qwhpx67UV9u3pqVwgj0bnfYnYITQEDjsf8rO4oDG7hZ+sX76apDaGRlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047226; c=relaxed/simple; bh=16wgRCEaRGE6KnaGWYUsE3X1jinLIZr1ZBK0aXw4RfM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H1M947X0G5b2MYXtqt8DODaSs57M8FFbR2Qe4LkCDDw2zpg/CdrNHqiGyEZ5rdXOCACCX4WJE0KfOaqpXAp8MU8tna3JW9Lp2jqtR9euc1LSsvJWxouUYuKjKWAWOuAQ0YmD7UjlCvKNBXyqh3v8MP++/89XIjWQf1M056jP1/M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YVozDYc2; 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="YVozDYc2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 945F0C4CEF1; Tue, 21 Oct 2025 11:47:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047226; bh=16wgRCEaRGE6KnaGWYUsE3X1jinLIZr1ZBK0aXw4RfM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YVozDYc2BWlZUf8wYFVhvmQ7lLAh6Wrd8xi0neNvo50eImcWhBWUi5OmVXAPeelf1 JJA6V4IEpS3GF3Gg18qzz3pfIIg+ZGaIyou61yvhnMEOQg5BP1HHm0qz2Eq7qgjBTw o9MixiTl6MVHGYHu1MLTlNadve2ow5rsoXtkBZjKB9yyRf77vsIciuiEAIhD41xpRW mdz6MLapzT/AZbe4VEz5z9j3Gf8xtq8pMlBBaTE4mDAG+LI/ekF0SNKS24cD0qY6zn Vn+xpp1uBVkQeYj0ICXSdfPHZp/ihnZiNmHrlGtWeDCXVTYM3ThOUyoXxgyrnATUuB 0723rs55b8+nA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:43 +0200 Subject: [PATCH RFC DRAFT 37/50] selftests/namespaces: third listns() test 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: <20251021-work-namespace-nstree-listns-v1-37-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2006; i=brauner@kernel.org; h=from:subject:message-id; bh=16wgRCEaRGE6KnaGWYUsE3X1jinLIZr1ZBK0aXw4RfM=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y335I7mPUwu4etyPWj761KUnkEOTWCxPR3bl38K vaCucKKjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIno8jIyHBGs5xP2UntiqdA7 O3YVy6pPCSuWBm/lntT1/8eDZX0hXxn+ij6OqYleaLSz8uaGrRGeq9iOnvJsqjoSkHtMsdbz2dE LTAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test listns() pagination. List namespaces in batches. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 53 ++++++++++++++++++++= ++++ 1 file changed, 53 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index 64249502ac49..7dff63a00263 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -115,4 +115,57 @@ TEST(listns_filter_by_type) } } =20 +/* + * Test listns() pagination. + * List namespaces in batches. + */ +TEST(listns_pagination) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 batch1[2], batch2[2]; + ssize_t ret1, ret2; + + /* Get first batch */ + ret1 =3D sys_listns(&req, batch1, ARRAY_SIZE(batch1), 0); + if (ret1 < 0) { + if (errno =3D=3D ENOSYS) + SKIP(return, "listns() not supported"); + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + ASSERT_TRUE(false); + } + ASSERT_GE(ret1, 0); + + if (ret1 =3D=3D 0) + SKIP(return, "No namespaces found"); + + TH_LOG("First batch: %zd namespaces", ret1); + + /* Get second batch using last ID from first batch */ + if (ret1 =3D=3D ARRAY_SIZE(batch1)) { + req.ns_id =3D batch1[ret1 - 1]; + ret2 =3D sys_listns(&req, batch2, ARRAY_SIZE(batch2), 0); + ASSERT_GE(ret2, 0); + + TH_LOG("Second batch: %zd namespaces (after ns_id=3D%llu)", + ret2, (unsigned long long)req.ns_id); + + /* If we got more results, verify IDs are monotonically increasing */ + if (ret2 > 0) { + ASSERT_GT(batch2[0], batch1[ret1 - 1]); + TH_LOG("Pagination working: %llu > %llu", + (unsigned long long)batch2[0], + (unsigned long long)batch1[ret1 - 1]); + } + } else { + TH_LOG("All namespaces fit in first batch"); + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 645A2331A59; Tue, 21 Oct 2025 11:47: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=1761047231; cv=none; b=WdMehTkC/AuG2YUEgvaaBEycrCILhPMXT0y4aVUWEhPkc1ylCOiu+bC3jhgWqNDlAPQdTtHqgn4XrQBJqLjdsJ7jIURugkT/9OMwW5IZJGwbniaMq5+eShGBhpdXp+xcBC7rqXVI6LgMaah2FKh9UyrQ0ygmhnv5g7uAO2Vx7n0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047231; c=relaxed/simple; bh=UxNNzwwfXU08oQlPAvQ0Gj3cx0fWVzo9FwN6OUP3IWE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fNoaZs7jacJ8Pfh/eahib9k4UHyUtJrCyj4M2Yjpp5hTNzpY3bCFra19KlkTQR5JxwBgZWKutmMI0s9UmcKRlY1ThWmNieFYuDH0CuLP7bGbgllO1jB9OjNyBUsO7Ft6BCE5XukIubhhQrdYOJ5Hl4VEUv1LUj8LqzMOBUORuso= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=huPX/l79; 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="huPX/l79" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A163DC4CEFF; Tue, 21 Oct 2025 11:47:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047231; bh=UxNNzwwfXU08oQlPAvQ0Gj3cx0fWVzo9FwN6OUP3IWE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=huPX/l79ayGnTtDzvAud738L4wVGg+6mVX9/DetwXihJUZ4DkDyjYB7ROwaHcdBhJ WV/TmFbpjn1R9KFzURg1nrj7tTLTaSxrX0T68sf//euWfdqNkJLmXHwxKNsYBlApEo CDUDp8vgU4BbdZQ/CUYzKIAQ+Hi+tT/OwUcGR2gAFP2j9IqjpZrZUXPtTm9JtOgOAw L7r2Yg+OWFdhLSHgNcwzG9dUIxVaVtVmunQxTojM4+RAFQNVWmmj55DwxJgCg8EnTh vZsG3uoUuEg+bo7wDjVXb4a5QPOPsQDGE6UW237Rr+mdxq4Vuj0HZoraTD7/dKwzH6 JyYwT6Ju9V9zA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:44 +0200 Subject: [PATCH RFC DRAFT 38/50] selftests/namespaces: fourth listns() test 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: <20251021-work-namespace-nstree-listns-v1-38-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1513; i=brauner@kernel.org; h=from:subject:message-id; bh=UxNNzwwfXU08oQlPAvQ0Gj3cx0fWVzo9FwN6OUP3IWE=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3wnaXlD92mP4Ku3ueFz0+7V9DKvdp79gL1v7wbb3 BtHumbv6yhlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZjIKVOG/7VGc18oFAZ9fTdv w+2zBs/kAyJYOOocbBmqbzX6vT5g/JeRofN8sqXt3kqtrIIu1ksWh6YLuNzfdKb50BH/LruWsPS rLAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test listns() with LISTNS_CURRENT_USER. List namespaces owned by current user namespace. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 33 ++++++++++++++++++++= ++++ 1 file changed, 33 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index 7dff63a00263..457298cb4c64 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -168,4 +168,37 @@ TEST(listns_pagination) } } =20 +/* + * Test listns() with LISTNS_CURRENT_USER. + * List namespaces owned by current user namespace. + */ +TEST(listns_current_user) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, + .spare2 =3D 0, + .user_ns_id =3D LISTNS_CURRENT_USER, + }; + __u64 ns_ids[100]; + ssize_t ret; + + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret < 0) { + if (errno =3D=3D ENOSYS) + SKIP(return, "listns() not supported"); + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + ASSERT_TRUE(false); + } + ASSERT_GE(ret, 0); + + /* Should find at least the initial namespaces if we're in init_user_ns */ + TH_LOG("Found %zd namespaces owned by current user namespace", ret); + + for (ssize_t i =3D 0; i < ret; i++) + TH_LOG(" [%zd] ns_id: %llu", i, (unsigned long long)ns_ids[i]); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 94ECA33769C; Tue, 21 Oct 2025 11:47:16 +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=1761047236; cv=none; b=uwgTrJ25ioggRATcup+j/GeXAmZaNoS1sJpkkGTviSA5uarGTSe+nNpX1KfDdUnBzvMtymOz4d9+mbOb6OKEH6Aez9ZpngvqDhHfzj5js5vQcBYPgsp/e2YGH4ULo+dt4hD9FC7K7GJTa7KIJzw4K+Bd5I1WF/gdOEfUei8gmdM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047236; c=relaxed/simple; bh=8oUiPySwgEUEU/08UclINQ2fnNQXoryHtImyDaO/kZg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qKVwtADAr0FvXnVQhNQyUhiWmKLYRxp4zDAuTiP/tp6vcaDob+eh4/Uo27Or0s6e0P+BXOhCy3ouDBfjGDgnFhLn+UdUeGY+zum09lZP1E91pcTX8sD1+xbQW3SDWQW9IDT/ozEePLBRI3q/FSpT4sxvSknZ91cRAs8vdCPzlpw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QJ6MBLGJ; 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="QJ6MBLGJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B335DC4CEF5; Tue, 21 Oct 2025 11:47:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047236; bh=8oUiPySwgEUEU/08UclINQ2fnNQXoryHtImyDaO/kZg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QJ6MBLGJYDeqA9DHIUJPVmaLKHGV9ZSbskochpTa7cJUQayKORuCM2Kdwm+KmbcKS 1duDNFpeDJLWZ/9gqpMjSBHmO9otx3RkLD3+OjOMIB61uVCJQNhEalmAOnYqW4xECT 2zCM6Y+o81n3uI5/MqzqzgOczlPOsPIftwQj/vxeut0jV9XSUnWy5QektLGFpWRj5z VywFROh5XZxl4rqZHtzQAIJRldpPDm2FKFzL3GHrMzDJmnmK7wTn1uCxF9pZpgD0JI wRyVo+Mhrqe9NFZH/B2QuaQ4dDmi90+vY2BdfuVIVa/aIpCp/c6l0IQloE6dZKiis2 hrAB+96w2VnhQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:45 +0200 Subject: [PATCH RFC DRAFT 39/50] selftests/namespaces: fifth listns() test 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: <20251021-work-namespace-nstree-listns-v1-39-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3866; i=brauner@kernel.org; h=from:subject:message-id; bh=8oUiPySwgEUEU/08UclINQ2fnNQXoryHtImyDaO/kZg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y3ZEq0E8NpIYk0TeWdmVqq6tf4s3Srk/lfVSp+2 rsmbWdDRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwETUTjD8L1rFfNhhuUO7944O tymvb4ieOb1WONJQeTuvDdvTlVdFXjD8jzdhY3lml7o4/lrylTePzjYZ/LlxO/PBRO4f0S/Yesq esQIA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that listns() only returns active namespaces. Create a namespace, let it become inactive, verify it's not listed. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 126 +++++++++++++++++++= ++++ 1 file changed, 126 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index 457298cb4c64..e854794abe56 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -201,4 +201,130 @@ TEST(listns_current_user) TH_LOG(" [%zd] ns_id: %llu", i, (unsigned long long)ns_ids[i]); } =20 +/* + * Test that listns() only returns active namespaces. + * Create a namespace, let it become inactive, verify it's not listed. + */ +TEST(listns_only_active) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWNET, + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 ns_ids_before[100], ns_ids_after[100]; + ssize_t ret_before, ret_after; + int pipefd[2]; + pid_t pid; + __u64 new_ns_id =3D 0; + int status; + + /* Get initial list */ + ret_before =3D sys_listns(&req, ns_ids_before, ARRAY_SIZE(ns_ids_before),= 0); + if (ret_before < 0) { + if (errno =3D=3D ENOSYS) + SKIP(return, "listns() not supported"); + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + ASSERT_TRUE(false); + } + ASSERT_GE(ret_before, 0); + + TH_LOG("Before: %zd active network namespaces", ret_before); + + /* Create a new namespace in a child process and get its ID */ + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + __u64 ns_id; + + close(pipefd[0]); + + /* Create new network namespace */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get its ID */ + fd =3D open("/proc/self/ns/net", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &ns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Send ID to parent */ + write(pipefd[1], &ns_id, sizeof(ns_id)); + close(pipefd[1]); + + /* Keep namespace active briefly */ + usleep(100000); + exit(0); + } + + /* Parent reads the new namespace ID */ + { + int bytes; + + close(pipefd[1]); + bytes =3D read(pipefd[0], &new_ns_id, sizeof(new_ns_id)); + close(pipefd[0]); + + if (bytes =3D=3D sizeof(new_ns_id)) { + __u64 ns_ids_during[100]; + int ret_during; + + TH_LOG("Child created namespace with ID %llu", (unsigned long long)new_= ns_id); + + /* List namespaces while child is still alive - should see new one */ + ret_during =3D sys_listns(&req, ns_ids_during, ARRAY_SIZE(ns_ids_during= ), 0); + ASSERT_GE(ret_during, 0); + TH_LOG("During: %d active network namespaces", ret_during); + + /* Should have more namespaces than before */ + ASSERT_GE(ret_during, ret_before); + } + } + + /* Wait for child to exit */ + waitpid(pid, &status, 0); + + /* Give time for namespace to become inactive */ + usleep(100000); + + /* List namespaces after child exits - should not see new one */ + ret_after =3D sys_listns(&req, ns_ids_after, ARRAY_SIZE(ns_ids_after), 0); + ASSERT_GE(ret_after, 0); + TH_LOG("After: %zd active network namespaces", ret_after); + + /* Verify the new namespace ID is not in the after list */ + if (new_ns_id !=3D 0) { + bool found =3D false; + + for (ssize_t i =3D 0; i < ret_after; i++) { + if (ns_ids_after[i] =3D=3D new_ns_id) { + found =3D true; + break; + } + } + if (found) { + TH_LOG("Warning: Namespace %llu still active after process exit", + (unsigned long long)new_ns_id); + } + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 7784832ED21; Tue, 21 Oct 2025 11:47:22 +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=1761047242; cv=none; b=t7twdTj0VKZUABXWfSfSsOdVdJoSFp2y+izGofGCc26PYAnkZy1yE8Wqb6j/aenJDMw506OKbd+CGd/3oyA+vUZxzrXD+l3UJD5qK2VlT1N/flQ6mREJLgCRRwdgeP2AGQlWreuQhLEX3dLB3BGXliIhAT8dXnBJB4LDUSCTVVc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047242; c=relaxed/simple; bh=4vBs0iC1GliO+F4XrLBJxRIywFUw/24vdpBSDdc51/s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lvfnOAG4zSVtGtAauTZPQ/iQiXTSKs6BlWcKO6oj9sseDZCZ+9JNd1zB5wdOq7QUi7YfvoseM6TuT/Ndr56cL3oFxgWbpkWuSwHOl4IDBJtASQPDS1dCQYein8RDuzji7ZZUIEL/dk/LxwKGemu+hP6AtfNz+pNw7JO7M+EnjHo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bI717obE; 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="bI717obE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E6E28C4CEFD; Tue, 21 Oct 2025 11:47:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047242; bh=4vBs0iC1GliO+F4XrLBJxRIywFUw/24vdpBSDdc51/s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bI717obESmGM0zhYVSTw0xxWy1nlhI/WfmtEyFBvL9Rw2+vP0HrYyjQKeWVWRw7MX buOB+EqQXxQrcz/07IyF9icBDS+mkgYGU9Ml7IovMvyANmc7U2R5m20jxS7GTb6MVx YheiQiZM4JP2aiG7qrluLBqF+dY+UNrDUQdVdyPcxe/PohZyPHOlgqpdKqIB2X7wsF VCSrpabpmol/DN01EvliztM6GV5o1hWJZuzBo64gHyPHFKFwdljZwShUMvgg862yA1 X6HCbIYPbsSp2bWZFmpMCbgmcVa3/E6E8MVRwjYJN3ZkbgKT5XyUwnYgAI+UYozlIV ebJnv/T9kkgJQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:46 +0200 Subject: [PATCH RFC DRAFT 40/50] selftests/namespaces: sixth listns() test 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: <20251021-work-namespace-nstree-listns-v1-40-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3170; i=brauner@kernel.org; h=from:subject:message-id; bh=4vBs0iC1GliO+F4XrLBJxRIywFUw/24vdpBSDdc51/s=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y3uXZe1M3HFstePDSbsX3Lo52T7kd886q83nA5j VHPvq5At6OUhUGMi0FWTJHFod0kXG45T8Vmo0wNmDmsTCBDGLg4BWAi0QoM/122tvLmnohbUV7f vORn/psHlrWc6vtWJq0+clUo/Izu10+MDK927DHmjtc5LB4cVPvxd9+pdKnVRb72ooxLU4LqA7d P4gUA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test listns() with specific user namespace ID. Create a user namespace and list namespaces it owns. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 109 +++++++++++++++++++= ++++ 1 file changed, 109 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index e854794abe56..e1e90ef933cf 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -327,4 +327,113 @@ TEST(listns_only_active) } } =20 +/* + * Test listns() with specific user namespace ID. + * Create a user namespace and list namespaces it owns. + */ +TEST(listns_specific_userns) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, + .spare2 =3D 0, + .user_ns_id =3D 0, /* Will be filled with created userns ID */ + }; + __u64 ns_ids[100]; + int pipefd[2]; + pid_t pid; + int status; + __u64 user_ns_id =3D 0; + int bytes; + ssize_t ret; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + __u64 ns_id; + char buf; + + close(pipefd[0]); + + /* Create new user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get user namespace ID */ + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &ns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Send ID to parent */ + write(pipefd[1], &ns_id, sizeof(ns_id)); + + /* Create some namespaces owned by this user namespace */ + unshare(CLONE_NEWNET); + unshare(CLONE_NEWUTS); + + /* Wait for parent signal */ + read(pipefd[1], &buf, 1); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + bytes =3D read(pipefd[0], &user_ns_id, sizeof(user_ns_id)); + + if (bytes !=3D sizeof(user_ns_id)) { + close(pipefd[0]); + kill(pid, SIGKILL); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to get user namespace ID from child"); + } + + TH_LOG("Child created user namespace with ID %llu", (unsigned long long)u= ser_ns_id); + + /* List namespaces owned by this user namespace */ + req.user_ns_id =3D user_ns_id; + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + + if (ret < 0) { + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + close(pipefd[0]); + kill(pid, SIGKILL); + waitpid(pid, NULL, 0); + if (errno =3D=3D ENOSYS) { + SKIP(return, "listns() not supported"); + } + ASSERT_GE(ret, 0); + } + + TH_LOG("Found %zd namespaces owned by user namespace %llu", ret, + (unsigned long long)user_ns_id); + + /* Should find at least the network and UTS namespaces we created */ + if (ret > 0) { + for (ssize_t i =3D 0; i < ret && i < 10; i++) + TH_LOG(" [%zd] ns_id: %llu", i, (unsigned long long)ns_ids[i]); + } + + /* Signal child to exit */ + close(pipefd[0]); + waitpid(pid, &status, 0); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 77AD1330B3A; Tue, 21 Oct 2025 11:47:27 +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=1761047247; cv=none; b=dpCHgqHdNMlRaXcOIZY5rGjDB8i+e/qRefvmv9m+wErKakS2jYIRp2YmKTPIUsPV6nCMGtE73sirsG5mPUld8G0wf6IHljPxZ7zoi1UaIwT4CbshCBBMQ4CzNt6rTu0Uo3o4naZB4jCgCrfG30r2ZOtcPXdEwf7I7okmbNFhJD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047247; c=relaxed/simple; bh=zSBiD0DmDYcPFHCmh4S9YgYEBZCkP3T4DUO3iD7+Aw0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eaU/n9RI6LLze719gqb3GOqVdc6cbz4M/2RQ8y0ksvlwBTuJ3B1IcaIcdy585dsVA5mvaCU+OzFVVSFry88mpUuo4h/aGmDitRss2JDT+KG5ThbiZV2XBAUKa7LmiHKQGI0zMwol3qRjNBcNXvAcDGYo3lmPwO+RbjtFmXXV2wk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n4fUWbRM; 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="n4fUWbRM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8058FC4CEF1; Tue, 21 Oct 2025 11:47:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047247; bh=zSBiD0DmDYcPFHCmh4S9YgYEBZCkP3T4DUO3iD7+Aw0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=n4fUWbRM11/PoGked2SvTK+PtnUeTyJJnKrdVB2F0HKz2qvX8fmqiQs8gGFtPXcU/ lSoQZIkEYCGdFEZm9ZzFa6kTb8jrb+CwLmAEh6gHINlWR6+aY3kascaVKCE3OrIyJM wDxrK1QgVVZEHD6L5HZiLyy6KxTHevLx61wb2IDmH9foswaH0p3NxFkr2je4Z2kdew HW1EDrKgCJgR44/R8+bVhTuhT4YiiVmkX5zzJ5SNHugOU5rPvPNpqW2wcOazJ7Pmcm Jtx1znmBjVktyAasvrhD9DaI+kyHYLvB2LttzRuov6oJYNKK31Q5zPi8M44LjQrgv8 9fL063LryCv8Q== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:47 +0200 Subject: [PATCH RFC DRAFT 41/50] selftests/namespaces: seventh listns() test 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: <20251021-work-namespace-nstree-listns-v1-41-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1404; i=brauner@kernel.org; h=from:subject:message-id; bh=zSBiD0DmDYcPFHCmh4S9YgYEBZCkP3T4DUO3iD7+Aw0=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y35jVz4vOpJxefyHY4JelrdrjV3vpI64W1bu7vt Ezy5heLdJSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAExk6iVGhsPSDVd/XpFq9G+S YqncmK+mUGuqbP05s1QgiXX7szsu1xgZWld0q3pGL/9WeunolvLmWeGSiw7MPTNjVZ1WTCLv3ah F3AA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test listns() with multiple namespace types filter. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 31 ++++++++++++++++++++= ++++ 1 file changed, 31 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index e1e90ef933cf..6afffddf9764 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -436,4 +436,35 @@ TEST(listns_specific_userns) waitpid(pid, &status, 0); } =20 +/* + * Test listns() with multiple namespace types filter. + */ +TEST(listns_multiple_types) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWNET | CLONE_NEWUTS, /* Network and UTS */ + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 ns_ids[100]; + ssize_t ret; + + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret < 0) { + if (errno =3D=3D ENOSYS) + SKIP(return, "listns() not supported"); + TH_LOG("listns failed: %s (errno=3D%d)", strerror(errno), errno); + ASSERT_TRUE(false); + } + ASSERT_GE(ret, 0); + + TH_LOG("Found %zd active network/UTS namespaces", ret); + + for (ssize_t i =3D 0; i < ret; i++) + TH_LOG(" [%zd] ns_id: %llu", i, (unsigned long long)ns_ids[i]); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 E6F8B330B3A; Tue, 21 Oct 2025 11:47:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047253; cv=none; b=AozA/Hak02aF+yh6GxxzNin4AUwFekwIV9wa1anhp//cF1wMInAlZ04h/6hNGU3g9jefVyz4A4tI8Nl+paWQ4enGjFIpHPRqcg3LvabBGlOJ9C3Nt5dCKpGnMPN5OaxzH2egrifulq6IOC8/XVWIHCrUl+u/OshIxGlDFxEo2Is= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047253; c=relaxed/simple; bh=V4fLSyijbME7l6bI490uSVspsEhpOL9UHRqTJM6dwA8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TNRFLUXL1x1iKsznP5KMtlFHe4PXnDQw3WhJsoPWfe50r4DCO1AXfrLPCOCoDuU5e2/Zm+t7p3nIZNfB9X54vE25zROIKqfzpuFCD6Y8NaYFKqP67C03VSn7ZWBu7JL9ZrkXa3jP43p/UAsR8JgGhzRm1EH3nhIT0WYt604SFQM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D73ZWQfv; 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="D73ZWQfv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92650C4CEF5; Tue, 21 Oct 2025 11:47:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047252; bh=V4fLSyijbME7l6bI490uSVspsEhpOL9UHRqTJM6dwA8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D73ZWQfvX6+4O7OBuostsMUjIKoA+fPF9ThEtDNzqoHLAGVj60UtQh/lRDo0GI08z KTU430P7bLfq+4gx+9wG0zus/Ud7/+ua6t3moptUk11/jyccMOMxwLSNOJYvwCnsgX GkY8Pc4fF76zu7cTYoVZeoOhjgn/g0RuW+FTPYGYpd9baVzVbiM+IH8kRPNPf14f/T AVsoWsQeOrKdvA6bfFj0GGka22rjG4/zZPCgoIf+BxIi0ez+V9I+axyqDeJFMcx1oB DSz46SNKHw++wV7JnCDKb96Kcl21iMYMJ85CXzTW+XXCuxZgGIPRPilJNj/AytuOir 6/AwnIIKMl6Iw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:48 +0200 Subject: [PATCH RFC DRAFT 42/50] selftests/namespaces: ninth listns() test 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: <20251021-work-namespace-nstree-listns-v1-42-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3882; i=brauner@kernel.org; h=from:subject:message-id; bh=V4fLSyijbME7l6bI490uSVspsEhpOL9UHRqTJM6dwA8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3x3KVv9/jlrgRVS2gd7f2sUeL5bGCN1KfTFBVHJe 3FXOrPDOkpZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACYSOIWR4dq2c2XrX3SsWDzP b/uhoxNXaGVdM+RmzEoRFfK+naTpNZuR4deqefOc1Ap3ndhyfWP/X50FT/dwt5Y7P3waeVnj0ex /p/kA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that hierarchical active reference propagation keeps parent user namespaces visible in listns(). Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 135 +++++++++++++++++++= ++++ 1 file changed, 135 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index 6afffddf9764..ddf4509d5cd6 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -467,4 +467,139 @@ TEST(listns_multiple_types) TH_LOG(" [%zd] ns_id: %llu", i, (unsigned long long)ns_ids[i]); } =20 +/* + * Test that hierarchical active reference propagation keeps parent + * user namespaces visible in listns(). + */ +TEST(listns_hierarchical_visibility) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWUSER, + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 parent_ns_id =3D 0, child_ns_id =3D 0; + int pipefd[2]; + pid_t pid; + int status; + int bytes; + __u64 ns_ids[100]; + ssize_t ret; + bool found_parent, found_child; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + char buf; + + close(pipefd[0]); + + /* Create parent user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &parent_ns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Create child user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &child_ns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Send both IDs to parent */ + write(pipefd[1], &parent_ns_id, sizeof(parent_ns_id)); + write(pipefd[1], &child_ns_id, sizeof(child_ns_id)); + + /* Wait for parent signal */ + read(pipefd[1], &buf, 1); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + /* Read both namespace IDs */ + bytes =3D read(pipefd[0], &parent_ns_id, sizeof(parent_ns_id)); + bytes +=3D read(pipefd[0], &child_ns_id, sizeof(child_ns_id)); + + if (bytes !=3D (int)(2 * sizeof(__u64))) { + close(pipefd[0]); + kill(pid, SIGKILL); + waitpid(pid, NULL, 0); + SKIP(return, "Failed to get namespace IDs from child"); + } + + TH_LOG("Parent user namespace ID: %llu", (unsigned long long)parent_ns_id= ); + TH_LOG("Child user namespace ID: %llu", (unsigned long long)child_ns_id); + + /* List all user namespaces */ + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + + if (ret < 0 && errno =3D=3D ENOSYS) { + close(pipefd[0]); + kill(pid, SIGKILL); + waitpid(pid, NULL, 0); + SKIP(return, "listns() not supported"); + } + + ASSERT_GE(ret, 0); + TH_LOG("Found %zd active user namespaces", ret); + + /* Both parent and child should be visible (active due to child process) = */ + found_parent =3D false; + found_child =3D false; + for (ssize_t i =3D 0; i < ret; i++) { + if (ns_ids[i] =3D=3D parent_ns_id) + found_parent =3D true; + if (ns_ids[i] =3D=3D child_ns_id) + found_child =3D true; + } + + TH_LOG("Parent namespace %s, child namespace %s", + found_parent ? "found" : "NOT FOUND", + found_child ? "found" : "NOT FOUND"); + + ASSERT_TRUE(found_child); + /* With hierarchical propagation, parent should also be active */ + ASSERT_TRUE(found_parent); + + /* Signal child to exit */ + close(pipefd[0]); + waitpid(pid, &status, 0); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 658E7337BBB; Tue, 21 Oct 2025 11:47:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047257; cv=none; b=hRh4Nv66ghqPldkjCcAwM2n7YOZHNZ6SdmmG6tT4fLaIzKxqxLvC47oDlfXyXo2RwOPPu8W37IHRNpW9i/YQl2Vt4MtTh07eQTbkf4Qnw4WINDFzZBU/5VFy+ge/dXGfr36EHeJKdH2xJwDz+5epSya22LxTpdoD/zQkSNgmSHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047257; c=relaxed/simple; bh=77H7R88MI0EUUkshwD3/5/W86ZbXu7/L538OO/0/fLQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nzb24C1xnhYocOGA21ubxsN0NlUOKnb8jc4FhJ+31LpgKPYSOWlzIwY+QPjNgJHEMUXXg1+4uIzrWUIT5BGhqijsG8HiHhu3c4/IySpLMMCEK1nE7u3D35y82Ax38iSt0R3RpSSgK2HEoUtVugTruv8Oq/LDwLNMUtZkF+7dteI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WnzjS9pE; 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="WnzjS9pE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DD60BC4CEFF; Tue, 21 Oct 2025 11:47:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047257; bh=77H7R88MI0EUUkshwD3/5/W86ZbXu7/L538OO/0/fLQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WnzjS9pEWFOER24ezYjY6jxri9E7sRPgkGGsF9ENWf38HphQRpT7maU4ZZ6+8TvIo iklg56swuw0YwPhFraxbHVHo0UnOGXOEHFyBGKd2qLmPC1Q3wsww59Jj5bwur5457i i5tDWn6rD4TCyywNVPQJ/VMF8WPHm49+/syy8kY7v+pTOz5+PGi29gIj9+541jhpb9 ujH4rhsPYZm0y09LCOnZX1PxSRy1rRQroGCGvlg99z7AfpIKWs4hk5oA5VqtZebVqh nWKBsZY2zFxnRpKoJ5DrOsSo9aWjrvmw/mpHiUfLwdEMZdJAWinMbfuoPBP5V8a8lt tIM/sXnkYDeng== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:49 +0200 Subject: [PATCH RFC DRAFT 43/50] selftests/namespaces: ninth listns() test 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: <20251021-work-namespace-nstree-listns-v1-43-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=1852; i=brauner@kernel.org; h=from:subject:message-id; bh=77H7R88MI0EUUkshwD3/5/W86ZbXu7/L538OO/0/fLQ=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xXHLm6+QXbd2eHip5czkeOV5qXHd2Yev/BrDu+8 dz9y54f6ShlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZjIu1pGhqP3d4krrczwYtBI PuMW8ZZtWePVTTzVe2NUHh6tYjkYkc3IMNtLO7dm7waPusrEGZXr1SqsHh7qUHymfHPj7N9s7A6 xfAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test error cases for listns(). Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/listns_test.c | 51 ++++++++++++++++++++= ++++ 1 file changed, 51 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_test.c b/tools/testi= ng/selftests/namespaces/listns_test.c index ddf4509d5cd6..eb44f50ab77a 100644 --- a/tools/testing/selftests/namespaces/listns_test.c +++ b/tools/testing/selftests/namespaces/listns_test.c @@ -602,4 +602,55 @@ TEST(listns_hierarchical_visibility) waitpid(pid, &status, 0); } =20 +/* + * Test error cases for listns(). + */ +TEST(listns_error_cases) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 ns_ids[10]; + int ret; + + /* Test with invalid flags */ + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0xFFFF); + if (ret >=3D 0 || errno =3D=3D ENOSYS) { + if (errno !=3D ENOSYS) { + TH_LOG("Warning: Expected EINVAL for invalid flags, got success"); + } + } else { + ASSERT_EQ(errno, EINVAL); + } + + /* Test with NULL ns_ids array */ + ret =3D sys_listns(&req, NULL, 10, 0); + if (ret >=3D 0) { + TH_LOG("Warning: Expected EFAULT for NULL array, got success"); + } + + /* Test with invalid spare field */ + req.spare =3D 1; + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret >=3D 0 || errno =3D=3D ENOSYS) { + if (errno !=3D ENOSYS) { + TH_LOG("Warning: Expected EINVAL for non-zero spare, got success"); + } + } + req.spare =3D 0; + + /* Test with huge nr_ns_ids */ + ret =3D sys_listns(&req, ns_ids, 2000000, 0); + if (ret >=3D 0 || errno =3D=3D ENOSYS) { + if (errno !=3D ENOSYS) { + TH_LOG("Warning: Expected EOVERFLOW for huge count, got success"); + } + } +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 80F7D33858A; Tue, 21 Oct 2025 11:47:42 +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=1761047262; cv=none; b=eY2fJANjBrclcyZELDeV6noeIWMrS5DtCP2WG2oseUBG78QxvS6xCWQG3+4RMD1ZvFsW4JDCYEw+wi1u5rT4HiWYU0WHOEB/59G48EtmrdBfPe4G8UB1KhCqkNJdx8cPYtG1eKGR0ZDyYR20bxJbeRgJUN1vQIlcE1G2spUdLDk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047262; c=relaxed/simple; bh=5YqEIrDVXqnPIx61aY2UFkn7520IFi2bPLuDDoqZd4M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Nu9UPn2s22fwko5TowDZfqTIsgLsxoINH2wBri73oqCBN7RbreCUlAA/kfTzlsUtbXvxo4ko/l4tGz8v+1/aJTZbPZBdwNls8/X5IKiXVVTXaRLHZQpJTx+p4lulgmXZ7aKtG3b8beHuOOVVxyeSOmO8jFcSXkfdTJLG4l1yCcc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R0Lqw7b4; 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="R0Lqw7b4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2BD4C4CEFD; Tue, 21 Oct 2025 11:47:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047262; bh=5YqEIrDVXqnPIx61aY2UFkn7520IFi2bPLuDDoqZd4M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=R0Lqw7b4mBzPYBrZIxBYhBTOL5ZAM8PeqobHDUuthY0mrwapNnrrPnvqyx3K4UWYt irEvjfJqXV9LrKxVBjj73j7vB6sYeuttPTIQeeBOuNyzi5ogVr2lk2C4vb2GQb2+oc jP5OJC3zrT67SjWVN13QHphX73uD691X5iArZXkN0XR3xauISjIXlEFksuczC95mPg v/yhNK/Tg5AYKr6j7CjueUf2J4n1G4nru7uN4V9HeQOcdXn20Ebj8q71Lb91HqbUwG NRwfEo6rhKEgE4o87HTKVJQQH5VKmUOcyJmorIc04gM0qcLbuIPgw9RGmz0p030ZKj Ymu0u9WShtVkQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:50 +0200 Subject: [PATCH RFC DRAFT 44/50] selftests/namespaces: first listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-44-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=5030; i=brauner@kernel.org; h=from:subject:message-id; bh=5YqEIrDVXqnPIx61aY2UFkn7520IFi2bPLuDDoqZd4M=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3y/c65cSv2/0uhZ85aF6WaUPs6Q/lzsrMz7f7d/4 6pO1+kLO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACbie4Dhf6RzqUfyO5l7ggGK 1yW8+2JiNvetv13HYLBJcEVFwWUXOUaGX35Pzn72fXfjYfB7Ffmz/7/8Efr/jZtp5cQjFnViz3/ zsAIA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that unprivileged users can only see namespaces they're currently in. Create a namespace, drop privileges, verify we can only see our own namespaces. Signed-off-by: Christian Brauner --- tools/testing/selftests/namespaces/.gitignore | 1 + tools/testing/selftests/namespaces/Makefile | 3 +- .../selftests/namespaces/listns_permissions_test.c | 134 +++++++++++++++++= ++++ 3 files changed, 137 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/namespaces/.gitignore b/tools/testing/= selftests/namespaces/.gitignore index 5065f07e92c9..17f9c675a60b 100644 --- a/tools/testing/selftests/namespaces/.gitignore +++ b/tools/testing/selftests/namespaces/.gitignore @@ -3,3 +3,4 @@ file_handle_test init_ino_test ns_active_ref_test listns_test +listns_permissions_test diff --git a/tools/testing/selftests/namespaces/Makefile b/tools/testing/se= lftests/namespaces/Makefile index de708f4df159..2dd22bc68b89 100644 --- a/tools/testing/selftests/namespaces/Makefile +++ b/tools/testing/selftests/namespaces/Makefile @@ -2,10 +2,11 @@ CFLAGS +=3D -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) LDLIBS +=3D -lcap =20 -TEST_GEN_PROGS :=3D nsid_test file_handle_test init_ino_test ns_active_ref= _test listns_test +TEST_GEN_PROGS :=3D nsid_test file_handle_test init_ino_test ns_active_ref= _test listns_test listns_permissions_test =20 include ../lib.mk =20 $(OUTPUT)/ns_active_ref_test: ../filesystems/utils.c $(OUTPUT)/listns_test: ../filesystems/utils.c +$(OUTPUT)/listns_permissions_test: ../filesystems/utils.c =20 diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c new file mode 100644 index 000000000000..87ec71560d99 --- /dev/null +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../kselftest_harness.h" +#include "../filesystems/utils.h" +#include "wrappers.h" + +/* + * Test that unprivileged users can only see namespaces they're currently = in. + * Create a namespace, drop privileges, verify we can only see our own nam= espaces. + */ +TEST(listns_unprivileged_current_only) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWNET, + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 ns_ids[100]; + ssize_t ret; + int pipefd[2]; + pid_t pid; + int status; + bool found_ours; + int unexpected_count; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + __u64 our_netns_id; + bool found_ours; + int unexpected_count; + + close(pipefd[0]); + + /* Create user namespace to be unprivileged */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Create a network namespace */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get our network namespace ID */ + fd =3D open("/proc/self/ns/net", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &our_netns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Now we're unprivileged - list all network namespaces */ + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret < 0) { + close(pipefd[1]); + exit(1); + } + + /* We should only see our own network namespace */ + found_ours =3D false; + unexpected_count =3D 0; + + for (ssize_t i =3D 0; i < ret; i++) { + if (ns_ids[i] =3D=3D our_netns_id) { + found_ours =3D true; + } else { + /* This is either init_net (which we can see) or unexpected */ + unexpected_count++; + } + } + + /* Send results to parent */ + write(pipefd[1], &found_ours, sizeof(found_ours)); + write(pipefd[1], &unexpected_count, sizeof(unexpected_count)); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + found_ours =3D false; + unexpected_count =3D 0; + read(pipefd[0], &found_ours, sizeof(found_ours)); + read(pipefd[0], &unexpected_count, sizeof(unexpected_count)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to setup namespaces or run listns"); + } + + /* Child should have seen its own namespace */ + ASSERT_TRUE(found_ours); + + TH_LOG("Unprivileged child saw its own namespace, plus %d others (likely = init_net)", + unexpected_count); +} + +TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 0A84934FF5C; Tue, 21 Oct 2025 11:47: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=1761047267; cv=none; b=PSbw+9i6MqFkyiI4ugkuexhXGKk6TlecvtlSY/TAjH6bGWST12tumXl4Bdl0GpRrZb6xMbIB8kxr17IGu7S/aashGm9EoPcGEBG1fdNby9IBcDknhwC0joNHvXgxtAx7/FuCHybJKy7icIrCyTbahNUjpa0qN5/wxTToQFZSJiU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047267; c=relaxed/simple; bh=rZyevUn6hfyhcE1DB3cv3yJAhND3Rlxt9xlbt7Q4T1s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k3zgSrvkuNCZpwNVf90s5zlV/JFDMNGTCdKJa/u47wgWAGB7ABCM5ygymH7oCSKlhI1I9T89G8AW44kjGwYxp6e9pB/2ZhQ+gmJBfOenvS4rvOA2Xk2BmmkfDKOaYofhKiHhlVwAyBi+nPkqcl3CK4f5hDETHwEgX2OHwJE24lg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D0iTTYSh; 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="D0iTTYSh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 93748C4CEF1; Tue, 21 Oct 2025 11:47:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047266; bh=rZyevUn6hfyhcE1DB3cv3yJAhND3Rlxt9xlbt7Q4T1s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D0iTTYShynUcHJSlJo+hUZiJHvzKhIqr9uML4BkcQpFI/uP9vzrFYGTgaEE3r0Zfp UDJ+pfAh52rKiBaow0nzJipcsuv+QRepKibuZSS9DA/BCU6gXmy25lmJu43WKFF40x 0Pl/W5+QVImeq5QGVnag0iYf6MCYia/I9VGbXTvs0MRKXZJlSuBZ6VRF7DA0REbt1m hK0MDD1EQwISwU013CCJLsQfBcUEcXDz79zOoEWajCbGCwofacTi26mzY8QMopxyw3 +mJ9mE2dZh0tioz+bd3fnG9//Yo9QVZM4sqwf/T4MLiMo21+m/ERC9nQwCCvUsahag bPLU1cV3akr3w== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:51 +0200 Subject: [PATCH RFC DRAFT 45/50] selftests/namespaces: second listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-45-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3077; i=brauner@kernel.org; h=from:subject:message-id; bh=rZyevUn6hfyhcE1DB3cv3yJAhND3Rlxt9xlbt7Q4T1s=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3zfoxP8bZXScga5dHPjr/8r5rSJdcRHMm/MMBM7f rRSb0lZRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwESmZTL89799Lfyzgnb0qukx LPq8Snuunnd/b+jx9CKvuMFPy97FRowM11dqJ3RfrXcTUD02vbOgwEZzu0ZF5iXb1j1rfI2FQ45 xAwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that users with CAP_SYS_ADMIN in a user namespace can see all namespaces owned by that user namespace. Signed-off-by: Christian Brauner --- .../selftests/namespaces/listns_permissions_test.c | 103 +++++++++++++++++= ++++ 1 file changed, 103 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c index 87ec71560d99..803c42fc76ec 100644 --- a/tools/testing/selftests/namespaces/listns_permissions_test.c +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -131,4 +131,107 @@ TEST(listns_unprivileged_current_only) unexpected_count); } =20 +/* + * Test that users with CAP_SYS_ADMIN in a user namespace can see + * all namespaces owned by that user namespace. + */ +TEST(listns_cap_sys_admin_in_userns) +{ + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, /* All types */ + .spare2 =3D 0, + .user_ns_id =3D 0, /* Will be set to our created user namespace */ + }; + __u64 ns_ids[100]; + int pipefd[2]; + pid_t pid; + int status; + bool success; + ssize_t count; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + __u64 userns_id; + ssize_t ret; + int min_expected; + bool success; + + close(pipefd[0]); + + /* Create user namespace - we'll have CAP_SYS_ADMIN in it */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get the user namespace ID */ + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &userns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Create several namespaces owned by this user namespace */ + unshare(CLONE_NEWNET); + unshare(CLONE_NEWUTS); + unshare(CLONE_NEWIPC); + + /* List namespaces owned by our user namespace */ + req.user_ns_id =3D userns_id; + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + if (ret < 0) { + close(pipefd[1]); + exit(1); + } + + /* + * We have CAP_SYS_ADMIN in this user namespace, + * so we should see all namespaces owned by it. + * That includes: net, uts, ipc, and the user namespace itself. + */ + min_expected =3D 4; + success =3D (ret >=3D min_expected); + + write(pipefd[1], &success, sizeof(success)); + write(pipefd[1], &ret, sizeof(ret)); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + success =3D false; + count =3D 0; + read(pipefd[0], &success, sizeof(success)); + read(pipefd[0], &count, sizeof(count)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to setup namespaces"); + } + + ASSERT_TRUE(success); + TH_LOG("User with CAP_SYS_ADMIN saw %zd namespaces owned by their user na= mespace", + count); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 DE6CB3314C0; Tue, 21 Oct 2025 11:47:52 +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=1761047273; cv=none; b=J47xOV0+1IGCnVD2kWGw6S7wMPF0KWVpzOEQYuOXUm0zgZHXyeDXg+0No98cLgCW0LFo8K+zD+beEyfjza8kv3DO01GgOxX4hiqfR0jAeWG2HpVuU1isXdPE2IJZCIr2ioNB62JV8em7QX7JlqUcCZbtwlknMQ7zHTqDUxxhMqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047273; c=relaxed/simple; bh=qOQpMwb8a6Ty7XQD33x8dOA998CFgN+vzt4Bsk/lfA4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y+j3wWpIBeAI9QvXaKwzB651qDc8MdwUrsTfXJCycSRzTUm6D6ZHixEbqBAYXqVhaoi+g8OiWFprQkvbFwI1DbXbSGUdbPRnptVw/Orzbeu9S9CUm7t37OM1QqquiVgLoaiTDZ3d/EQ0Pn933MQchLIM5AWS499QhVRjMFtEA+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UnllnALm; 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="UnllnALm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5A35CC4CEF1; Tue, 21 Oct 2025 11:47:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047272; bh=qOQpMwb8a6Ty7XQD33x8dOA998CFgN+vzt4Bsk/lfA4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UnllnALmRxvfKcaWrXUqHNeJcbwIjlN5jFQVsQ8XdMqXlAu5/BKDB6VPHHf9O+IWn NwPlrwboArjmrr6tZm4Ba4LFWj3u9ZP3rQLtXLToL9L5RL1nme1f5qsGaEcCBS1N15 nXGw+c04Vos0ywnHGpPOeHhWsCXFoWFrHXazxYLma/wH/92Skh9oGOU/jjx4UVUukX CZg1g980uP0WLmjdt/uAnX2woKdI/0ED+ScRpWG8pFKGfC9k7HKAmHbgLtMvoWHCmC WsW5YUHpHxvksQbSJYdtFPZojCYyYyeg535H0TvdohGp5PcREXYbyEcDKNmd5Wh8NN h6WLrPtN6lRSw== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:52 +0200 Subject: [PATCH RFC DRAFT 46/50] selftests/namespaces: third listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-46-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=4038; i=brauner@kernel.org; h=from:subject:message-id; bh=qOQpMwb8a6Ty7XQD33x8dOA998CFgN+vzt4Bsk/lfA4=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3xvFT+bOeOmqer+fnmXpylqOb7HjOYkFsx/Vre/M jhf8PnDjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIlUijEy7JrA3HZh2qfyaPut krpvinyvdr7Mtb/+YN69mrXfLq3e6sbIcL564b/W5K9v7ym9qdljPcuP5XyBS9CpyI09D/9sYT/ vyQgA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that users cannot see namespaces from unrelated user namespaces. Create two sibling user namespaces, verify they can't see each other's owned namespaces. Signed-off-by: Christian Brauner --- .../selftests/namespaces/listns_permissions_test.c | 138 +++++++++++++++++= ++++ 1 file changed, 138 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c index 803c42fc76ec..4e47b4c82c56 100644 --- a/tools/testing/selftests/namespaces/listns_permissions_test.c +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -234,4 +234,142 @@ TEST(listns_cap_sys_admin_in_userns) count); } =20 +/* + * Test that users cannot see namespaces from unrelated user namespaces. + * Create two sibling user namespaces, verify they can't see each other's + * owned namespaces. + */ +TEST(listns_cannot_see_sibling_userns_namespaces) +{ + int pipefd[2]; + pid_t pid1, pid2; + int status; + __u64 netns_a_id; + int pipefd2[2]; + bool found_sibling_netns; + + ASSERT_EQ(pipe(pipefd), 0); + + /* Fork first child - creates user namespace A */ + pid1 =3D fork(); + ASSERT_GE(pid1, 0); + + if (pid1 =3D=3D 0) { + int fd; + __u64 netns_a_id; + char buf; + + close(pipefd[0]); + + /* Create user namespace A */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Create network namespace owned by user namespace A */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get network namespace ID */ + fd =3D open("/proc/self/ns/net", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &netns_a_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Send namespace ID to parent */ + write(pipefd[1], &netns_a_id, sizeof(netns_a_id)); + + /* Keep alive for sibling to check */ + read(pipefd[1], &buf, 1); + close(pipefd[1]); + exit(0); + } + + /* Parent reads namespace A ID */ + close(pipefd[1]); + netns_a_id =3D 0; + read(pipefd[0], &netns_a_id, sizeof(netns_a_id)); + + TH_LOG("User namespace A created network namespace with ID %llu", + (unsigned long long)netns_a_id); + + /* Fork second child - creates user namespace B */ + ASSERT_EQ(pipe(pipefd2), 0); + + pid2 =3D fork(); + ASSERT_GE(pid2, 0); + + if (pid2 =3D=3D 0) { + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWNET, + .spare2 =3D 0, + .user_ns_id =3D 0, + }; + __u64 ns_ids[100]; + ssize_t ret; + bool found_sibling_netns; + + close(pipefd[0]); + close(pipefd2[0]); + + /* Create user namespace B (sibling to A) */ + if (setup_userns() < 0) { + close(pipefd2[1]); + exit(1); + } + + /* Try to list all network namespaces */ + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + + found_sibling_netns =3D false; + if (ret > 0) { + for (ssize_t i =3D 0; i < ret; i++) { + if (ns_ids[i] =3D=3D netns_a_id) { + found_sibling_netns =3D true; + break; + } + } + } + + /* We should NOT see the sibling's network namespace */ + write(pipefd2[1], &found_sibling_netns, sizeof(found_sibling_netns)); + close(pipefd2[1]); + exit(0); + } + + /* Parent reads result from second child */ + close(pipefd2[1]); + found_sibling_netns =3D false; + read(pipefd2[0], &found_sibling_netns, sizeof(found_sibling_netns)); + close(pipefd2[0]); + + /* Signal first child to exit */ + close(pipefd[0]); + + /* Wait for both children */ + waitpid(pid2, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + waitpid(pid1, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + /* Second child should NOT have seen first child's namespace */ + ASSERT_FALSE(found_sibling_netns); + TH_LOG("User namespace B correctly could not see sibling namespace A's ne= twork namespace"); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 698543385A5; Tue, 21 Oct 2025 11:47:57 +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=1761047277; cv=none; b=nMjZNFPHnFrPzlpwP8N832LP27uatWGO21FO2bRSrgQxIqwRBtRNpeQ++ir1QNIoj4r990BTsnBJspgeecJxkLvgUjrLKOwXXhC66hqtfOBMyDCwKo7/qFT/A62TNrCWGuSBEYuFyzr+5tRgAE4kfzxEANVx36rATEidB7M8d6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047277; c=relaxed/simple; bh=+NPTtaVGIJjtOfL6a6/pXZ3Jnd+MAnJdtzTqZX7/Ujw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I5et0nRdARzrmT7W2qxWaw8IUyc0XqAz218WXbn2xU8caHQjECZlSLXPVu+W95gxZCWsO2VoEvjKp84fn5dEHK+uERqhKUZdFRT0sW+2AhJ4seGv+1Xb3EPNcNgB/iMNh2689ErBoBf76lhnqqAqadKSb27XFwiqHMGmMsG7O3E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sDgbSmwq; 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="sDgbSmwq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2173C4CEFF; Tue, 21 Oct 2025 11:47:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047277; bh=+NPTtaVGIJjtOfL6a6/pXZ3Jnd+MAnJdtzTqZX7/Ujw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sDgbSmwq898kGjkUjUwVIwoEkgrf7TcaAc55pOq4cCKu3wKjPA1gdS4QJ7T8EXg5Q Rtn7VCQHzcNgDlGdTwOv2P7wCmujE65XhP3tlW5ViHy7EN4qee0hV42d1XPXOTDwRs YTelbwE79ucRHxmV2qGKTm8VrfvKeK5CgKUGl4pEvEi8Yy1+ucW4ZAk+R6GHOcprnO dpNerNU7R2jbZ0DVRKymzrKOwWPMHPL/GqAfMQ91RONRIpzpqAhZ2VFnTq8m3m1fme vEOpMX7nUny83mVla4JT6CagyVHkvb8T5ECepC1bbXkHzDTzXsvLAIOo1goVh17P3x HSoNDJJ3gKSlQ== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:53 +0200 Subject: [PATCH RFC DRAFT 47/50] selftests/namespaces: fourth listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-47-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2557; i=brauner@kernel.org; h=from:subject:message-id; bh=+NPTtaVGIJjtOfL6a6/pXZ3Jnd+MAnJdtzTqZX7/Ujw=; b=kA0DAAoWkcYbwGV43KIByyZiAGj3ce+grmB2YsNoDeIhC/++jqy+s2ytfxIZeAqtBH+rpl649 Ih1BAAWCgAdFiEEQIc0Vx6nDHizMmkokcYbwGV43KIFAmj3ce8ACgkQkcYbwGV43KLLJgD/SwaS xBs0dYddjUyS2N3tRkV+AmeLq+Zm2hikXtm7duIA+wU7pfQwovCuoj28FprhidsfVOsBQoWQ1yv cn0eMYJMO X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test permission checking with LISTNS_CURRENT_USER. Verify that listing with LISTNS_CURRENT_USER respects permissions. Signed-off-by: Christian Brauner --- .../selftests/namespaces/listns_permissions_test.c | 79 ++++++++++++++++++= ++++ 1 file changed, 79 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c index 4e47b4c82c56..ff42109779ca 100644 --- a/tools/testing/selftests/namespaces/listns_permissions_test.c +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -372,4 +372,83 @@ TEST(listns_cannot_see_sibling_userns_namespaces) TH_LOG("User namespace B correctly could not see sibling namespace A's ne= twork namespace"); } =20 +/* + * Test permission checking with LISTNS_CURRENT_USER. + * Verify that listing with LISTNS_CURRENT_USER respects permissions. + */ +TEST(listns_current_user_permissions) +{ + int pipefd[2]; + pid_t pid; + int status; + bool success; + ssize_t count; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D 0, + .spare2 =3D 0, + .user_ns_id =3D LISTNS_CURRENT_USER, + }; + __u64 ns_ids[100]; + ssize_t ret; + bool success; + + close(pipefd[0]); + + /* Create user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Create some namespaces owned by this user namespace */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + if (unshare(CLONE_NEWUTS) < 0) { + close(pipefd[1]); + exit(1); + } + + /* List with LISTNS_CURRENT_USER - should see our owned namespaces */ + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + + success =3D (ret >=3D 3); /* At least user, net, uts */ + write(pipefd[1], &success, sizeof(success)); + write(pipefd[1], &ret, sizeof(ret)); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + success =3D false; + count =3D 0; + read(pipefd[0], &success, sizeof(success)); + read(pipefd[0], &count, sizeof(count)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to setup namespaces"); + } + + ASSERT_TRUE(success); + TH_LOG("LISTNS_CURRENT_USER returned %zd namespaces", count); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 BA34932E6B3; Tue, 21 Oct 2025 11:48:02 +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=1761047282; cv=none; b=jauYDzCvLizPaWeJl67tJtYpkBqSY3Py5Las69oBlnTNxNIXfbgX5P+pG9nYqPThXuaCtQF/yQea0gdanvB9WMlR6KrThD8z0iouu72kwjg8SuIWU0gjpYk2Hb/ZLuuospnG7+n3QJitrgxM80pZ6YYogEoIm+/lGm/oH3CIxFk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047282; c=relaxed/simple; bh=W101eyhrLICscf7roVQMEA8GrDRzuQACPaa4FbASft0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AlIsAJmj2NR/ENUenFYtswarvVbF9jiEGEikyuKnts6EhPkGeCsfjQJDp9ckvRAfAeRpVZ512w4lEibRaPKNEWYTSwXXJscwys/Qkp+Q0QWv53rFMinpWmlMOPIoCa5sHMTuN8WhRe3u9mSvKkDFoSkluMX2ybzKsG5ZHpknRco= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WdnTFMDT; 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="WdnTFMDT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE0B9C4CEF1; Tue, 21 Oct 2025 11:47:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047282; bh=W101eyhrLICscf7roVQMEA8GrDRzuQACPaa4FbASft0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WdnTFMDTwFXHFuujB+n2q93dvk41YRGjdmay+TXzLQ6LD0Bb/PslarbDOzdho3Gb7 YeEfp5WiQJJ4/4HoVeIRvw17bA1S3iECixJrDnGUVbLRnoUPu2RptxKCaDRQ/0k6WV +pG7AmVJOH4+Waoz6w8JVRh3fJcOxNQxd6R0itSsL/1b3a/JT65QlcpqWhVEtN49WO 3QauUsXp1DM+wkCgJFI/kEyDScNIpAySFzfLwgs5+E9MaDDbf0FJxspr9sBojV9mwT /6nzTKf2/vP9koWVgRiX/udBxCokXIoPVhSBx8/nmdXBLz1rhTIvGncy1j8p957Hn1 u0iFn6qKpDkHA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:54 +0200 Subject: [PATCH RFC DRAFT 48/50] selftests/namespaces: fifth listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-48-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3512; i=brauner@kernel.org; h=from:subject:message-id; bh=W101eyhrLICscf7roVQMEA8GrDRzuQACPaa4FbASft0=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3x/9uGUkPPny4S4Ps08+Pa/nK6Myduu369dZsbbl 5tmXDTw7ChlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZjIdWGG/zlSr6K8Q7bOPHIh fHXS4UvWHc5Hyjx0+YsLqmff2TZl3VRGhvcmKjyfHoXJHVx+n7NyRkP1qWvZnjtWdIslppU/m1u VywEA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that CAP_SYS_ADMIN in parent user namespace allows seeing child user namespace's owned namespaces. Signed-off-by: Christian Brauner --- .../selftests/namespaces/listns_permissions_test.c | 122 +++++++++++++++++= ++++ 1 file changed, 122 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c index ff42109779ca..07c0c2be0aa5 100644 --- a/tools/testing/selftests/namespaces/listns_permissions_test.c +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -451,4 +451,126 @@ TEST(listns_current_user_permissions) TH_LOG("LISTNS_CURRENT_USER returned %zd namespaces", count); } =20 +/* + * Test that CAP_SYS_ADMIN in parent user namespace allows seeing + * child user namespace's owned namespaces. + */ +TEST(listns_parent_userns_cap_sys_admin) +{ + int pipefd[2]; + pid_t pid; + int status; + bool found_child_userns; + ssize_t count; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + __u64 parent_userns_id; + __u64 child_userns_id; + struct ns_id_req req; + __u64 ns_ids[100]; + ssize_t ret; + bool found_child_userns; + + close(pipefd[0]); + + /* Create parent user namespace - we have CAP_SYS_ADMIN in it */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get parent user namespace ID */ + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &parent_userns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Create child user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get child user namespace ID */ + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &child_userns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* Create namespaces owned by child user namespace */ + if (unshare(CLONE_NEWNET) < 0) { + close(pipefd[1]); + exit(1); + } + + /* List namespaces owned by parent user namespace */ + req.size =3D sizeof(req); + req.spare =3D 0; + req.ns_id =3D 0; + req.ns_type =3D 0; + req.spare2 =3D 0; + req.user_ns_id =3D parent_userns_id; + + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + + /* Should see child user namespace in the list */ + found_child_userns =3D false; + if (ret > 0) { + for (ssize_t i =3D 0; i < ret; i++) { + if (ns_ids[i] =3D=3D child_userns_id) { + found_child_userns =3D true; + break; + } + } + } + + write(pipefd[1], &found_child_userns, sizeof(found_child_userns)); + write(pipefd[1], &ret, sizeof(ret)); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + found_child_userns =3D false; + count =3D 0; + read(pipefd[0], &found_child_userns, sizeof(found_child_userns)); + read(pipefd[0], &count, sizeof(count)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to setup namespaces"); + } + + ASSERT_TRUE(found_child_userns); + TH_LOG("Process with CAP_SYS_ADMIN in parent user namespace saw child use= r namespace (total: %zd)", + count); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 AC6A7340282; Tue, 21 Oct 2025 11:48:07 +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=1761047287; cv=none; b=kiMEmARdPjo63NfmdTNU8WOrf/DAtlPVggRwgslDvc4E3LiZJmBwseL/IBc6LY1Vxq0bZiet1DHNBX4srixGxPAOGs5holTpm9p1+C/GBD9S5Ok/mzA3AWrXA8Kt1CJmevXkqL6+/5lWcYRrd4OeoulO7pVKceFKcwyNIrEbXWE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047287; c=relaxed/simple; bh=zyvSyEvHN08sO6ilDq1bp8H9I2nWZ5I4e4dJ8kwOeEM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GyCQN9ul07K1TR22OY4rCe/lw7dPggN6lNk+ctrIRUbx+83SiBe3Rz3Zy9Qe440wbfAnodzax+c0vv+gEi1cOldya92Jp6a05vK/hJE1FGo8sZos7gu4DeEXrrwoi2w8u9L4cJVWPleqMBQNZCdgXcg9m5+5A+uZhRMItXo47m4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k56CjcQr; 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="k56CjcQr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B4518C4CEFD; Tue, 21 Oct 2025 11:48:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047287; bh=zyvSyEvHN08sO6ilDq1bp8H9I2nWZ5I4e4dJ8kwOeEM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=k56CjcQrfgL+lHhiTYqs67nqOzI9yjnL60HczgPgk/cbHjhtjU90xZrLGBKG9orB2 s03OMJPSaflfkuWJEkQ/RwHvY7m/pDFhb5ZcDCrtFYaabfCMkSYdyx7JMxspnH6+av FMAsBSr51lbsaQwqv28YpvfBHp7oy6p6EM1BjyTHY/Mz96YnJp4/WCnj4pbNIc31lr +bN9In4VojYUg392Ar4bZ69zyIdY8T1fBw99jXw8LFKoIrow40eS3XS4PY23ZZ3/c8 vB2VDw7QevxzaDEM0ZzNjuDgxXXV3N+S1YQxKV7EXXbTxGO6iLZs4Dx9OGmiiMknNg ogERhEF6SREaA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:55 +0200 Subject: [PATCH RFC DRAFT 49/50] selftests/namespaces: sixth listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-49-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=2704; i=brauner@kernel.org; h=from:subject:message-id; bh=zyvSyEvHN08sO6ilDq1bp8H9I2nWZ5I4e4dJ8kwOeEM=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3yvX7suviu+Wc3jXf/3P2F+Cp7rN8Y9ME1RqLy7o 4qt8/bbjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIlIxTP8zzmeuENn9nLGR21K U1fOdDhsr/Y08uj8cwJO3VOmztj0+wDD/+Ar5u4VnSs+Czm3uDgkHLT2ebtPeJnZzuutoVfZYi3 m8gEA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that we can see user namespaces we have CAP_SYS_ADMIN inside of. This is different from seeing namespaces owned by a user namespace. Signed-off-by: Christian Brauner --- .../selftests/namespaces/listns_permissions_test.c | 90 ++++++++++++++++++= ++++ 1 file changed, 90 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c index 07c0c2be0aa5..709250ce1542 100644 --- a/tools/testing/selftests/namespaces/listns_permissions_test.c +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -573,4 +573,94 @@ TEST(listns_parent_userns_cap_sys_admin) count); } =20 +/* + * Test that we can see user namespaces we have CAP_SYS_ADMIN inside of. + * This is different from seeing namespaces owned by a user namespace. + */ +TEST(listns_cap_sys_admin_inside_userns) +{ + int pipefd[2]; + pid_t pid; + int status; + bool found_ours; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + int fd; + __u64 our_userns_id; + struct ns_id_req req; + __u64 ns_ids[100]; + ssize_t ret; + bool found_ours; + + close(pipefd[0]); + + /* Create user namespace - we have CAP_SYS_ADMIN inside it */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Get our user namespace ID */ + fd =3D open("/proc/self/ns/user", O_RDONLY); + if (fd < 0) { + close(pipefd[1]); + exit(1); + } + + if (ioctl(fd, NS_GET_ID, &our_userns_id) < 0) { + close(fd); + close(pipefd[1]); + exit(1); + } + close(fd); + + /* List all user namespaces globally */ + req.size =3D sizeof(req); + req.spare =3D 0; + req.ns_id =3D 0; + req.ns_type =3D CLONE_NEWUSER; + req.spare2 =3D 0; + req.user_ns_id =3D 0; + + ret =3D sys_listns(&req, ns_ids, ARRAY_SIZE(ns_ids), 0); + + /* We should be able to see our own user namespace */ + found_ours =3D false; + if (ret > 0) { + for (ssize_t i =3D 0; i < ret; i++) { + if (ns_ids[i] =3D=3D our_userns_id) { + found_ours =3D true; + break; + } + } + } + + write(pipefd[1], &found_ours, sizeof(found_ours)); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + found_ours =3D false; + read(pipefd[0], &found_ours, sizeof(found_ours)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to setup namespace"); + } + + ASSERT_TRUE(found_ours); + TH_LOG("Process can see user namespace it has CAP_SYS_ADMIN inside of"); +} + TEST_HARNESS_MAIN --=20 2.47.3 From nobody Sun Feb 8 11:41:09 2026 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 F225B34029B; Tue, 21 Oct 2025 11:48:12 +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=1761047293; cv=none; b=oLOUDV3XgbbEQmlN42VHx6o7fGnyH2aLEo+Sp27VPyiZ7HZ8NPNKDIByFsw+Cgt577GLN3Q6LBihYekO2soI9Em4jP3i+h/lglzVeHuwwCUq8qPRd8KjRR1MHGFXqgMR7B5r/47pma3pcSoU5gec9iI2iTAl6Iz8iiH8PqDK/Dc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761047293; c=relaxed/simple; bh=Jz2qZpRe8+RR2mHCIjuTDi9/gaS5B8ErVeSfakXzmUk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Cor0cmAvOjx6qYcz4n2beO2ZpAchv6Ub5u7EG67/bSPpY5X9DU7R1NseaSpmiEeXlvrVIE9MMv42Lq/IQvM4SgCQprtb6JlDF+7z94Y0yZX0wK7qzRFxUKBKFWs1xwbRi2AuB3jmbpnnEICMWX7FhdxVORh7genhkIJ19JNHZWY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=C4mlpyhI; 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="C4mlpyhI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E1DFC4CEF1; Tue, 21 Oct 2025 11:48:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761047292; bh=Jz2qZpRe8+RR2mHCIjuTDi9/gaS5B8ErVeSfakXzmUk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=C4mlpyhIGvKUgqqLYymipY+q92Q0Y6a8LxZZHPWt8Q9Ms8fcpxI+zKHIRhAGNSY0v 2sFBTo0bbJ/mGEr7zSeIZjxwolrW3hmf5ndAKnPD6nms66SRweZDmq3kEDC4QTQJoJ b3AJJztU7NwjCMT/r/77QwrjfWQmicCSrGNIqCLKxYytRhWPcddLdkMyh7GmTamXMT xvnQRhKlQDkhV6bi+K1bg5IxXOUkbBGBzQPZKdgHxptAutGLmlVSmHbJbiMiJsYmad lcZ2tGpq3i3W59BlICyKrkcgJ4DyN/OKQ04KFg8GtmSRXQu2AhsYnw6stvPUjjue0V iDR251KCbcthA== From: Christian Brauner Date: Tue, 21 Oct 2025 13:43:56 +0200 Subject: [PATCH RFC DRAFT 50/50] selftests/namespaces: seventh listns() permission test 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: <20251021-work-namespace-nstree-listns-v1-50-ad44261a8a5b@kernel.org> References: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org> To: linux-fsdevel@vger.kernel.org, Josef Bacik , Jeff Layton Cc: Jann Horn , Mike Yuan , =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= , Lennart Poettering , Daan De Meyer , Aleksa Sarai , Amir Goldstein , Tejun Heo , Johannes Weiner , Thomas Gleixner , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, bpf@vger.kernel.org, Eric Dumazet , Jakub Kicinski , netdev@vger.kernel.org, Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=3549; i=brauner@kernel.org; h=from:subject:message-id; bh=Jz2qZpRe8+RR2mHCIjuTDi9/gaS5B8ErVeSfakXzmUk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWR8L3x/e8KebWaLVN8qlM2KcXcwOs+8WPUeZ5KJ736P1 34Vc35c7ShlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZiI4xZGhqvfppWEf9T0mB3s 6D9V+Yqkd1LimZ0not0c7//a8X1Clhsjw31D/3O7BCdOus2g/WHNqwtr5yv8fn5KX+iupP6xmU5 SubwA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test that dropping CAP_SYS_ADMIN restricts what we can see. Signed-off-by: Christian Brauner --- .../selftests/namespaces/listns_permissions_test.c | 111 +++++++++++++++++= ++++ 1 file changed, 111 insertions(+) diff --git a/tools/testing/selftests/namespaces/listns_permissions_test.c b= /tools/testing/selftests/namespaces/listns_permissions_test.c index 709250ce1542..9d1767e8b804 100644 --- a/tools/testing/selftests/namespaces/listns_permissions_test.c +++ b/tools/testing/selftests/namespaces/listns_permissions_test.c @@ -663,4 +663,115 @@ TEST(listns_cap_sys_admin_inside_userns) TH_LOG("Process can see user namespace it has CAP_SYS_ADMIN inside of"); } =20 +/* + * Test that dropping CAP_SYS_ADMIN restricts what we can see. + */ +TEST(listns_drop_cap_sys_admin) +{ + cap_t caps; + cap_value_t cap_list[1] =3D { CAP_SYS_ADMIN }; + + /* This test needs to start with CAP_SYS_ADMIN */ + caps =3D cap_get_proc(); + if (!caps) { + SKIP(return, "Cannot get capabilities"); + } + + cap_flag_value_t cap_val; + if (cap_get_flag(caps, CAP_SYS_ADMIN, CAP_EFFECTIVE, &cap_val) < 0) { + cap_free(caps); + SKIP(return, "Cannot check CAP_SYS_ADMIN"); + } + + if (cap_val !=3D CAP_SET) { + cap_free(caps); + SKIP(return, "Test needs CAP_SYS_ADMIN to start"); + } + cap_free(caps); + + int pipefd[2]; + pid_t pid; + int status; + bool correct; + ssize_t count_before, count_after; + + ASSERT_EQ(pipe(pipefd), 0); + + pid =3D fork(); + ASSERT_GE(pid, 0); + + if (pid =3D=3D 0) { + struct ns_id_req req =3D { + .size =3D sizeof(req), + .spare =3D 0, + .ns_id =3D 0, + .ns_type =3D CLONE_NEWNET, + .spare2 =3D 0, + .user_ns_id =3D LISTNS_CURRENT_USER, + }; + __u64 ns_ids_before[100]; + ssize_t count_before; + __u64 ns_ids_after[100]; + ssize_t count_after; + bool correct; + + close(pipefd[0]); + + /* Create user namespace */ + if (setup_userns() < 0) { + close(pipefd[1]); + exit(1); + } + + /* Count namespaces with CAP_SYS_ADMIN */ + count_before =3D sys_listns(&req, ns_ids_before, ARRAY_SIZE(ns_ids_befor= e), 0); + + /* Drop CAP_SYS_ADMIN */ + caps =3D cap_get_proc(); + if (caps) { + cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_list, CAP_CLEAR); + cap_set_flag(caps, CAP_PERMITTED, 1, cap_list, CAP_CLEAR); + cap_set_proc(caps); + cap_free(caps); + } + + /* Ensure we can't regain the capability */ + prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + + /* Count namespaces without CAP_SYS_ADMIN */ + count_after =3D sys_listns(&req, ns_ids_after, ARRAY_SIZE(ns_ids_after),= 0); + + /* Without CAP_SYS_ADMIN, we should see same or fewer namespaces */ + correct =3D (count_after <=3D count_before); + + write(pipefd[1], &correct, sizeof(correct)); + write(pipefd[1], &count_before, sizeof(count_before)); + write(pipefd[1], &count_after, sizeof(count_after)); + close(pipefd[1]); + exit(0); + } + + /* Parent */ + close(pipefd[1]); + + correct =3D false; + count_before =3D 0; + count_after =3D 0; + read(pipefd[0], &correct, sizeof(correct)); + read(pipefd[0], &count_before, sizeof(count_before)); + read(pipefd[0], &count_after, sizeof(count_after)); + close(pipefd[0]); + + waitpid(pid, &status, 0); + ASSERT_TRUE(WIFEXITED(status)); + + if (WEXITSTATUS(status) !=3D 0) { + SKIP(return, "Child failed to setup namespace"); + } + + ASSERT_TRUE(correct); + TH_LOG("With CAP_SYS_ADMIN: %zd namespaces, without: %zd namespaces", + count_before, count_after); +} + TEST_HARNESS_MAIN --=20 2.47.3