David Disseldorp 92426c
From 984534ac10f71d0b4c2541b2b1fa231d245d668d Mon Sep 17 00:00:00 2001
David Disseldorp 92426c
From: Miklos Szeredi <mszeredi@redhat.com>
David Disseldorp 92426c
Date: Tue, 24 Jan 2023 16:41:18 +0100
David Disseldorp 92426c
Subject: [PATCH] ovl: fail on invalid uid/gid mapping at copy up
David Disseldorp 92426c
Git-commit: 4f11ada10d0ad3fd53e2bd67806351de63a4f9c3
David Disseldorp 92426c
Patch-mainline: v6.2-rc6
David Disseldorp 92426c
References: CVE-2023-0386 bsc#1209615
David Disseldorp 92426c
David Disseldorp 92426c
If st_uid/st_gid doesn't have a mapping in the mounter's user_ns, then
David Disseldorp 92426c
copy-up should fail, just like it would fail if the mounter task was doing
David Disseldorp 92426c
the copy using "cp -a".
David Disseldorp 92426c
David Disseldorp 92426c
There's a corner case where the "cp -a" would succeed but copy up fail: if
David Disseldorp 92426c
there's a mapping of the invalid uid/gid (65534 by default) in the user
David Disseldorp 92426c
namespace.  This is because stat(2) will return this value if the mapping
David Disseldorp 92426c
doesn't exist in the current user_ns and "cp -a" will in turn be able to
David Disseldorp 92426c
create a file with this uid/gid.
David Disseldorp 92426c
David Disseldorp 92426c
This behavior would be inconsistent with POSIX ACL's, which return -1 for
David Disseldorp 92426c
invalid uid/gid which result in a failed copy.
David Disseldorp 92426c
David Disseldorp 92426c
For consistency and simplicity fail the copy of the st_uid/st_gid are
David Disseldorp 92426c
invalid.
David Disseldorp 92426c
David Disseldorp 92426c
Fixes: 459c7c565ac3 ("ovl: unprivieged mounts")
David Disseldorp 92426c
Cc: <stable@vger.kernel.org> # v5.11
David Disseldorp 92426c
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
David Disseldorp 92426c
Reviewed-by: Christian Brauner <brauner@kernel.org>
David Disseldorp 92426c
Reviewed-by: Seth Forshee <sforshee@kernel.org>
David Disseldorp 92426c
Acked-by: David Disseldorp <ddiss@suse.de>
David Disseldorp 92426c
---
David Disseldorp 92426c
 fs/overlayfs/copy_up.c | 4 ++++
David Disseldorp 92426c
 1 file changed, 4 insertions(+)
David Disseldorp 92426c
David Disseldorp 92426c
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
David Disseldorp 92426c
index 2846b943e80c1..95b2173ab9bca 100644
David Disseldorp 92426c
--- a/fs/overlayfs/copy_up.c
David Disseldorp 92426c
+++ b/fs/overlayfs/copy_up.c
David Disseldorp 92426c
@@ -886,6 +886,10 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
David Disseldorp 92426c
 	if (err)
David Disseldorp 92426c
 		return err;
David Disseldorp 92426c
 
David Disseldorp 92426c
+	if (!kuid_has_mapping(current_user_ns(), ctx.stat.uid) ||
David Disseldorp 92426c
+	    !kgid_has_mapping(current_user_ns(), ctx.stat.gid))
David Disseldorp 92426c
+		return -EOVERFLOW;
David Disseldorp 92426c
+
David Disseldorp 92426c
 	ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags);
David Disseldorp 92426c
 
David Disseldorp 92426c
 	if (parent) {
David Disseldorp 92426c
-- 
David Disseldorp 92426c
2.40.0
David Disseldorp 92426c