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
next prev 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