From patchwork Wed Nov 22 12:44:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13464762 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 088314D10B for ; Wed, 22 Nov 2023 12:44:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EkXobvd6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C0859C433C7; Wed, 22 Nov 2023 12:44:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700657094; bh=bh+RhuUSY0u6U+8qlDB7mjHHPW8EueOuRxZPnyhYibc=; h=From:Date:Subject:References:In-Reply-To:To:From; b=EkXobvd6+XGKRu54sXwZZZZFgRelQjWH+YiEgKpfpRHcIiw14C37/273itgDknhH4 TFjMATCRqQED5iMMx88QoQROLnd3DcNI+0nNvQ9F28d5j2nSvrVn8dVSgFI0HXdeoV mr0aBOsDABtZzmnuvYTg8fXrSFrIw7CvYToXMUGAMGBxqSGuOnITBYDDoDNdBQoPk+ amKZAFoHILv8qtUr72WirGyeF+yPTp26j+/wxwEmYjPCcz1jM+AOi/B2lceMqFt7BH U37MUeKLrW6q+Veqr4QIRJiOXjlDHWQiubn9wVJPGBRX4Jq9z+RJmU8H3rPT0TZugD sUziyaif57FHg== From: Christian Brauner Date: Wed, 22 Nov 2023 13:44:37 +0100 Subject: [PATCH 1/4] mnt_idmapping: remove check_fsmapping() Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231122-vfs-mnt_idmap-v1-1-dae4abdde5bd@kernel.org> References: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> In-Reply-To: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> To: linux-fsdevel@vger.kernel.org, Seth Forshee , Christian Brauner X-Mailer: b4 0.13-dev-26615 X-Developer-Signature: v=1; a=openpgp-sha256; l=2388; i=brauner@kernel.org; h=from:subject:message-id; bh=bh+RhuUSY0u6U+8qlDB7mjHHPW8EueOuRxZPnyhYibc=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTGfj/88nD9/WNBZWmnS66zrLp0/8Yxm58Ce8OvOP306 PXcJlkxq6OUhUGMi0FWTJHFod0kXG45T8Vmo0wNmDmsTCBDGLg4BWAiFyYyMnR1CPOy8Knqf7SN E+zSKWe/9TuJ68KydQLrvrwX3nTtHgsjw7R2w9P1DV33u54xflQ/UZJfEPrmeJvFh/dzYn6suBl 3lA8A X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 The helper is a bit pointless. Just open-code the check. Signed-off-by: Christian Brauner --- fs/mnt_idmapping.c | 17 ++--------------- fs/namespace.c | 2 +- include/linux/mnt_idmapping.h | 3 --- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c index 57d1dedf3f8f..2674942311c3 100644 --- a/fs/mnt_idmapping.c +++ b/fs/mnt_idmapping.c @@ -25,19 +25,6 @@ struct mnt_idmap nop_mnt_idmap = { }; EXPORT_SYMBOL_GPL(nop_mnt_idmap); -/** - * check_fsmapping - check whether an mount idmapping is allowed - * @idmap: idmap of the relevent mount - * @sb: super block of the filesystem - * - * Return: true if @idmap is allowed, false if not. - */ -bool check_fsmapping(const struct mnt_idmap *idmap, - const struct super_block *sb) -{ - return idmap->owner != sb->s_user_ns; -} - /** * initial_idmapping - check whether this is the initial mapping * @ns: idmapping to check @@ -94,8 +81,8 @@ static inline bool no_idmapping(const struct user_namespace *mnt_userns, */ vfsuid_t make_vfsuid(struct mnt_idmap *idmap, - struct user_namespace *fs_userns, - kuid_t kuid) + struct user_namespace *fs_userns, + kuid_t kuid) { uid_t uid; struct user_namespace *mnt_userns = idmap->owner; diff --git a/fs/namespace.c b/fs/namespace.c index fbf0e596fcd3..736baf07115c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4288,7 +4288,7 @@ static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) * Creating an idmapped mount with the filesystem wide idmapping * doesn't make sense so block that. We don't allow mushy semantics. */ - if (!check_fsmapping(kattr->mnt_idmap, m->mnt_sb)) + if (kattr->mnt_userns == m->mnt_sb->s_user_ns) return -EINVAL; /* diff --git a/include/linux/mnt_idmapping.h b/include/linux/mnt_idmapping.h index b8da2db4ecd2..cd4d5c8781f5 100644 --- a/include/linux/mnt_idmapping.h +++ b/include/linux/mnt_idmapping.h @@ -244,7 +244,4 @@ static inline kgid_t mapped_fsgid(struct mnt_idmap *idmap, return from_vfsgid(idmap, fs_userns, VFSGIDT_INIT(current_fsgid())); } -bool check_fsmapping(const struct mnt_idmap *idmap, - const struct super_block *sb); - #endif /* _LINUX_MNT_IDMAPPING_H */ From patchwork Wed Nov 22 12:44:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13464763 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 452C64D10B for ; Wed, 22 Nov 2023 12:44:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fQahI3T8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 04915C433C9; Wed, 22 Nov 2023 12:44:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700657095; bh=JwWBrAaZpvHJTpdhGpdS9t7GETXOmA8d0qV90iLlbSg=; h=From:Date:Subject:References:In-Reply-To:To:From; b=fQahI3T8oG+OG9IW///0Ux/6vVKTrKlNelWCKgUzlPHKGZSFdjZxWJFlIp0KckBSo 9oYjcbIwMXQG5JdLURr7axl2E7dQYJkwGVvvQ2vO0cM12dAxLK5PWo4AoJIR62VTq1 uLt4ekebML/DFagoAchCtpXeKqAUqSDmM5CnlpxSaiaqVJvWZ9QYMigwfbk3AW1bmt Rn2RSh8cLnvLdCSyNUot7f++A3T/90pui9WcvaBcL+lOmZ3a/uAWjZJI9sfP4/+Pi8 PrEej/OgZwNyu53PWcx4FFdCppvaHEiONmHBKfW8G/G+I7P2X4L1VlNg1m0yb9FqGe rUo1yjP3vYgLA== From: Christian Brauner Date: Wed, 22 Nov 2023 13:44:38 +0100 Subject: [PATCH 2/4] mnt_idmapping: remove nop check Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231122-vfs-mnt_idmap-v1-2-dae4abdde5bd@kernel.org> References: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> In-Reply-To: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> To: linux-fsdevel@vger.kernel.org, Seth Forshee , Christian Brauner X-Mailer: b4 0.13-dev-26615 X-Developer-Signature: v=1; a=openpgp-sha256; l=4252; i=brauner@kernel.org; h=from:subject:message-id; bh=JwWBrAaZpvHJTpdhGpdS9t7GETXOmA8d0qV90iLlbSg=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTGfj98ateVo0IzWc6dZ+R51yLYUy20a329cto/0UsXd mxd23LqekcpC4MYF4OsmCKLQ7tJuNxynorNRpkaMHNYmUCGMHBxCsBEnvcyMizOlu9qNE58rfVD /Jz/H1YOfrUT2sfmycvOr9+VtkSOKY3hD6/TJgnrwN8yxdMqRJTusfw+Ozf6uRKDhrF4cL6JmOx HfgA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 All mounts default to nop_mnt_idmap and we don't allow creating idmapped mounts that reuse the idmapping of the filesystem. So unless someone passes a non-superblock namespace to these helpers this check will always be false. Remove it and replace it with a simple check for nop_mnt_idmap. Signed-off-by: Christian Brauner --- fs/mnt_idmapping.c | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c index 2674942311c3..35d78cb3c38a 100644 --- a/fs/mnt_idmapping.c +++ b/fs/mnt_idmapping.c @@ -39,26 +39,6 @@ static inline bool initial_idmapping(const struct user_namespace *ns) return ns == &init_user_ns; } -/** - * no_idmapping - check whether we can skip remapping a kuid/gid - * @mnt_userns: the mount's idmapping - * @fs_userns: the filesystem's idmapping - * - * This function can be used to check whether a remapping between two - * idmappings is required. - * An idmapped mount is a mount that has an idmapping attached to it that - * is different from the filsystem's idmapping and the initial idmapping. - * If the initial mapping is used or the idmapping of the mount and the - * filesystem are identical no remapping is required. - * - * Return: true if remapping can be skipped, false if not. - */ -static inline bool no_idmapping(const struct user_namespace *mnt_userns, - const struct user_namespace *fs_userns) -{ - return initial_idmapping(mnt_userns) || mnt_userns == fs_userns; -} - /** * make_vfsuid - map a filesystem kuid according to an idmapping * @idmap: the mount's idmapping @@ -68,8 +48,8 @@ static inline bool no_idmapping(const struct user_namespace *mnt_userns, * Take a @kuid and remap it from @fs_userns into @idmap. Use this * function when preparing a @kuid to be reported to userspace. * - * If no_idmapping() determines that this is not an idmapped mount we can - * simply return @kuid unchanged. + * If initial_idmapping() determines that this is not an idmapped mount + * we can simply return @kuid unchanged. * If initial_idmapping() tells us that the filesystem is not mounted with an * idmapping we know the value of @kuid won't change when calling * from_kuid() so we can simply retrieve the value via __kuid_val() @@ -87,7 +67,7 @@ vfsuid_t make_vfsuid(struct mnt_idmap *idmap, uid_t uid; struct user_namespace *mnt_userns = idmap->owner; - if (no_idmapping(mnt_userns, fs_userns)) + if (idmap == &nop_mnt_idmap) return VFSUIDT_INIT(kuid); if (initial_idmapping(fs_userns)) uid = __kuid_val(kuid); @@ -108,8 +88,8 @@ EXPORT_SYMBOL_GPL(make_vfsuid); * Take a @kgid and remap it from @fs_userns into @idmap. Use this * function when preparing a @kgid to be reported to userspace. * - * If no_idmapping() determines that this is not an idmapped mount we can - * simply return @kgid unchanged. + * If initial_idmapping() determines that this is not an idmapped mount + * we can simply return @kgid unchanged. * If initial_idmapping() tells us that the filesystem is not mounted with an * idmapping we know the value of @kgid won't change when calling * from_kgid() so we can simply retrieve the value via __kgid_val() @@ -125,7 +105,7 @@ vfsgid_t make_vfsgid(struct mnt_idmap *idmap, gid_t gid; struct user_namespace *mnt_userns = idmap->owner; - if (no_idmapping(mnt_userns, fs_userns)) + if (idmap == &nop_mnt_idmap) return VFSGIDT_INIT(kgid); if (initial_idmapping(fs_userns)) gid = __kgid_val(kgid); @@ -154,7 +134,7 @@ kuid_t from_vfsuid(struct mnt_idmap *idmap, uid_t uid; struct user_namespace *mnt_userns = idmap->owner; - if (no_idmapping(mnt_userns, fs_userns)) + if (idmap == &nop_mnt_idmap) return AS_KUIDT(vfsuid); uid = from_kuid(mnt_userns, AS_KUIDT(vfsuid)); if (uid == (uid_t)-1) @@ -182,7 +162,7 @@ kgid_t from_vfsgid(struct mnt_idmap *idmap, gid_t gid; struct user_namespace *mnt_userns = idmap->owner; - if (no_idmapping(mnt_userns, fs_userns)) + if (idmap == &nop_mnt_idmap) return AS_KGIDT(vfsgid); gid = from_kgid(mnt_userns, AS_KGIDT(vfsgid)); if (gid == (gid_t)-1) From patchwork Wed Nov 22 12:44:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13464764 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 9BD4C3D999 for ; Wed, 22 Nov 2023 12:44:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gJ6CnHJ5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 55482C433C7; Wed, 22 Nov 2023 12:44:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700657097; bh=m8UauW8T3utqONI/xPOmce94etfNcpHe3Eh/YRiZ0/E=; h=From:Date:Subject:References:In-Reply-To:To:From; b=gJ6CnHJ5LVlA6y/khMJ7EvZ2I1USaWbOBlFbEYrGn9282raB6g76+SPmzkP+9R7pn AicfM/F2yTVPQBOSDmmauT/TWyiy0BiZzGHxREfgAN2PhplZf9j3KwXw2LpMWFUOom naBe4iwyMwpHlIOLN72DC6tQ3W7sfhJZtNHMRlhvCPIyDLR2MlD8QDDdQxrMhwYQJm g12plgikhN+bZSsMxw3JSUCoGQXZ5k7S9TTZxViyEbpleTGNXtr1vNQjeFBkxDSEF0 cr2EbWeyZsc++2fPvLHaXvRDq+ekgZmNzelQi6yX1H26ISxaFdEv0IM2xJy7v8N9v8 JVdeN22ZjzADQ== From: Christian Brauner Date: Wed, 22 Nov 2023 13:44:39 +0100 Subject: [PATCH 3/4] mnt_idmapping: decouple from namespaces Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231122-vfs-mnt_idmap-v1-3-dae4abdde5bd@kernel.org> References: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> In-Reply-To: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> To: linux-fsdevel@vger.kernel.org, Seth Forshee , Christian Brauner X-Mailer: b4 0.13-dev-26615 X-Developer-Signature: v=1; a=openpgp-sha256; l=8406; i=brauner@kernel.org; h=from:subject:message-id; bh=m8UauW8T3utqONI/xPOmce94etfNcpHe3Eh/YRiZ0/E=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTGfj/yS9yra72wf2yZm+D9UMurXRzXrr0zu8O17bDFo /37PJbs7yhlYRDjYpAVU2RxaDcJl1vOU7HZKFMDZg4rE8gQBi5OAZhI/R5GhrlbJ719uulyn8Ph +/lCl4U3T8riL55k1yWdELjgYWv1ExFGhsX5l+PkXrBl5iuvL32ttGCu8QbPEmldpVVe+9clvLn 5kRMA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 There's no reason we need to couple mnt idmapping to namespaces in the way we currently do. Copy the idmapping when an idmapped mount is created and don't take any reference on the namespace at all. We also can't easily refcount struct uid_gid_map because it needs to stay the size of a cacheline otherwise we risk performance regressions (Ignoring for a second that right now struct uid_gid_map isn't actually 64 byte but 72 but that's a fix for another patch series.). Signed-off-by: Christian Brauner Reviewed-by: Josef Bacik --- fs/mnt_idmapping.c | 106 +++++++++++++++++++++++++++++++++++++++++------- include/linux/uidgid.h | 13 ++++++ kernel/user_namespace.c | 4 +- 3 files changed, 106 insertions(+), 17 deletions(-) diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c index 35d78cb3c38a..64c5205e2b5e 100644 --- a/fs/mnt_idmapping.c +++ b/fs/mnt_idmapping.c @@ -9,8 +9,16 @@ #include "internal.h" +/* + * Outside of this file vfs{g,u}id_t are always created from k{g,u}id_t, + * never from raw values. These are just internal helpers. + */ +#define VFSUIDT_INIT_RAW(val) (vfsuid_t){ val } +#define VFSGIDT_INIT_RAW(val) (vfsgid_t){ val } + struct mnt_idmap { - struct user_namespace *owner; + struct uid_gid_map uid_map; + struct uid_gid_map gid_map; refcount_t count; }; @@ -20,7 +28,6 @@ struct mnt_idmap { * mapped to {g,u}id 1, [...], {g,u}id 1000 to {g,u}id 1000, [...]. */ struct mnt_idmap nop_mnt_idmap = { - .owner = &init_user_ns, .count = REFCOUNT_INIT(1), }; EXPORT_SYMBOL_GPL(nop_mnt_idmap); @@ -65,7 +72,6 @@ vfsuid_t make_vfsuid(struct mnt_idmap *idmap, kuid_t kuid) { uid_t uid; - struct user_namespace *mnt_userns = idmap->owner; if (idmap == &nop_mnt_idmap) return VFSUIDT_INIT(kuid); @@ -75,7 +81,7 @@ vfsuid_t make_vfsuid(struct mnt_idmap *idmap, uid = from_kuid(fs_userns, kuid); if (uid == (uid_t)-1) return INVALID_VFSUID; - return VFSUIDT_INIT(make_kuid(mnt_userns, uid)); + return VFSUIDT_INIT_RAW(map_id_down(&idmap->uid_map, uid)); } EXPORT_SYMBOL_GPL(make_vfsuid); @@ -103,7 +109,6 @@ vfsgid_t make_vfsgid(struct mnt_idmap *idmap, struct user_namespace *fs_userns, kgid_t kgid) { gid_t gid; - struct user_namespace *mnt_userns = idmap->owner; if (idmap == &nop_mnt_idmap) return VFSGIDT_INIT(kgid); @@ -113,7 +118,7 @@ vfsgid_t make_vfsgid(struct mnt_idmap *idmap, gid = from_kgid(fs_userns, kgid); if (gid == (gid_t)-1) return INVALID_VFSGID; - return VFSGIDT_INIT(make_kgid(mnt_userns, gid)); + return VFSGIDT_INIT_RAW(map_id_down(&idmap->gid_map, gid)); } EXPORT_SYMBOL_GPL(make_vfsgid); @@ -132,11 +137,10 @@ kuid_t from_vfsuid(struct mnt_idmap *idmap, struct user_namespace *fs_userns, vfsuid_t vfsuid) { uid_t uid; - struct user_namespace *mnt_userns = idmap->owner; if (idmap == &nop_mnt_idmap) return AS_KUIDT(vfsuid); - uid = from_kuid(mnt_userns, AS_KUIDT(vfsuid)); + uid = map_id_up(&idmap->uid_map, __vfsuid_val(vfsuid)); if (uid == (uid_t)-1) return INVALID_UID; if (initial_idmapping(fs_userns)) @@ -160,11 +164,10 @@ kgid_t from_vfsgid(struct mnt_idmap *idmap, struct user_namespace *fs_userns, vfsgid_t vfsgid) { gid_t gid; - struct user_namespace *mnt_userns = idmap->owner; if (idmap == &nop_mnt_idmap) return AS_KGIDT(vfsgid); - gid = from_kgid(mnt_userns, AS_KGIDT(vfsgid)); + gid = map_id_up(&idmap->gid_map, __vfsgid_val(vfsgid)); if (gid == (gid_t)-1) return INVALID_GID; if (initial_idmapping(fs_userns)) @@ -195,16 +198,91 @@ int vfsgid_in_group_p(vfsgid_t vfsgid) #endif EXPORT_SYMBOL_GPL(vfsgid_in_group_p); +static int copy_mnt_idmap(struct uid_gid_map *map_from, + struct uid_gid_map *map_to) +{ + struct uid_gid_extent *forward, *reverse; + u32 nr_extents = READ_ONCE(map_from->nr_extents); + /* Pairs with smp_wmb() when writing the idmapping. */ + smp_rmb(); + + /* + * Don't blindly copy @map_to into @map_from if nr_extents is + * smaller or equal to UID_GID_MAP_MAX_BASE_EXTENTS. Since we + * read @nr_extents someone could have written an idmapping and + * then we might end up with inconsistent data. So just don't do + * anything at all. + */ + if (nr_extents == 0) + return 0; + + /* + * Here we know that nr_extents is greater than zero which means + * a map has been written. Since idmappings can't be changed + * once they have been written we know that we can safely copy + * from @map_to into @map_from. + */ + + if (nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS) { + *map_to = *map_from; + return 0; + } + + forward = kmemdup(map_from->forward, + nr_extents * sizeof(struct uid_gid_extent), + GFP_KERNEL_ACCOUNT); + if (!forward) + return -ENOMEM; + + reverse = kmemdup(map_from->reverse, + nr_extents * sizeof(struct uid_gid_extent), + GFP_KERNEL_ACCOUNT); + if (!reverse) { + kfree(forward); + return -ENOMEM; + } + + /* + * The idmapping isn't exposed anywhere so we don't need to care + * about ordering between extent pointers and @nr_extents + * initialization. + */ + map_to->forward = forward; + map_to->reverse = reverse; + map_to->nr_extents = nr_extents; + return 0; +} + +static void free_mnt_idmap(struct mnt_idmap *idmap) +{ + if (idmap->uid_map.nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) { + kfree(idmap->uid_map.forward); + kfree(idmap->uid_map.reverse); + } + if (idmap->gid_map.nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) { + kfree(idmap->gid_map.forward); + kfree(idmap->gid_map.reverse); + } + kfree(idmap); +} + struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns) { struct mnt_idmap *idmap; + int ret; idmap = kzalloc(sizeof(struct mnt_idmap), GFP_KERNEL_ACCOUNT); if (!idmap) return ERR_PTR(-ENOMEM); - idmap->owner = get_user_ns(mnt_userns); refcount_set(&idmap->count, 1); + ret = copy_mnt_idmap(&mnt_userns->uid_map, &idmap->uid_map); + if (!ret) + ret = copy_mnt_idmap(&mnt_userns->gid_map, &idmap->gid_map); + if (ret) { + free_mnt_idmap(idmap); + idmap = ERR_PTR(ret); + } return idmap; } @@ -234,9 +312,7 @@ EXPORT_SYMBOL_GPL(mnt_idmap_get); */ void mnt_idmap_put(struct mnt_idmap *idmap) { - if (idmap != &nop_mnt_idmap && refcount_dec_and_test(&idmap->count)) { - put_user_ns(idmap->owner); - kfree(idmap); - } + if (idmap != &nop_mnt_idmap && refcount_dec_and_test(&idmap->count)) + free_mnt_idmap(idmap); } EXPORT_SYMBOL_GPL(mnt_idmap_put); diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h index b0542cd11aeb..7806e93b907d 100644 --- a/include/linux/uidgid.h +++ b/include/linux/uidgid.h @@ -17,6 +17,7 @@ struct user_namespace; extern struct user_namespace init_user_ns; +struct uid_gid_map; typedef struct { uid_t val; @@ -138,6 +139,9 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid) return from_kgid(ns, gid) != (gid_t) -1; } +u32 map_id_down(struct uid_gid_map *map, u32 id); +u32 map_id_up(struct uid_gid_map *map, u32 id); + #else static inline kuid_t make_kuid(struct user_namespace *from, uid_t uid) @@ -186,6 +190,15 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid) return gid_valid(gid); } +static inline u32 map_id_down(struct uid_gid_map *map, u32 id) +{ + return id; +} + +static inline u32 map_id_up(struct uid_gid_map *map, u32 id); +{ + return id; +} #endif /* CONFIG_USER_NS */ #endif /* _LINUX_UIDGID_H */ diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index eabe8bcc7042..a649e58e3b6a 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -332,7 +332,7 @@ static u32 map_id_range_down(struct uid_gid_map *map, u32 id, u32 count) return id; } -static u32 map_id_down(struct uid_gid_map *map, u32 id) +u32 map_id_down(struct uid_gid_map *map, u32 id) { return map_id_range_down(map, id, 1); } @@ -375,7 +375,7 @@ map_id_up_max(unsigned extents, struct uid_gid_map *map, u32 id) sizeof(struct uid_gid_extent), cmp_map_id); } -static u32 map_id_up(struct uid_gid_map *map, u32 id) +u32 map_id_up(struct uid_gid_map *map, u32 id) { struct uid_gid_extent *extent; unsigned extents = map->nr_extents; From patchwork Wed Nov 22 12:44:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13464765 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 96D65495FB for ; Wed, 22 Nov 2023 12:44:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WAGLmXve" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A66ADC433CA; Wed, 22 Nov 2023 12:44:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700657098; bh=uKuNPUXLK2gLNkKe02Yai19TRRbzLMVmA8ccRa9KuT8=; h=From:Date:Subject:References:In-Reply-To:To:From; b=WAGLmXvek6I8o1UXBXRZ+3ezbedQFioQ2B06F/QUW9CfTzWLescH+j08J0dThEhYA m+WGfJHA6e3bv2du+c8+tuyKi96OknqfL3Cu4tPF/SHt8xF/Zeup+811iNErDl+evz SC1ZQ8HqDUjQfGo+TXwDQDRnYjScXSGynihJ5RyozXc/xGdqg+tK0WhTIbeIoCCoWf E6HjKsTH7rUV1KaCpzoZf2+QdYI8rHx/TI2i+0VJfawwwTFln3n3LVK9bHhKUcCTLr ZQdhvnlRC3+/3xaQ1E760lEVuBmpckK1TV0OFq9lQGPmZZda5qo95yJXt55BY6/u5g kvbB96XqQJkNw== From: Christian Brauner Date: Wed, 22 Nov 2023 13:44:40 +0100 Subject: [PATCH 4/4] fs: reformat idmapped mounts entry Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231122-vfs-mnt_idmap-v1-4-dae4abdde5bd@kernel.org> References: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> In-Reply-To: <20231122-vfs-mnt_idmap-v1-0-dae4abdde5bd@kernel.org> To: linux-fsdevel@vger.kernel.org, Seth Forshee , Christian Brauner X-Mailer: b4 0.13-dev-26615 X-Developer-Signature: v=1; a=openpgp-sha256; l=1909; i=brauner@kernel.org; h=from:subject:message-id; bh=uKuNPUXLK2gLNkKe02Yai19TRRbzLMVmA8ccRa9KuT8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTGfj/CaldwV7Pw5bzDoYxifnLrmvKUNX7NY9A7uFV2M jPTtlXuHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABP54MPwP1zZa5GjjSNz/Zbd bQ7tPhWSbAtLzTNDstc2uxfumymzmZHhj/Kb45t+cm1xPc+s56Zp1Hr4Be/78MNfN7XWvFE8l/G CHwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Reformat idmapped mounts to clearly mark where it belongs. Signed-off-by: Christian Brauner --- MAINTAINERS | 20 ++++++++++---------- include/linux/uidgid.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 97f51d5ec1cf..d0a7b6f357ce 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8177,6 +8177,16 @@ F: fs/exportfs/ F: fs/fhandle.c F: include/linux/exportfs.h +FILESYSTEMS [IDMAPPED MOUNTS] +M: Christian Brauner +M: Seth Forshee +L: linux-fsdevel@vger.kernel.org +S: Maintained +F: Documentation/filesystems/idmappings.rst +F: fs/mnt_idmapping.c +F: include/linux/mnt_idmapping.* +F: tools/testing/selftests/mount_setattr/ + FILESYSTEMS [IOMAP] M: Christian Brauner R: Darrick J. Wong @@ -10252,16 +10262,6 @@ S: Maintained W: https://github.com/o2genum/ideapad-slidebar F: drivers/input/misc/ideapad_slidebar.c -IDMAPPED MOUNTS -M: Christian Brauner -M: Seth Forshee -L: linux-fsdevel@vger.kernel.org -S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping.git -F: Documentation/filesystems/idmappings.rst -F: include/linux/mnt_idmapping.* -F: tools/testing/selftests/mount_setattr/ - IDT VersaClock 5 CLOCK DRIVER M: Luca Ceresoli S: Maintained diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h index 7806e93b907d..415a7ca2b882 100644 --- a/include/linux/uidgid.h +++ b/include/linux/uidgid.h @@ -195,7 +195,7 @@ static inline u32 map_id_down(struct uid_gid_map *map, u32 id) return id; } -static inline u32 map_id_up(struct uid_gid_map *map, u32 id); +static inline u32 map_id_up(struct uid_gid_map *map, u32 id) { return id; }