[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20200207170447.1251404-1-arnd@arndb.de>
Date: Fri, 7 Feb 2020 18:04:05 +0100
From: Arnd Bergmann <arnd@...db.de>
To: Alexander Viro <viro@...iv.linux.org.uk>
Cc: Arnd Bergmann <arnd@...db.de>,
Christian Zigotzky <chzigotzky@...osoft.de>,
youling257 <youling257@...il.com>,
Ben Hutchings <ben.hutchings@...ethink.co.uk>,
"Darrick J. Wong" <darrick.wong@...cle.com>,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH] compat_ioctl: fix FIONREAD on devices
My final cleanup patch for sys_compat_ioctl() introduced a regression on
the FIONREAD ioctl command, which is used for both regular and special
files, but only works on regular files after my patch, as I had missed
the warning that Al Viro put into a comment right above it.
Change it back so it can work on any file again by moving the implementation
to do_vfs_ioctl() instead.
Fixes: 77b9040195de ("compat_ioctl: simplify the implementation")
Reported-by: Christian Zigotzky <chzigotzky@...osoft.de>
Reported-by: youling257 <youling257@...il.com>
Signed-off-by: Arnd Bergmann <arnd@...db.de>
---
Untested so far. Christian and youling257, can you see if this patch
addresses your problems?
---
fs/ioctl.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 7c9a5df5a597..5152c98cfc30 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -523,13 +523,9 @@ static int compat_ioctl_preallocate(struct file *file, int mode,
static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
{
- struct inode *inode = file_inode(filp);
-
switch (cmd) {
case FIBMAP:
return ioctl_fibmap(filp, p);
- case FIONREAD:
- return put_user(i_size_read(inode) - filp->f_pos, p);
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
return ioctl_preallocate(filp, 0, p);
@@ -721,6 +717,13 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
case FIDEDUPERANGE:
return ioctl_file_dedupe_range(filp, argp);
+ case FIONREAD:
+ if (!S_ISREG(inode->i_mode))
+ return vfs_ioctl(filp, cmd, arg);
+
+ return put_user(i_size_read(inode) - filp->f_pos,
+ (int __user *)argp);
+
default:
if (S_ISREG(inode->i_mode))
return file_ioctl(filp, cmd, argp);
--
2.25.0
Powered by blists - more mailing lists