All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: Amir Goldstein <amir73il@gmail.com>,
	Miklos Szeredi <mszeredi@redhat.com>
Cc: "Christian Brauner" <brauner@kernel.org>,
	"Christoph Hellwig" <hch@lst.de>,
	linux-unionfs@vger.kernel.org, "Aleksa Sarai" <cyphar@cyphar.com>,
	"Giuseppe Scrivano" <gscrivan@redhat.com>,
	"Rodrigo Campos Catelin" <rodrigo@sdfg.com.ar>,
	"Seth Forshee" <sforshee@digitalocean.com>,
	"Luca Bocassi" <luca.boccassi@microsoft.com>,
	"Lennart Poettering" <mzxreary@0pointer.de>,
	"Stéphane Graber" <stgraber@ubuntu.com>
Subject: [PATCH v5 09/19] ovl: use ovl_do_notify_change() wrapper
Date: Thu,  7 Apr 2022 13:21:46 +0200	[thread overview]
Message-ID: <20220407112157.1775081-10-brauner@kernel.org> (raw)
In-Reply-To: <20220407112157.1775081-1-brauner@kernel.org>

Introduce ovl_do_notify_change() as a simple wrapper around
notify_change() to support idmapped layers. The helper mirrors other
ovl_do_*() helpers that operate on the upper layers.

When changing ownership of an upper object the intended ownership needs
to be mapped according to the upper layer's idmapping. This mapping is
the inverse to the mapping applied when copying inode information from
an upper layer to the corresponding overlay inode. So e.g., when an
upper mount maps files that are stored on-disk as owned by id 1001 to
1000 this means that calling stat on this object from an idmapped mount
will report the file as being owned by id 1000. Consequently in order to
change ownership of an object in this filesystem so it appears as being
owned by id 1000 in the upper idmapped layer it needs to store id 1001
on disk. The mnt mapping helpers take care of this.

All idmapping helpers are nops when no idmapped base layers are used.

Cc: <linux-unionfs@vger.kernel.org>
Tested-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
---
/* v2 */
unchanged

/* v3 */
unchanged

/* v4 */
- Vivek Goyal <vgoyal@redhat.com>:
  - s/ovl_upper_idmap()/ovl_upper_mnt_userns()/g
    and other variable renamings

/* v5 */
unchanged
---
 fs/overlayfs/copy_up.c   |  8 ++++----
 fs/overlayfs/dir.c       |  2 +-
 fs/overlayfs/inode.c     |  3 ++-
 fs/overlayfs/overlayfs.h | 29 +++++++++++++++++++++++++++++
 fs/overlayfs/super.c     |  2 +-
 5 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 2c336acb2ba0..a5d68302693f 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -301,7 +301,7 @@ static int ovl_set_size(struct ovl_fs *ofs,
 		.ia_size = stat->size,
 	};
 
-	return notify_change(&init_user_ns, upperdentry, &attr, NULL);
+	return ovl_do_notify_change(ofs, upperdentry, &attr);
 }
 
 static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry,
@@ -314,7 +314,7 @@ static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry,
 		.ia_mtime = stat->mtime,
 	};
 
-	return notify_change(&init_user_ns, upperdentry, &attr, NULL);
+	return ovl_do_notify_change(ofs, upperdentry, &attr);
 }
 
 int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry,
@@ -327,7 +327,7 @@ int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry,
 			.ia_valid = ATTR_MODE,
 			.ia_mode = stat->mode,
 		};
-		err = notify_change(&init_user_ns, upperdentry, &attr, NULL);
+		err = ovl_do_notify_change(ofs, upperdentry, &attr);
 	}
 	if (!err) {
 		struct iattr attr = {
@@ -335,7 +335,7 @@ int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry,
 			.ia_uid = stat->uid,
 			.ia_gid = stat->gid,
 		};
-		err = notify_change(&init_user_ns, upperdentry, &attr, NULL);
+		err = ovl_do_notify_change(ofs, upperdentry, &attr);
 	}
 	if (!err)
 		ovl_set_timestamps(ofs, upperdentry, stat);
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index e2b3502f6b12..439b727885fe 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -515,7 +515,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
 			.ia_mode = cattr->mode,
 		};
 		inode_lock(newdentry->d_inode);
-		err = notify_change(&init_user_ns, newdentry, &attr, NULL);
+		err = ovl_do_notify_change(ofs, newdentry, &attr);
 		inode_unlock(newdentry->d_inode);
 		if (err)
 			goto out_cleanup;
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index c51a9dd36cc7..9a8e6b94d9e8 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -21,6 +21,7 @@ int ovl_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 		struct iattr *attr)
 {
 	int err;
+	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
 	bool full_copy_up = false;
 	struct dentry *upperdentry;
 	const struct cred *old_cred;
@@ -77,7 +78,7 @@ int ovl_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 
 		inode_lock(upperdentry->d_inode);
 		old_cred = ovl_override_creds(dentry->d_sb);
-		err = notify_change(&init_user_ns, upperdentry, attr, NULL);
+		err = ovl_do_notify_change(ofs, upperdentry, attr);
 		revert_creds(old_cred);
 		if (!err)
 			ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 716e31ace058..139f76640ae7 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -122,6 +122,35 @@ static inline const char *ovl_xattr(struct ovl_fs *ofs, enum ovl_xattr ox)
 	return ovl_xattr_table[ox][ofs->config.userxattr];
 }
 
