public inbox for linux-audit@redhat.com
 help / color / mirror / Atom feed
From: Christian Brauner <christian.brauner@ubuntu.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	Christoph Hellwig <hch@infradead.org>,
	linux-fsdevel@vger.kernel.org
Cc: "Phil Estes" <estesp@gmail.com>,
	"Lennart Poettering" <lennart@poettering.net>,
	"Mimi Zohar" <zohar@linux.ibm.com>,
	"James Bottomley" <James.Bottomley@hansenpartnership.com>,
	"Andreas Dilger" <adilger.kernel@dilger.ca>,
	containers@lists.linux-foundation.org,
	"Christian Brauner" <christian.brauner@ubuntu.com>,
	"Christoph Hellwig" <hch@lst.de>,
	"Tycho Andersen" <tycho@tycho.ws>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"James Morris" <jmorris@namei.org>,
	smbarber@chromium.org, linux-ext4@vger.kernel.org,
	"Mrunal Patel" <mpatel@redhat.com>,
	"Serge Hallyn" <serge@hallyn.com>,
	"Arnd Bergmann" <arnd@arndb.de>, "Jann Horn" <jannh@google.com>,
	selinux@vger.kernel.org, "Josh Triplett" <josh@joshtriplett.org>,
	"Seth Forshee" <seth.forshee@canonical.com>,
	"Aleksa Sarai" <cyphar@cyphar.com>,
	"Andy Lutomirski" <luto@kernel.org>,
	"OGAWA Hirofumi" <hirofumi@mail.parknet.co.jp>,
	"Geoffrey Thomas" <geofft@ldpreload.com>,
	"David Howells" <dhowells@redhat.com>,
	"John Johansen" <john.johansen@canonical.com>,
	"Theodore Tso" <tytso@mit.edu>,
	"Dmitry Kasatkin" <dmitry.kasatkin@gmail.com>,
	linux-security-module@vger.kernel.org, linux-audit@redhat.com,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	linux-api@vger.kernel.org, "Alban Crequy" <alban@kinvolk.io>,
	linux-integrity@vger.kernel.org,
	"Stéphane Graber" <stgraber@ubuntu.com>,
	"Todd Kjos" <tkjos@google.com>
Subject: [PATCH v2 19/39] open: handle idmapped mounts in do_truncate()
Date: Sun, 15 Nov 2020 11:36:58 +0100	[thread overview]
Message-ID: <20201115103718.298186-20-christian.brauner@ubuntu.com> (raw)
In-Reply-To: <20201115103718.298186-1-christian.brauner@ubuntu.com>

When truncating files the vfs will verify that the caller is privileged
over the inode. Since the do_truncate() helper is only used in a few places
in the vfs code extend it to handle idmapped mounts instead of adding a new
helper.  If the inode is accessed through an idmapped mount it is mapped
according to the mount's user namespace. Afterwards the permissions checks
are identical to non-idmapped mounts. If the initial user namespace is
passed all mapping operations are a nop so non-idmapped mounts will not see
a change in behavior and will also not see any performance impact.

Cc: Christoph Hellwig <hch@lst.de>
Cc: David Howells <dhowells@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
/* v2 */
unchanged
---
 fs/coredump.c      | 12 +++++++++---
 fs/inode.c         | 13 +++++++++----
 fs/namei.c         |  6 +++---
 fs/open.c          | 21 +++++++++++++--------
 include/linux/fs.h |  4 ++--
 5 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/fs/coredump.c b/fs/coredump.c
index 0cd9056d79cc..25beac7230ff 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -703,6 +703,7 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 			goto close_fail;
 		}
 	} else {
+		struct user_namespace *user_ns;
 		struct inode *inode;
 		int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
 				 O_LARGEFILE | O_EXCL;
@@ -786,7 +787,8 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 			goto close_fail;
 		if (!(cprm.file->f_mode & FMODE_CAN_WRITE))
 			goto close_fail;
-		if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
+		user_ns = mnt_user_ns(cprm.file->f_path.mnt);
+		if (do_truncate(user_ns, cprm.file->f_path.dentry, 0, 0, cprm.file))
 			goto close_fail;
 	}
 
