From patchwork Tue Jan 28 10:33:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13952419 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 66F4519E965 for ; Tue, 28 Jan 2025 10:34: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=1738060444; cv=none; b=O7VysGRAtQqfypEqrOsKEzrNhQ2AOxDXXimjEOomLsXsg+mAKbQbFOEVlq7AvH4/KONyZj5vv+weM7hBsGWy6c5WUP7ZUq30wFtkMFYBYybL32OoGph1tenFyjYc3b8ohaBuflC3W++OtXbuyQsuIq7nj9jF6CcFq8WRc3g3vbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738060444; c=relaxed/simple; bh=IBRscUIUI6xMwpf16BJSqNB0KlIBXsRA9FwvCpui/gg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fGMJNyU//xUU0vLAt2WptIPqpJgn8/H11OTRIPdrJPlJcqIQKDOw51O5Ido8gOyW7RNn76zE2MSr0oPHx9gxq1Fh/F5hlcJjrEyxXjcTj3nkNrKQc3ErqPZ/BLMv1nQfVDaLqS+uUOzjDWvDikf2bnQXZvHJ1A9pLSEOc8n03wg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q/P5PNmp; 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="q/P5PNmp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6CE72C4CEE5; Tue, 28 Jan 2025 10:34:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1738060443; bh=IBRscUIUI6xMwpf16BJSqNB0KlIBXsRA9FwvCpui/gg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=q/P5PNmpEGHCIByjQCGqW/j2IK69BBD0UvabZzQNlEvna6mWpOnQvkPZEIjiPQnam KdjdVIogR7a+AbnsccbNwipwTGNtnTWR1VLWHr5rs1WL+0gr3P8/WEParxhnl4V0KC OWSr4RQBdkHX0ZjEU/R6GdQxL5EphpUfWoPK2z5Dhy93DKJppk4qsINIDzPTTV3avk 9KwNd9QTUFY3CH88tQgW827FiNlAA9GChgNe4QWleaRNAZ17mUknVvEui6UzfbsSw4 EClvWXc5pCDrKQ/tP0EhOHsnWhItPkbkNLC6YRpFFh/u+B4Gn2xo+MD0VfeZY9SURM G/ZIyhsFcmoOQ== From: Christian Brauner Date: Tue, 28 Jan 2025 11:33:39 +0100 Subject: [PATCH 1/5] fs: add vfs_open_tree() helper Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250128-work-mnt_idmap-update-v2-v1-1-c25feb0d2eb3@kernel.org> References: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> In-Reply-To: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Amir Goldstein , Al Viro , Josef Bacik , Jeff Layton , Jan Kara , Lennart Poettering , Daan De Meyer , Seth Forshee , Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-1b0d6 X-Developer-Signature: v=1; a=openpgp-sha256; l=2701; i=brauner@kernel.org; h=from:subject:message-id; bh=IBRscUIUI6xMwpf16BJSqNB0KlIBXsRA9FwvCpui/gg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTP2DT1oGB2/xR2uw8Rq6/f3SZeMpl/Wtj2nw+feYurX ak0kHDN6yhlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhIzmxGht3up34sr3o/4/Zt lTd7ynm2r/J7zc+SxzNDajU/t8WJ+fMY/kq07RETOZWxgTddLsXZc9H3MPn6Z/NveW2S81w0eff HqewA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Split out vfs_open_tree() from open_tree() so we can use it in later patches. Signed-off-by: Christian Brauner --- fs/namespace.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 4013fbac354a284732eb10e5a869b86184a52d1d..2a8ac568a08d125290ae3cdeeeec3280ea4c1721 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2889,24 +2889,22 @@ static struct file *open_detached_copy(struct path *path, bool recursive) return file; } -SYSCALL_DEFINE3(open_tree, int, dfd, const char __user *, filename, unsigned, flags) +static struct file *vfs_open_tree(int dfd, const char __user *filename, unsigned int flags) { - struct file *file; - struct path path; + int ret; + struct path path __free(path_put) = {}; int lookup_flags = LOOKUP_AUTOMOUNT | LOOKUP_FOLLOW; bool detached = flags & OPEN_TREE_CLONE; - int error; - int fd; BUILD_BUG_ON(OPEN_TREE_CLOEXEC != O_CLOEXEC); if (flags & ~(AT_EMPTY_PATH | AT_NO_AUTOMOUNT | AT_RECURSIVE | AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC)) - return -EINVAL; + return ERR_PTR(-EINVAL); if ((flags & (AT_RECURSIVE | OPEN_TREE_CLONE)) == AT_RECURSIVE) - return -EINVAL; + return ERR_PTR(-EINVAL); if (flags & AT_NO_AUTOMOUNT) lookup_flags &= ~LOOKUP_AUTOMOUNT; @@ -2916,27 +2914,32 @@ SYSCALL_DEFINE3(open_tree, int, dfd, const char __user *, filename, unsigned, fl lookup_flags |= LOOKUP_EMPTY; if (detached && !may_mount()) - return -EPERM; + return ERR_PTR(-EPERM); + + ret = user_path_at(dfd, filename, lookup_flags, &path); + if (unlikely(ret)) + return ERR_PTR(ret); + + if (detached) + return open_detached_copy(&path, flags & AT_RECURSIVE); + + return dentry_open(&path, O_PATH, current_cred()); +} + +SYSCALL_DEFINE3(open_tree, int, dfd, const char __user *, filename, unsigned, flags) +{ + int fd; + struct file *file __free(fput) = NULL; + + file = vfs_open_tree(dfd, filename, flags); + if (IS_ERR(file)) + return PTR_ERR(file); fd = get_unused_fd_flags(flags & O_CLOEXEC); if (fd < 0) return fd; - error = user_path_at(dfd, filename, lookup_flags, &path); - if (unlikely(error)) { - file = ERR_PTR(error); - } else { - if (detached) - file = open_detached_copy(&path, flags & AT_RECURSIVE); - else - file = dentry_open(&path, O_PATH, current_cred()); - path_put(&path); - } - if (IS_ERR(file)) { - put_unused_fd(fd); - return PTR_ERR(file); - } - fd_install(fd, file); + fd_install(fd, no_free_ptr(file)); return fd; } From patchwork Tue Jan 28 10:33:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13952420 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 4726919F104 for ; Tue, 28 Jan 2025 10:34: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=1738060447; cv=none; b=tenuOH4TJxpILIDxwHdaK97iYB0ICRtEpCBVHc3kvsYetd3LAL05OkAXZSjQOS5GPd+qnO0JcoxdrimaEBOmFxYEaCWEguSKi1/hYCjeg/CgcKDDVGQH3dB+EFB+SZR912XbYkTTmzCT6yPeNYqnbV24OaGBRBUdfNU45o4JDws= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738060447; c=relaxed/simple; bh=Y8BskR6ld4M3X7bKNH2f1EupxvCpoYJCPqGHpNiv6Fs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mwxmS4nnMyJ/cl8FsPM4eJH7hdQWRnnet9oHC/76eb7TizcKR9e7di6yin6NU9TlSTGiK/qJy2C3JZgBEz9U3ym7rOCX9I1VZSOuBLx5IzUPamewpgipRLlU0faKqJqAfWXXKiMNfnVSuxLBUm8YfEErSlUWmqBXV0jS1VodBu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kUnWLmkD; 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="kUnWLmkD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 60CCFC4CED3; Tue, 28 Jan 2025 10:34:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1738060446; bh=Y8BskR6ld4M3X7bKNH2f1EupxvCpoYJCPqGHpNiv6Fs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kUnWLmkDGQD86KRAfGTGpJRrJ2ryk2GXBlj+nRA2xdBrf0/Cr849L/BcdJvTPYo9a CEAZ3mVNlpAE9se6GpKuUs3ivb50Zh72pfsmM7YS0aB+0mr7kmECwBjJYjX0LG5MNc vgvAtcp32Wd1/JUaFA3hLGMMRvHhcLYAW+eyp74pKgzQunwBRDs+P+ydHip31/FVjC vjPQK6bXry9ugTIOYGEVLXkdI2/3BX8s5R3ACSe9NPBvHxd6G8bIhnTtzlYEfCI/5n 98e9cgQOe60gNBWcGdAaf6WbrURf76GvgYLaW0vIIWWMCRjwRohzl/+U5iQVQyue4x hpUpvPYumYpPQ== From: Christian Brauner Date: Tue, 28 Jan 2025 11:33:40 +0100 Subject: [PATCH 2/5] fs: add copy_mount_setattr() helper Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250128-work-mnt_idmap-update-v2-v1-2-c25feb0d2eb3@kernel.org> References: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> In-Reply-To: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Amir Goldstein , Al Viro , Josef Bacik , Jeff Layton , Jan Kara , Lennart Poettering , Daan De Meyer , Seth Forshee , Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-1b0d6 X-Developer-Signature: v=1; a=openpgp-sha256; l=4292; i=brauner@kernel.org; h=from:subject:message-id; bh=Y8BskR6ld4M3X7bKNH2f1EupxvCpoYJCPqGHpNiv6Fs=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTP2DRV/tPWkx7Vk1iTD6e4qb//J5b/wWrtXK9tos6Ok 12idkS/6yhlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhI7BNGhub5LaInbs/Rbwn3 lwrZ5t//Mcjx6728lMJZFxhb80x0JjMyLBXO62hX/fql7LRbX9TmJCtO06+r+OZoSzPec0k9Pns KIwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Split out copy_mount_setattr() from mount_setattr() so we can use it in later patches. Signed-off-by: Christian Brauner --- fs/namespace.c | 73 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 2a8ac568a08d125290ae3cdeeeec3280ea4c1721..ef7db39c8776ab13da968d7f69c56698e3846914 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4721,7 +4721,7 @@ static int do_mount_setattr(struct path *path, struct mount_kattr *kattr) } static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, - struct mount_kattr *kattr, unsigned int flags) + struct mount_kattr *kattr) { struct ns_common *ns; struct user_namespace *mnt_userns; @@ -4772,22 +4772,8 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, } static int build_mount_kattr(const struct mount_attr *attr, size_t usize, - struct mount_kattr *kattr, unsigned int flags) + struct mount_kattr *kattr) { - unsigned int lookup_flags = LOOKUP_AUTOMOUNT | LOOKUP_FOLLOW; - - if (flags & AT_NO_AUTOMOUNT) - lookup_flags &= ~LOOKUP_AUTOMOUNT; - if (flags & AT_SYMLINK_NOFOLLOW) - lookup_flags &= ~LOOKUP_FOLLOW; - if (flags & AT_EMPTY_PATH) - lookup_flags |= LOOKUP_EMPTY; - - *kattr = (struct mount_kattr) { - .lookup_flags = lookup_flags, - .recurse = !!(flags & AT_RECURSIVE), - }; - if (attr->propagation & ~MOUNT_SETATTR_PROPAGATION_FLAGS) return -EINVAL; if (hweight32(attr->propagation & MOUNT_SETATTR_PROPAGATION_FLAGS) > 1) @@ -4835,7 +4821,7 @@ static int build_mount_kattr(const struct mount_attr *attr, size_t usize, return -EINVAL; } - return build_mount_idmapped(attr, usize, kattr, flags); + return build_mount_idmapped(attr, usize, kattr); } static void finish_mount_kattr(struct mount_kattr *kattr) @@ -4847,23 +4833,14 @@ static void finish_mount_kattr(struct mount_kattr *kattr) mnt_idmap_put(kattr->mnt_idmap); } -SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, - unsigned int, flags, struct mount_attr __user *, uattr, - size_t, usize) +static int copy_mount_setattr(struct mount_attr __user *uattr, size_t usize, + struct mount_kattr *kattr) { - int err; - struct path target; + int ret; struct mount_attr attr; - struct mount_kattr kattr; BUILD_BUG_ON(sizeof(struct mount_attr) != MOUNT_ATTR_SIZE_VER0); - if (flags & ~(AT_EMPTY_PATH | - AT_RECURSIVE | - AT_SYMLINK_NOFOLLOW | - AT_NO_AUTOMOUNT)) - return -EINVAL; - if (unlikely(usize > PAGE_SIZE)) return -E2BIG; if (unlikely(usize < MOUNT_ATTR_SIZE_VER0)) @@ -4872,9 +4849,9 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, if (!may_mount()) return -EPERM; - err = copy_struct_from_user(&attr, sizeof(attr), uattr, usize); - if (err) - return err; + ret = copy_struct_from_user(&attr, sizeof(attr), uattr, usize); + if (ret) + return ret; /* Don't bother walking through the mounts if this is a nop. */ if (attr.attr_set == 0 && @@ -4882,7 +4859,37 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, attr.propagation == 0) return 0; - err = build_mount_kattr(&attr, usize, &kattr, flags); + return build_mount_kattr(&attr, usize, kattr); +} + +SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, + unsigned int, flags, struct mount_attr __user *, uattr, + size_t, usize) +{ + int err; + struct path target; + struct mount_kattr kattr; + unsigned int lookup_flags = LOOKUP_AUTOMOUNT | LOOKUP_FOLLOW; + + if (flags & ~(AT_EMPTY_PATH | + AT_RECURSIVE | + AT_SYMLINK_NOFOLLOW | + AT_NO_AUTOMOUNT)) + return -EINVAL; + + if (flags & AT_NO_AUTOMOUNT) + lookup_flags &= ~LOOKUP_AUTOMOUNT; + if (flags & AT_SYMLINK_NOFOLLOW) + lookup_flags &= ~LOOKUP_FOLLOW; + if (flags & AT_EMPTY_PATH) + lookup_flags |= LOOKUP_EMPTY; + + kattr = (struct mount_kattr) { + .lookup_flags = lookup_flags, + .recurse = !!(flags & AT_RECURSIVE), + }; + + err = copy_mount_setattr(uattr, usize, &kattr); if (err) return err; From patchwork Tue Jan 28 10:33:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13952421 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 37C6F19F135 for ; Tue, 28 Jan 2025 10:34: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=1738060450; cv=none; b=V6dWwHKeIRKErdprDwOpvVT+R9EdIjVEy5Spi+9h6rMap/sTr3avxdeQ/0HYuSVKBNUVqsh5f69nJgKUqrEOSJbPODGOzj7DfC2+56u6esHGhNR1CLhk8xB0oeiuAJa1lQWPkpI9imB+2/4oFLTvOhZAbLLWQWqQ5BaquYM/4J0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738060450; c=relaxed/simple; bh=l5Skrm9EWdfc/SzE8hRuoLDcjPQDcYV42cNxO/WZkf8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tNat/yvGsCxg/N6E730S+II9hEYCSs1dyzn21VwUJHW8HlLQlIJaWBENja7+CGLpMjbMpZPloJJzMGkZ3Q7DfPcYcUcIcDvHkw3RS5i32FZBPFDVym3ZsF+7Cod8+VNiwHbYvghfWgF8AEBfrGq7drQH7J0mwT3o8P1h5m32yUU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SXqxE6d4; 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="SXqxE6d4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 410F9C4CEE3; Tue, 28 Jan 2025 10:34:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1738060449; bh=l5Skrm9EWdfc/SzE8hRuoLDcjPQDcYV42cNxO/WZkf8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SXqxE6d4Qw85zBEPp5AzknRPzZZRgFnDe1ttYjtLKV7kk0QNKKG1HlLqOsXG1Wt/5 jqL69t0SbEePiOL2rMW7FSeibfRXGgZYUBI9DGeZzx6K0LQmHOMvGCEmUTOeVJTzRj My/n+wMYqg+pm8gpxPq+Uvs+cEbZPbbpFUgdDyrg3aRuXGC1/Nsl2UEIhl3K4rewSw oaF0G/pNhOi2cmxu8k3anJ8qFCQJ3nRMOP6fPLd4xcUUbIlY8qjLOFEFCh2UyL1Zza oFEos4dTPoLwvYzOUhsJllTSVxl328yQ0jU+K3dya/fUXncybfcXLzSXXugM/OulBB BDd9ikXTFMl0g== From: Christian Brauner Date: Tue, 28 Jan 2025 11:33:41 +0100 Subject: [PATCH 3/5] fs: add open_tree_attr() Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250128-work-mnt_idmap-update-v2-v1-3-c25feb0d2eb3@kernel.org> References: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> In-Reply-To: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Amir Goldstein , Al Viro , Josef Bacik , Jeff Layton , Jan Kara , Lennart Poettering , Daan De Meyer , Seth Forshee , Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-1b0d6 X-Developer-Signature: v=1; a=openpgp-sha256; l=12503; i=brauner@kernel.org; h=from:subject:message-id; bh=l5Skrm9EWdfc/SzE8hRuoLDcjPQDcYV42cNxO/WZkf8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTP2DTt0JpNFmtP+an4mP/uT3fYbyP5cq3o/+aNBQeDy sQ9QxjjOkpZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACayuYuR4dXs2pL+Y1rJ6l9y bUXrb0sGH9n5uIfTZfmsLn6HClkGV4a/EsXXV93n+n448yTb9ApNm38H76rs/HD0H3uXZVz5BCk DXgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add open_tree_attr() which allow to atomically create a detached mount tree and set mount options on it. If OPEN_TREE_CLONE is used this will allow the creation of a detached mount with a new set of mount options without it ever being exposed to userspace without that set of mount options applied. 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 + fs/namespace.c | 39 +++++++++++++++++++++++++++++ include/linux/syscalls.h | 4 +++ include/uapi/asm-generic/unistd.h | 4 ++- scripts/syscall.tbl | 1 + 20 files changed, 63 insertions(+), 1 deletion(-) diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index c59d53d6d3f3490f976ca179ddfe02e69265ae4d..2dd6340de6b4efddc406f0c235701c15cf02f650 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -506,3 +506,4 @@ 574 common getxattrat sys_getxattrat 575 common listxattrat sys_listxattrat 576 common removexattrat sys_removexattrat +577 common open_tree_attr sys_open_tree_attr diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 49eeb2ad8dbd8e074c6240417693f23fb328afa8..27c1d5ebcd91c8c296dc6676307f66bfdf4ab78d 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -481,3 +481,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/arm64/tools/syscall_32.tbl b/arch/arm64/tools/syscall_32.tbl index 69a829912a05eb8a3e21ed701d1030e31c0148bc..0765b3a8d6d600d7b9f83182d401d9f80c03476c 100644 --- a/arch/arm64/tools/syscall_32.tbl +++ b/arch/arm64/tools/syscall_32.tbl @@ -478,3 +478,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl index f5ed71f1910d09769c845c2d062d99ee0449437c..9fe47112c586f152662af38a9a7f90957cb96cf8 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -466,3 +466,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl index 680f568b77f2cbefc3eacb2517f276041f229b1e..7b6e97828e552d4da90046ddfcd4a55723e522bb 100644 --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl @@ -472,3 +472,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl index 0b9b7e25b69ad592642f8533bee9ccfe95ce9626..aa70e371bb54ab5d9c8dd8923b6ecf9693ee914d 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -405,3 +405,4 @@ 464 n32 getxattrat sys_getxattrat 465 n32 listxattrat sys_listxattrat 466 n32 removexattrat sys_removexattrat +467 n32 open_tree_attr sys_open_tree_attr diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl index c844cd5cda620b2809a397cdd6f4315ab6a1bfe2..1e8c44c7b61492eabf00c777831e457a7a6e579c 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -381,3 +381,4 @@ 464 n64 getxattrat sys_getxattrat 465 n64 listxattrat sys_listxattrat 466 n64 removexattrat sys_removexattrat +467 n64 open_tree_attr sys_open_tree_attr diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl index e8a57c2067580618f4635f9582bcec4c4b2a92c5..dbbba6c4465f6af5124c8c9f1ade4da8c5407ca6 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -454,3 +454,4 @@ 464 o32 getxattrat sys_getxattrat 465 o32 listxattrat sys_listxattrat 466 o32 removexattrat sys_removexattrat +467 o32 open_tree_attr sys_open_tree_attr diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index d9fc94c869657fcfbd7aca1d5f5abc9fae2fb9d8..94df3cb957e9d547d192e8732c0cf23ef2b5ce5d 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -465,3 +465,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index d8b4ab78bef076bd50d49b87dea5060fd8c1686a..9a084bdb892694bc562f514b55212d167cbac12f 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -557,3 +557,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index e9115b4d8b635b846e5c9ad6ce229605323723a5..a4569b96ef06c54ce7aa795d039541c90a38284f 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -469,3 +469,4 @@ 464 common getxattrat sys_getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl index c8cad33bf250ea110de37bd1407f5a43ec5e38f2..52a7652fcff6394b96ace1f3b0ed72250ee5e669 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -470,3 +470,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index 727f99d333b304b3db0711953a3d91ece18a28eb..83e45eb6c095a36baaf749927628e6052fe900e6 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -512,3 +512,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index 4d0fb2fba7e208ae9455459afe11e277321d9f74..3f0ec87d5db4e290c62e2ffa6391a431a00dd36a 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -472,3 +472,4 @@ 464 i386 getxattrat sys_getxattrat 465 i386 listxattrat sys_listxattrat 466 i386 removexattrat sys_removexattrat +467 i386 open_tree_attr sys_open_tree_attr diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 5eb708bff1c791debd6cfc5322583b2ae53f6437..cfb5ca41e30de1a4e073750096f5b51a2ec137d2 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -390,6 +390,7 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr # # Due to a historical design error, certain syscalls are numbered differently diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl index 37effc1b134eea061f2c350c1d68b4436b65a4dd..f657a77314f8667fa019a01e10c84ea270024adc 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -437,3 +437,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/fs/namespace.c b/fs/namespace.c index ef7db39c8776ab13da968d7f69c56698e3846914..2a188a6c8df2bceed61c86877e91b87fd154c5a0 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4902,6 +4902,45 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, return err; } +SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename, + unsigned, flags, struct mount_attr __user *, uattr, + size_t, usize) +{ + struct file __free(fput) *file = NULL; + int fd; + + if (!uattr && usize) + return -EINVAL; + + file = vfs_open_tree(dfd, filename, flags); + if (IS_ERR(file)) + return PTR_ERR(file); + + if (uattr) { + int ret; + struct mount_kattr kattr = { + .recurse = !!(flags & AT_RECURSIVE), + }; + + ret = copy_mount_setattr(uattr, usize, &kattr); + if (ret) + return ret; + + ret = do_mount_setattr(&file->f_path, &kattr); + if (ret) + return ret; + + finish_mount_kattr(&kattr); + } + + fd = get_unused_fd_flags(flags & O_CLOEXEC); + if (fd < 0) + return fd; + + fd_install(fd, no_free_ptr(file)); + return fd; +} + int show_path(struct seq_file *m, struct dentry *root) { if (root->d_sb->s_op->show_path) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c6333204d45130eb022f6db460eea34a1f6e91db..079ea1d09d85e60bd87fbbe66e1b2f551705c56d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -951,6 +951,10 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len, int flags, uint32_t sig); asmlinkage long sys_open_tree(int dfd, const char __user *path, unsigned flags); +asmlinkage long sys_open_tree_attr(int dfd, const char __user *path, + unsigned flags, + struct mount_attr __user *uattr, + size_t usize); asmlinkage long sys_move_mount(int from_dfd, const char __user *from_path, int to_dfd, const char __user *to_path, unsigned int ms_flags); diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 88dc393c2bca38c0fa1b3fae579f7cfe4931223c..2892a45023af6d3eb941623d4fed04841ab07e02 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -849,9 +849,11 @@ __SYSCALL(__NR_getxattrat, sys_getxattrat) __SYSCALL(__NR_listxattrat, sys_listxattrat) #define __NR_removexattrat 466 __SYSCALL(__NR_removexattrat, sys_removexattrat) +#define __NR_open_tree_attr 467 +__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr) #undef __NR_syscalls -#define __NR_syscalls 467 +#define __NR_syscalls 468 /* * 32 bit systems traditionally used different diff --git a/scripts/syscall.tbl b/scripts/syscall.tbl index ebbdb3c42e9f74613b003014c0baf44c842bb756..580b4e246aecd5f07d542943ba68fc4ed5961660 100644 --- a/scripts/syscall.tbl +++ b/scripts/syscall.tbl @@ -407,3 +407,4 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr From patchwork Tue Jan 28 10:33:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13952422 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 C7B7619F438 for ; Tue, 28 Jan 2025 10:34: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=1738060452; cv=none; b=UQfN1RWTjf0Asq0fXBImsH75qs49ADujBzg5x4pEq2bycRu1T7wGN85TEBeB4dfHeUpXt7LUfmmAf6iT2EI2GyK5/8/7E7r191Q9tKfY8ASbE5Ki3Jh1kKdl+3/znG0aoQzV5B3Ywe3vg2vSKdt32TLewDnv0lL10yVQGlus0jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738060452; c=relaxed/simple; bh=mKrbP1RlZ4IXxNfE4ieSzr34lEjsrChFcqwRTQWD/jA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=l+hdmRIlJX6Lu/CE3zN28y1fIbEZNsFfxHV+6QVwPdNW57rrK/qt35o2jrmOq2P+5dZrTg3ZP38Dn//fXOZtjtDCEHotneZWpSzfcOYwb7wIfQRKrD2cFb8IOSNaNX9GYrSjwx+ZSuDTxf1gDpfRSd0wCeII6mlzlTKEfKJIznM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RfAgQiAP; 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="RfAgQiAP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 39A56C4CEE4; Tue, 28 Jan 2025 10:34:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1738060452; bh=mKrbP1RlZ4IXxNfE4ieSzr34lEjsrChFcqwRTQWD/jA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RfAgQiAPKybyedxMoiw77wGUobQAL49pATqxxcTSND6M020/2ZbVRLJ39rNS4vt9o x+xvcWD6X6yHX51NgMXBFZnWmnxP51JkAiCiks7fodfuTPte0kWSymedB93BzFRoY2 RB1d7w84dpJ79AI6xTOGBVsfbHkG9g7F80OpD1+GxfdGuK4eQRf9NQCTeKsQn5SCiH ddayZq/I+SH2gZsBEQ/b2LoONjw6WR5RKM5t5y6ir/I2nGkiuWareJ8hC3KwLIY7L/ bZMHOtZd9ywgBbi577KgzjQPev1/Z0oV23MnkupwdLIJTZV5dOmhXZONiimrDaH881 uA9uRCjNC1M+Q== From: Christian Brauner Date: Tue, 28 Jan 2025 11:33:42 +0100 Subject: [PATCH 4/5] fs: add kflags member to struct mount_kattr Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250128-work-mnt_idmap-update-v2-v1-4-c25feb0d2eb3@kernel.org> References: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> In-Reply-To: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Amir Goldstein , Al Viro , Josef Bacik , Jeff Layton , Jan Kara , Lennart Poettering , Daan De Meyer , Seth Forshee , Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-1b0d6 X-Developer-Signature: v=1; a=openpgp-sha256; l=2638; i=brauner@kernel.org; h=from:subject:message-id; bh=mKrbP1RlZ4IXxNfE4ieSzr34lEjsrChFcqwRTQWD/jA=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTP2DTtz+bHpUp6r56X2+znf1z+qTtuzkJDld1sjLlW4 qavl4S4d5SyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEzk62lGhre3Li62T+M8tp1v ZtIs1hMMl5RV1ny+mvPKR/FI5EWn6nJGhl1BKfO0hLjT30d4snCaGz3NPeI0XfPf+1CRK2rrG4V 5uAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Instead of using a boolean use a flag so we can add new flags in following patches. Signed-off-by: Christian Brauner --- fs/namespace.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 2a188a6c8df2bceed61c86877e91b87fd154c5a0..2405f839202b3916bcdc4304599996a55ce5deb7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -84,12 +84,16 @@ static DEFINE_SEQLOCK(mnt_ns_tree_lock); static struct rb_root mnt_ns_tree = RB_ROOT; /* protected by mnt_ns_tree_lock */ static LIST_HEAD(mnt_ns_list); /* protected by mnt_ns_tree_lock */ +enum mount_kattr_flags_t { + MOUNT_KATTR_RECURSE = (1 << 0), +}; + struct mount_kattr { unsigned int attr_set; unsigned int attr_clr; unsigned int propagation; unsigned int lookup_flags; - bool recurse; + enum mount_kattr_flags_t kflags; struct user_namespace *mnt_userns; struct mnt_idmap *mnt_idmap; }; @@ -4579,7 +4583,7 @@ static int mount_setattr_prepare(struct mount_kattr *kattr, struct mount *mnt) break; } - if (!kattr->recurse) + if (!(kattr->kflags & MOUNT_KATTR_RECURSE)) return 0; } @@ -4640,7 +4644,7 @@ static void mount_setattr_commit(struct mount_kattr *kattr, struct mount *mnt) if (kattr->propagation) change_mnt_propagation(m, kattr->propagation); - if (!kattr->recurse) + if (!(kattr->kflags & MOUNT_KATTR_RECURSE)) break; } touch_mnt_namespace(mnt->mnt_ns); @@ -4670,7 +4674,7 @@ static int do_mount_setattr(struct path *path, struct mount_kattr *kattr) */ namespace_lock(); if (kattr->propagation == MS_SHARED) { - err = invent_group_ids(mnt, kattr->recurse); + err = invent_group_ids(mnt, kattr->kflags & MOUNT_KATTR_RECURSE); if (err) { namespace_unlock(); return err; @@ -4886,9 +4890,11 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, kattr = (struct mount_kattr) { .lookup_flags = lookup_flags, - .recurse = !!(flags & AT_RECURSIVE), }; + if (flags & AT_RECURSIVE) + kattr.kflags |= MOUNT_KATTR_RECURSE; + err = copy_mount_setattr(uattr, usize, &kattr); if (err) return err; @@ -4918,9 +4924,10 @@ SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename, if (uattr) { int ret; - struct mount_kattr kattr = { - .recurse = !!(flags & AT_RECURSIVE), - }; + struct mount_kattr kattr = {}; + + if (flags & AT_RECURSIVE) + kattr.kflags |= MOUNT_KATTR_RECURSE; ret = copy_mount_setattr(uattr, usize, &kattr); if (ret) From patchwork Tue Jan 28 10:33:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13952423 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 18E621A00F2 for ; Tue, 28 Jan 2025 10:34: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=1738060457; cv=none; b=MPg0+i1E0Bcg7bKi8cZaLtLLRnRXrFQ7TsB9BhZ5D11Kv7bOtl0tS99qu88OOnZzSSBmnjhvpA919tb13OpOFBV1VMnj+gzGoGnk5w/dxD0/cZsil9vbzxpAttDaVZkWY8f1er+PWwCjmTI3F32gj5Dnasdad8KF+2YsijwWniI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738060457; c=relaxed/simple; bh=GxNn3m7pFY1XpP8XNi22kWt9J2oDrzLmQKuPaEu5Fnw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UDEDFYRJ5ODa50lGIOAbLKKekDv/Gd3SKCk0S3bNU7fqEkTQRdhj/+M3lGm1lwwOKQMKGKV/IzMCyzvaEQmmboodhWBxmnMw8rj9VSg82T4RYvg+2fR27OR4lNTLvzY7bTBTaE+Rd4g92WSCHKIaHh3LmMJXO8M6y6C0Jil7CT4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A30bnOel; 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="A30bnOel" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2A334C4CEE4; Tue, 28 Jan 2025 10:34:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1738060455; bh=GxNn3m7pFY1XpP8XNi22kWt9J2oDrzLmQKuPaEu5Fnw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=A30bnOel+fHf3yRBvrU9MdChsL5UxRkttutn/LA16n8cdAtPM+3nMzsVjMooiZ8pG E/gk2bvPKt+kJ8PpXramXitY0m1o8djj82jDs5awN+ODzLtDcmJnl0ACQAgI88tr50 Iizjb4kaWPTkB7R387WBJpKcpwh8kbAvX6dlPQ9944dGFfUh40wrD4XnufffMh1ClS dcl3JBFrZTHl2Zz2J2zN5joaCfhSTFVvUnGN4vqsd+TWITyglPmncC/JIaIKOUM7CN vUGMbghpm3Qny1LkPKhgfbqYq6mPkstt40AO2PiM3VyBm+k3MCSzy43EJlF58LLT4+ C4ysgGXpASOWA== From: Christian Brauner Date: Tue, 28 Jan 2025 11:33:43 +0100 Subject: [PATCH 5/5] fs: allow changing idmappings Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250128-work-mnt_idmap-update-v2-v1-5-c25feb0d2eb3@kernel.org> References: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> In-Reply-To: <20250128-work-mnt_idmap-update-v2-v1-0-c25feb0d2eb3@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Amir Goldstein , Al Viro , Josef Bacik , Jeff Layton , Jan Kara , Lennart Poettering , Daan De Meyer , Seth Forshee , Arnd Bergmann , Christian Brauner X-Mailer: b4 0.15-dev-1b0d6 X-Developer-Signature: v=1; a=openpgp-sha256; l=4507; i=brauner@kernel.org; h=from:subject:message-id; bh=GxNn3m7pFY1XpP8XNi22kWt9J2oDrzLmQKuPaEu5Fnw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTP2DStb/6b395lh6b+l7t55/Kjvzp2O9P2/bd+O9fyQ eZON5XciI5SFgYxLgZZMUUWh3aTcLnlPBWbjTI1YOawMoEMYeDiFICJpL1nZGjvX5wmcEzi3aOv fstlJysar3kYmh9x4P6xnLDiSdm7OWYz/M95c+RNwqbPV9x2CGsr1VnYGB++NjE4s/CgRdCba69 OHOIAAA== X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 This patchset makes it possible to create a new idmapped mount from an already idmapped mount and to clear idmappings. // Create a first idmapped mount struct mount_attr attr = { .attr_set = MOUNT_ATTR_IDMAP .userns_fd = fd_userns }; fd_tree = open_tree(-EBADF, "/", OPEN_TREE_CLONE, &attr, sizeof(attr)); move_mount(fd_tree, "", -EBADF, "/mnt", MOVE_MOUNT_F_EMPTY_PATH); // Create a second idmapped mount from the first idmapped mount attr.attr_set = MOUNT_ATTR_IDMAP; attr.userns_fd = fd_userns2; fd_tree2 = open_tree(-EBADF, "/mnt", OPEN_TREE_CLONE, &attr, sizeof(attr)); // Create a second non-idmapped mount from the first idmapped mount: memset(&attr, 0, sizeof(attr)); attr.attr_clr = MOUNT_ATTR_IDMAP; fd_tree2 = open_tree(-EBADF, "/mnt", OPEN_TREE_CLONE, &attr, sizeof(attr)); Signed-off-by: Christian Brauner --- fs/namespace.c | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 2405f839202b3916bcdc4304599996a55ce5deb7..453edc27b2a46c6b6c9a321af8769f3ee1de147a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -86,6 +86,7 @@ static LIST_HEAD(mnt_ns_list); /* protected by mnt_ns_tree_lock */ enum mount_kattr_flags_t { MOUNT_KATTR_RECURSE = (1 << 0), + MOUNT_KATTR_IDMAP_REPLACE = (1 << 1), }; struct mount_kattr { @@ -4519,11 +4520,10 @@ static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) return -EINVAL; /* - * Once a mount has been idmapped we don't allow it to change its - * mapping. It makes things simpler and callers can just create - * another bind-mount they can idmap if they want to. + * We only allow an mount to change it's idmapping if it has + * never been accessible to userspace. */ - if (is_idmapped_mnt(m)) + if (!(kattr->kflags & MOUNT_KATTR_IDMAP_REPLACE) && is_idmapped_mnt(m)) return -EPERM; /* The underlying filesystem doesn't support idmapped mounts yet. */ @@ -4613,18 +4613,16 @@ static int mount_setattr_prepare(struct mount_kattr *kattr, struct mount *mnt) static void do_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) { + struct mnt_idmap *old_idmap; + if (!kattr->mnt_idmap) return; - /* - * Pairs with smp_load_acquire() in mnt_idmap(). - * - * Since we only allow a mount to change the idmapping once and - * verified this in can_idmap_mount() we know that the mount has - * @nop_mnt_idmap attached to it. So there's no need to drop any - * references. - */ + old_idmap = mnt_idmap(&mnt->mnt); + + /* Pairs with smp_load_acquire() in mnt_idmap(). */ smp_store_release(&mnt->mnt.mnt_idmap, mnt_idmap_get(kattr->mnt_idmap)); + mnt_idmap_put(old_idmap); } static void mount_setattr_commit(struct mount_kattr *kattr, struct mount *mnt) @@ -4733,13 +4731,23 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP)) return 0; - /* - * We currently do not support clearing an idmapped mount. If this ever - * is a use-case we can revisit this but for now let's keep it simple - * and not allow it. - */ - if (attr->attr_clr & MOUNT_ATTR_IDMAP) - return -EINVAL; + if (attr->attr_clr & MOUNT_ATTR_IDMAP) { + /* + * We can only remove an idmapping if it's never been + * exposed to userspace. + */ + if (!(kattr->kflags & MOUNT_KATTR_IDMAP_REPLACE)) + return -EINVAL; + + /* + * Removal of idmappings is equivalent to setting + * nop_mnt_idmap. + */ + if (!(attr->attr_set & MOUNT_ATTR_IDMAP)) { + kattr->mnt_idmap = &nop_mnt_idmap; + return 0; + } + } if (attr->userns_fd > INT_MAX) return -EINVAL; @@ -4830,8 +4838,10 @@ static int build_mount_kattr(const struct mount_attr *attr, size_t usize, static void finish_mount_kattr(struct mount_kattr *kattr) { - put_user_ns(kattr->mnt_userns); - kattr->mnt_userns = NULL; + if (kattr->mnt_userns) { + put_user_ns(kattr->mnt_userns); + kattr->mnt_userns = NULL; + } if (kattr->mnt_idmap) mnt_idmap_put(kattr->mnt_idmap); @@ -4926,6 +4936,7 @@ SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename, int ret; struct mount_kattr kattr = {}; + kattr.kflags = MOUNT_KATTR_IDMAP_REPLACE; if (flags & AT_RECURSIVE) kattr.kflags |= MOUNT_KATTR_RECURSE;