+/*
+ * When changing ownership of an upper object map the intended ownership
+ * according to the upper layer's idmapping. When an upper mount idmaps files
+ * that are stored on-disk as owned by id 1001 to id 1000 this means stat on
+ * this object will report it as being owned by id 1000 when calling stat via
+ * the upper mount.
+ * In order to change ownership of an object so stat reports id 1000 when
+ * called on an idmapped upper mount the value written to disk - i.e., the
+ * value stored in ia_*id - must 1001. The mount mapping helper will thus take
+ * care to map 1000 to 1001.
+ * The mnt idmapping helpers are nops if the upper layer isn't idmapped.
+ */
+static inline int ovl_do_notify_change(struct ovl_fs *ofs,
+				       struct dentry *upperdentry,
+				       struct iattr *attr)
+{
+	struct user_namespace *upper_mnt_userns = ovl_upper_mnt_userns(ofs);
+	struct user_namespace *fs_userns = i_user_ns(d_inode(upperdentry));
+
+	if (attr->ia_valid & ATTR_UID)
+		attr->ia_uid = mapped_kuid_user(upper_mnt_userns,
+						fs_userns, attr->ia_uid);
+	if (attr->ia_valid & ATTR_GID)
+		attr->ia_gid = mapped_kgid_user(upper_mnt_userns,
+						fs_userns, attr->ia_gid);
+
+	return notify_change(upper_mnt_userns, upperdentry, attr, NULL);
+}
+
 static inline int ovl_do_rmdir(struct ovl_fs *ofs,
 			       struct inode *dir, struct dentry *dentry)
 {
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 307a36af7b4f..432ef060d2ab 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -821,7 +821,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
 
 		/* Clear any inherited mode bits */
 		inode_lock(work->d_inode);
-		err = notify_change(&init_user_ns, work, &attr, NULL);
+		err = ovl_do_notify_change(ofs, work, &attr);
 		inode_unlock(work->d_inode);
 		if (err)
 			goto out_dput;
-- 
2.32.0


  parent reply	other threads:[~2022-04-07 11:23 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-07 11:21 [PATCH v5 00/19] overlay: support idmapped layers Christian Brauner
2022-04-07 11:21 ` [PATCH v5 01/19] fs: add two trivial lookup helpers Christian Brauner
2022-04-07 11:21 ` [PATCH v5 02/19] exportfs: support idmapped mounts Christian Brauner
2022-04-07 11:21 ` [PATCH v5 03/19] ovl: use wrappers to all vfs_*xattr() calls Christian Brauner
2022-04-07 11:21 ` [PATCH v5 04/19] ovl: pass ofs to creation operations Christian Brauner
2022-04-07 11:21 ` [PATCH v5 05/19] ovl: add ovl_upper_mnt_userns() wrapper Christian Brauner
2022-04-07 11:21 ` [PATCH v5 06/19] ovl: handle idmappings in creation operations Christian Brauner
2022-04-07 11:21 ` [PATCH v5 07/19] ovl: pass ofs to setattr operations Christian Brauner
2022-04-07 11:21 ` [PATCH v5 08/19] ovl: pass layer mnt to ovl_open_realfile() Christian Brauner
2022-04-07 11:21 ` Christian Brauner [this message]
2022-04-07 11:21 ` [PATCH v5 10/19] ovl: use ovl_lookup_upper() wrapper Christian Brauner
2022-04-07 11:21 ` [PATCH v5 11/19] ovl: use ovl_path_getxattr() wrapper Christian Brauner
2022-04-07 11:21 ` [PATCH v5 12/19] ovl: handle idmappings for layer fileattrs Christian Brauner
2022-04-07 11:21 ` [PATCH v5 13/19] ovl: handle idmappings for layer lookup Christian Brauner
2022-04-28 10:10   ` Miklos Szeredi
2022-04-28 10:30     ` Christian Brauner
2022-04-28 10:57       ` Amir Goldstein
2022-04-28 11:43         ` Miklos Szeredi
2022-04-28 11:30       ` Miklos Szeredi
2022-04-28 11:35         ` Miklos Szeredi
2022-04-28 11:50           ` Christian Brauner
2022-04-07 11:21 ` [PATCH v5 14/19] ovl: store lower path in ovl_inode Christian Brauner
2022-04-07 11:21 ` [PATCH v5 15/19] ovl: use ovl_copy_{real,upper}attr() wrappers Christian Brauner
2022-04-07 11:21 ` [PATCH v5 16/19] ovl: handle idmappings in ovl_permission() Christian Brauner
2022-04-07 11:21 ` [PATCH v5 17/19] ovl: handle idmappings in layer open helpers Christian Brauner
2022-04-07 11:21 ` [PATCH v5 18/19] ovl: handle idmappings in ovl_xattr_{g,s}et() Christian Brauner
2022-04-07 11:21 ` [PATCH v5 19/19] ovl: support idmapped layers Christian Brauner
2022-04-07 11:21 ` [PATCH v5] common: allow to run all tests on idmapped mounts Christian Brauner
2022-04-13  7:49   ` Christian Brauner
2022-04-28 14:39 ` [PATCH v5 00/19] overlay: support idmapped layers Miklos Szeredi
2022-04-28 14:47   ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220407112157.1775081-10-brauner@kernel.org \
    --to=brauner@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=cyphar@cyphar.com \
    --cc=gscrivan@redhat.com \
    --cc=hch@lst.de \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=luca.boccassi@microsoft.com \
    --cc=mszeredi@redhat.com \
    --cc=mzxreary@0pointer.de \
    --cc=rodrigo@sdfg.com.ar \
    --cc=sforshee@digitalocean.com \
    --cc=stgraber@ubuntu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.