@@ -931,8 +933,12 @@ void dump_truncate(struct coredump_params *cprm)
 
 	if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
 		offset = file->f_op->llseek(file, 0, SEEK_CUR);
-		if (i_size_read(file->f_mapping->host) < offset)
-			do_truncate(file->f_path.dentry, offset, 0, file);
+		if (i_size_read(file->f_mapping->host) < offset) {
+			struct user_namespace *user_ns;
+
+			user_ns = mnt_user_ns(file->f_path.mnt);
+			do_truncate(user_ns, file->f_path.dentry, offset, 0, file);
+		}
 	}
 }
 EXPORT_SYMBOL(dump_truncate);
diff --git a/fs/inode.c b/fs/inode.c
index 75c64f003c45..0ccdd673636d 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1904,7 +1904,8 @@ int dentry_needs_remove_privs(struct dentry *dentry)
 	return mask;
 }
 
-static int __remove_privs(struct dentry *dentry, int kill)
+static int __remove_privs(struct user_namespace *user_ns, struct dentry *dentry,
+			  int kill)
 {
 	struct iattr newattrs;
 
@@ -1913,7 +1914,7 @@ static int __remove_privs(struct dentry *dentry, int kill)
 	 * Note we call this on write, so notify_change will not
 	 * encounter any conflicting delegations:
 	 */
-	return notify_change(&init_user_ns, dentry, &newattrs, NULL);
+	return notify_change(user_ns, dentry, &newattrs, NULL);
 }
 
 /*
@@ -1939,8 +1940,12 @@ int file_remove_privs(struct file *file)
 	kill = dentry_needs_remove_privs(dentry);
 	if (kill < 0)
 		return kill;
-	if (kill)
-		error = __remove_privs(dentry, kill);
+	if (kill) {
+		struct user_namespace *user_ns;
+
+		user_ns = mnt_user_ns(file->f_path.mnt);
+		error = __remove_privs(user_ns, dentry, kill);
+	}
 	if (!error)
 		inode_has_no_xattr(inode);
 
diff --git a/fs/namei.c b/fs/namei.c
index b91bf923d22c..5601b6680d4c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2940,9 +2940,9 @@ static int handle_truncate(struct file *filp)
 	if (!error)
 		error = security_path_truncate(path);
 	if (!error) {
-		error = do_truncate(path->dentry, 0,
-				    ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
-				    filp);
+		error = do_truncate(mnt_user_ns(filp->f_path.mnt),
+				    path->dentry, 0,
+				    ATTR_MTIME | ATTR_CTIME | ATTR_OPEN, filp);
 	}
 	put_write_access(inode);
 	return error;
diff --git a/fs/open.c b/fs/open.c
index 2dc94689a7dc..137dcc52d2f8 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -35,8 +35,8 @@
 
 #include "internal.h"
 
-int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
-	struct file *filp)
+int do_truncate(struct user_namespace *user_ns, struct dentry *dentry,
+		loff_t length, unsigned int time_attrs, struct file *filp)
 {
 	int ret;
 	struct iattr newattrs;
@@ -61,13 +61,14 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
 
 	inode_lock(dentry->d_inode);
 	/* Note any delegations or leases have already been broken: */
