mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
scsi: aacraid: Improve compat_ioctl handlers
[ Upstream commit077054215a] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
92b6415e97
commit
6dd60eb9b3
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <linux/delay.h> /* ssleep prototype */
|
#include <linux/delay.h> /* ssleep prototype */
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
@@ -226,6 +227,12 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct compat_fib_ioctl {
|
||||||
|
u32 fibctx;
|
||||||
|
s32 wait;
|
||||||
|
compat_uptr_t fib;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* next_getadapter_fib - get the next fib
|
* next_getadapter_fib - get the next fib
|
||||||
* @dev: adapter to use
|
* @dev: adapter to use
|
||||||
@@ -243,8 +250,19 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
|||||||
struct list_head * entry;
|
struct list_head * entry;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
|
if (in_compat_syscall()) {
|
||||||
return -EFAULT;
|
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
|
* 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);
|
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,
|
static ssize_t aac_show_model(struct device *device,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
@@ -1523,7 +1466,7 @@ static const struct file_operations aac_cfg_fops = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.unlocked_ioctl = aac_cfg_ioctl,
|
.unlocked_ioctl = aac_cfg_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = aac_compat_cfg_ioctl,
|
.compat_ioctl = aac_cfg_ioctl,
|
||||||
#endif
|
#endif
|
||||||
.open = aac_cfg_open,
|
.open = aac_cfg_open,
|
||||||
.llseek = noop_llseek,
|
.llseek = noop_llseek,
|
||||||
@@ -1536,7 +1479,7 @@ static struct scsi_host_template aac_driver_template = {
|
|||||||
.info = aac_info,
|
.info = aac_info,
|
||||||
.ioctl = aac_ioctl,
|
.ioctl = aac_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = aac_compat_ioctl,
|
.compat_ioctl = aac_ioctl,
|
||||||
#endif
|
#endif
|
||||||
.queuecommand = aac_queuecommand,
|
.queuecommand = aac_queuecommand,
|
||||||
.bios_param = aac_biosparm,
|
.bios_param = aac_biosparm,
|
||||||
|
|||||||
Reference in New Issue
Block a user