mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-14 15:54:15 +08:00
scsi: aacraid: Improve compat_ioctl handlers
The use of compat_alloc_user_space() can be easily replaced by handling
compat arguments in the regular handler, and this will make it work for
big-endian kernels as well, which at the moment get an invalid indirect
pointer argument.
Calling aac_ioctl() instead of aac_compat_do_ioctl() means the compat and
native code paths behave the same way again, which they stopped when the
adapter health check was added only in the native function.
Link: https://lore.kernel.org/r/20201030164450.1253641-1-arnd@kernel.org
Fixes: 572ee53a9b
("scsi: aacraid: check adapter health")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
2030745877
commit
077054215a
@ -25,6 +25,7 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/delay.h> /* ssleep prototype */
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/uaccess.h>
|
||||
@ -226,6 +227,12 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
||||
return status;
|
||||
}
|
||||
|
||||
struct compat_fib_ioctl {
|
||||
u32 fibctx;
|
||||
s32 wait;
|
||||
compat_uptr_t fib;
|
||||
};
|
||||
|
||||
/**
|
||||
* next_getadapter_fib - get the next fib
|
||||
* @dev: adapter to use
|
||||
@ -243,8 +250,19 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
||||
struct list_head * entry;
|
||||
unsigned long flags;
|
||||
|
||||
if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
|
||||
return -EFAULT;
|
||||
if (in_compat_syscall()) {
|
||||
struct compat_fib_ioctl cf;
|
||||
|
||||
if (copy_from_user(&cf, arg, sizeof(struct compat_fib_ioctl)))
|
||||
return -EFAULT;
|
||||
|
||||
f.fibctx = cf.fibctx;
|
||||
f.wait = cf.wait;
|
||||
f.fib = compat_ptr(cf.fib);
|
||||
} else {
|
||||
if (copy_from_user(&f, arg, sizeof(struct fib_ioctl)))
|
||||
return -EFAULT;
|
||||
}
|
||||
/*
|
||||
* Verify that the HANDLE passed in was a valid AdapterFibContext
|
||||
*
|
||||
|
@ -1182,63 +1182,6 @@ static long aac_cfg_ioctl(struct file *file,
|
||||
return aac_do_ioctl(aac, cmd, (void __user *)arg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long arg)
|
||||
{
|
||||
long ret;
|
||||
switch (cmd) {
|
||||
case FSACTL_MINIPORT_REV_CHECK:
|
||||
case FSACTL_SENDFIB:
|
||||
case FSACTL_OPEN_GET_ADAPTER_FIB:
|
||||
case FSACTL_CLOSE_GET_ADAPTER_FIB:
|
||||
case FSACTL_SEND_RAW_SRB:
|
||||
case FSACTL_GET_PCI_INFO:
|
||||
case FSACTL_QUERY_DISK:
|
||||
case FSACTL_DELETE_DISK:
|
||||
case FSACTL_FORCE_DELETE_DISK:
|
||||
case FSACTL_GET_CONTAINERS:
|
||||
case FSACTL_SEND_LARGE_FIB:
|
||||
ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
|
||||
break;
|
||||
|
||||
case FSACTL_GET_NEXT_ADAPTER_FIB: {
|
||||
struct fib_ioctl __user *f;
|
||||
|
||||
f = compat_alloc_user_space(sizeof(*f));
|
||||
ret = 0;
|
||||
if (clear_user(f, sizeof(*f)))
|
||||
ret = -EFAULT;
|
||||
if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32)))
|
||||
ret = -EFAULT;
|
||||
if (!ret)
|
||||
ret = aac_do_ioctl(dev, cmd, f);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aac_compat_ioctl(struct scsi_device *sdev, unsigned int cmd,
|
||||
void __user *arg)
|
||||
{
|
||||
struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
|
||||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
return aac_compat_do_ioctl(dev, cmd, (unsigned long)arg);
|
||||
}
|
||||
|
||||
static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
{
|
||||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
return aac_compat_do_ioctl(file->private_data, cmd, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t aac_show_model(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -1523,7 +1466,7 @@ static const struct file_operations aac_cfg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = aac_cfg_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = aac_compat_cfg_ioctl,
|
||||
.compat_ioctl = aac_cfg_ioctl,
|
||||
#endif
|
||||
.open = aac_cfg_open,
|
||||
.llseek = noop_llseek,
|
||||
@ -1536,7 +1479,7 @@ static struct scsi_host_template aac_driver_template = {
|
||||
.info = aac_info,
|
||||
.ioctl = aac_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = aac_compat_ioctl,
|
||||
.compat_ioctl = aac_ioctl,
|
||||
#endif
|
||||
.queuecommand = aac_queuecommand,
|
||||
.bios_param = aac_biosparm,
|
||||
|
Loading…
Reference in New Issue
Block a user