-	ret = notify_change(&init_user_ns, dentry, &newattrs, NULL);
+	ret = notify_change(user_ns, dentry, &newattrs, NULL);
 	inode_unlock(dentry->d_inode);
 	return ret;
 }
 
 long vfs_truncate(const struct path *path, loff_t length)
 {
+	struct user_namespace *user_ns;
 	struct inode *inode;
 	long error;
 
@@ -83,7 +84,8 @@ long vfs_truncate(const struct path *path, loff_t length)
 	if (error)
 		goto out;
 
-	error = inode_permission(&init_user_ns, inode, MAY_WRITE);
+	user_ns = mnt_user_ns(path->mnt);
+	error = inode_permission(user_ns, inode, MAY_WRITE);
 	if (error)
 		goto mnt_drop_write_and_out;
 
@@ -107,7 +109,7 @@ long vfs_truncate(const struct path *path, loff_t length)
 	if (!error)
 		error = security_path_truncate(path);
 	if (!error)
-		error = do_truncate(path->dentry, length, 0, NULL);
+		error = do_truncate(user_ns, path->dentry, length, 0, NULL);
 
 put_write_and_out:
 	put_write_access(inode);
@@ -186,13 +188,16 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
 	/* Check IS_APPEND on real upper inode */
 	if (IS_APPEND(file_inode(f.file)))
 		goto out_putf;
-
 	sb_start_write(inode->i_sb);
 	error = locks_verify_truncate(inode, f.file, length);
 	if (!error)
 		error = security_path_truncate(&f.file->f_path);
-	if (!error)
-		error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, f.file);
+	if (!error) {
+		struct user_namespace *user_ns;
+
+		user_ns = mnt_user_ns(f.file->f_path.mnt);
+		error = do_truncate(user_ns, dentry, length, ATTR_MTIME | ATTR_CTIME, f.file);
+	}
 	sb_end_write(inode->i_sb);
 out_putf:
 	fdput(f);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f29909139838..1f2ec4c3c70b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2565,8 +2565,8 @@ struct filename {
 static_assert(offsetof(struct filename, iname) % sizeof(long) == 0);
 
 extern long vfs_truncate(const struct path *, loff_t);
-extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
-		       struct file *filp);
+extern int do_truncate(struct user_namespace *, struct dentry *, loff_t start,
+		       unsigned int time_attrs, struct file *filp);
 extern int vfs_fallocate(struct file *file, int mode, loff_t offset,
 			loff_t len);
 extern long do_sys_open(int dfd, const char __user *filename, int flags,
-- 
2.29.2

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


  parent reply	other threads:[~2020-11-16  2:15 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-15 10:36 [PATCH v2 00/39] fs: idmapped mounts Christian Brauner
2020-11-15 10:36 ` [PATCH v2 01/39] namespace: take lock_mount_hash() directly when changing flags Christian Brauner
2020-11-15 10:36 ` [PATCH v2 02/39] mount: make {lock,unlock}_mount_hash() static Christian Brauner
2020-11-15 10:36 ` [PATCH v2 03/39] namespace: only take read lock in do_reconfigure_mnt() Christian Brauner
2020-11-15 10:36 ` [PATCH v2 04/39] fs: add mount_setattr() Christian Brauner
2020-11-15 10:36 ` [PATCH v2 05/39] tests: add mount_setattr() selftests Christian Brauner
2020-11-15 10:36 ` [PATCH v2 06/39] fs: add id translation helpers Christian Brauner
2020-11-15 10:36 ` [PATCH v2 07/39] mount: attach mappings to mounts Christian Brauner
2020-11-23 15:47   ` Tycho Andersen
2020-11-23 16:24     ` Tycho Andersen
2020-11-24 12:30       ` Christian Brauner
2020-11-24 13:37         ` Tycho Andersen
2020-11-24 13:40           ` Christian Brauner
2020-11-24 13:44             ` Tycho Andersen
2020-11-24 13:59               ` Christian Brauner
2020-11-15 10:36 ` [PATCH v2 08/39] capability: handle idmapped mounts Christian Brauner
2020-11-15 10:36 ` [PATCH v2 09/39] namei: add idmapped mount aware permission helpers Christian Brauner
2020-11-15 10:36 ` [PATCH v2 10/39] inode: add idmapped mount aware init and " Christian Brauner
2020-11-28 18:12   ` Serge E. Hallyn
2020-11-15 10:36 ` [PATCH v2 11/39] attr: handle idmapped mounts Christian Brauner
2020-11-15 10:36 ` [PATCH v2 12/39] acl: " Christian Brauner
2020-11-15 10:36 ` [PATCH v2 13/39] xattr: " Christian Brauner
2020-11-15 10:36 ` [PATCH v2 14/39] commoncap: " Christian Brauner
2020-11-22 21:18   ` Paul Moore
2020-11-23  7:45     ` Christian Brauner
2020-11-15 10:36 ` [PATCH v2 15/39] stat: " Christian Brauner
2020-11-15 10:36 ` [PATCH v2 16/39] namei: handle idmapped mounts in may_*() helpers Christian Brauner
2020-11-15 10:36 ` [PATCH v2 17/39] namei: introduce struct renamedata Christian Brauner
2020-11-15 10:36 ` [PATCH v2 18/39] namei: prepare for idmapped mounts Christian Brauner
2020-11-15 10:36 ` Christian Brauner [this message]
2020-11-15 10:36 ` [PATCH v2 20/39] open: handle " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 21/39] af_unix: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 22/39] utimes: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 23/39] fcntl: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 24/39] notify: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 25/39] init: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 26/39] ioctl: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 27/39] would_dump: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 28/39] exec: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 29/39] fs: add helpers for idmap mounts Christian Brauner
2020-11-15 10:37 ` [PATCH v2 30/39] apparmor: handle idmapped mounts Christian Brauner
2020-11-15 10:37 ` [PATCH v2 31/39] audit: " Christian Brauner
2020-11-22 22:17   ` Paul Moore
2020-11-23  7:41     ` Christian Brauner
2020-11-23 22:06       ` Paul Moore
2020-11-15 10:37 ` [PATCH v2 32/39] ima: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 33/39] fat: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 34/39] ext4: support " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 35/39] ecryptfs: do not mount on top of " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 36/39] overlayfs: " Christian Brauner
2020-11-15 10:37 ` [PATCH v2 37/39] fs: introduce MOUNT_ATTR_IDMAP Christian Brauner
2020-11-15 10:37 ` [PATCH v2 38/39] selftests: add idmapped mounts xattr selftest Christian Brauner
2020-11-15 10:37 ` [PATCH v2 39/39] tests: add vfs/idmapped mounts test suite Christian Brauner
2020-11-20 21:15   ` Kees Cook
2020-11-17 23:54 ` [PATCH v2 00/39] fs: idmapped mounts Jonathan Corbet
2020-11-18  9:45   ` Christian Brauner
2020-11-18  3:51 ` Stephen Barber
2020-11-20  2:33 ` Darrick J. Wong
2020-11-20  9:10   ` Christian Brauner
2020-11-20  9:12     ` Christoph Hellwig
2020-11-20 11:58       ` 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=20201115103718.298186-20-christian.brauner@ubuntu.com \
    --to=christian.brauner@ubuntu.com \
    --cc=James.Bottomley@hansenpartnership.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=alban@kinvolk.io \
    --cc=arnd@arndb.de \
    --cc=containers@lists.linux-foundation.org \
    --cc=corbet@lwn.net \
    --cc=cyphar@cyphar.com \
    --cc=dhowells@redhat.com \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=ebiederm@xmission.com \
    --cc=estesp@gmail.com \
    --cc=geofft@ldpreload.com \
    --cc=hch@infradead.org \
    --cc=hch@lst.de \
    --cc=hirofumi@mail.parknet.co.jp \
    --cc=jannh@google.com \
    --cc=jmorris@namei.org \
    --cc=john.johansen@canonical.com \
    --cc=josh@joshtriplett.org \
    --cc=lennart@poettering.net \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-audit@redhat.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mpatel@redhat.com \
    --cc=selinux@vger.kernel.org \
    --cc=serge@hallyn.com \
    --cc=seth.forshee@canonical.com \
    --cc=smbarber@chromium.org \
    --cc=stgraber@ubuntu.com \
    --cc=tkjos@google.com \
    --cc=tycho@tycho.ws \
    --cc=tytso@mit.edu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=zohar@linux.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox