]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
compat_ioctl: scsi: handle HDIO commands from drivers
authorArnd Bergmann <arnd@arndb.de>
Sat, 30 Nov 2019 19:28:12 +0000 (20:28 +0100)
committerArnd Bergmann <arnd@arndb.de>
Fri, 3 Jan 2020 08:42:52 +0000 (09:42 +0100)
The ata_sas_scsi_ioctl() function implements a number of HDIO_* commands
for SCSI devices, it is used by all libata drivers as well as a few
drivers that support SAS attached SATA drives.

The only command that is not safe for compat ioctls here is
HDIO_GET_32BIT. Change the implementation to check for in_compat_syscall()
in order to do both cases correctly, and change all callers to use it
as both native and compat callback pointers, including the indirect
callers through sas_ioctl and ata_scsi_ioctl.

Reviewed-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
drivers/ata/libata-scsi.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
drivers/scsi/ipr.c
drivers/scsi/isci/init.c
drivers/scsi/mvsas/mv_init.c
drivers/scsi/pm8001/pm8001_init.c
include/linux/libata.h

index 58e09ffe8b9cbe034f066d22747446e25d10d3f3..eb2eb599e602303f1a4cdac487cda3f914cd9d59 100644 (file)
@@ -17,6 +17,7 @@
  *  - http://www.t13.org/
  */
 
+#include <linux/compat.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
@@ -761,6 +762,10 @@ static int ata_ioc32(struct ata_port *ap)
        return 0;
 }
 
+/*
+ * This handles both native and compat commands, so anything added
+ * here must have a compatible argument, or check in_compat_syscall()
+ */
 int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
                     unsigned int cmd, void __user *arg)
 {
@@ -773,6 +778,10 @@ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
                spin_lock_irqsave(ap->lock, flags);
                val = ata_ioc32(ap);
                spin_unlock_irqrestore(ap->lock, flags);
+#ifdef CONFIG_COMPAT
+               if (in_compat_syscall())
+                       return put_user(val, (compat_ulong_t __user *)arg);
+#endif
                return put_user(val, (unsigned long __user *)arg);
 
        case HDIO_SET_32BIT:
index f5781e31f57c6e394d62274ce96d8fc68d12bb14..d022407e5645c7166eb9f6a684bfd466f0c69b10 100644 (file)
@@ -54,6 +54,9 @@ static struct scsi_host_template aic94xx_sht = {
        .eh_target_reset_handler        = sas_eh_target_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl           = sas_ioctl,
+#endif
        .track_queue_depth      = 1,
 };
 
index 3af53cc42bd6bc1f550144f2dae09fb44c2158b6..fa25766502a23ef1a8e6eabf0ef5bd1ecae50456 100644 (file)
@@ -1772,6 +1772,9 @@ static struct scsi_host_template sht_v1_hw = {
        .eh_target_reset_handler = sas_eh_target_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl           = sas_ioctl,
+#endif
        .shost_attrs            = host_attrs_v1_hw,
        .host_reset             = hisi_sas_host_reset,
 };
index 61b1e2693b08d8264bd293254c31892dee0cb1fe..545eaff5f3ee75ea6aae6924235118daf63f7473 100644 (file)
@@ -3551,6 +3551,9 @@ static struct scsi_host_template sht_v2_hw = {
        .eh_target_reset_handler = sas_eh_target_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl           = sas_ioctl,
+#endif
        .shost_attrs            = host_attrs_v2_hw,
        .host_reset             = hisi_sas_host_reset,
 };
index bf5d5f1384374beab51145e189f93ca296fca48a..fa05e612d85a93222d1e220cdcb491b11db6f104 100644 (file)
@@ -3075,6 +3075,9 @@ static struct scsi_host_template sht_v3_hw = {
        .eh_target_reset_handler = sas_eh_target_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl           = sas_ioctl,
+#endif
        .shost_attrs            = host_attrs_v3_hw,
        .tag_alloc_policy       = BLK_TAG_ALLOC_RR,
        .host_reset             = hisi_sas_host_reset,
index 079c04bc448af9a15383526fca7a3e55d40c2a46..ae45cbe98ae23957306c700ae0a6e1e1de05493c 100644 (file)
@@ -6727,6 +6727,9 @@ static struct scsi_host_template driver_template = {
        .name = "IPR",
        .info = ipr_ioa_info,
        .ioctl = ipr_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = ipr_ioctl,
+#endif
        .queuecommand = ipr_queuecommand,
        .eh_abort_handler = ipr_eh_abort,
        .eh_device_reset_handler = ipr_eh_dev_reset,
index 1727d0c71b1235e153b7565cff1e5a29ead37b4b..b48aac8dfcb82d0ff69644c74e74e774f4bb5e5f 100644 (file)
@@ -168,6 +168,9 @@ static struct scsi_host_template isci_sht = {
        .eh_target_reset_handler        = sas_eh_target_reset_handler,
        .target_destroy                 = sas_target_destroy,
        .ioctl                          = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl                   = sas_ioctl,
+#endif
        .shost_attrs                    = isci_host_attrs,
        .track_queue_depth              = 1,
 };
index da719b0694dcc41cb2ccef8d5ff7e0576535a289..7af9173c492578f700111dbc259edcf4f1862a54 100644 (file)
@@ -47,6 +47,9 @@ static struct scsi_host_template mvs_sht = {
        .eh_target_reset_handler = sas_eh_target_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl           = sas_ioctl,
+#endif
        .shost_attrs            = mvst_host_attrs,
        .track_queue_depth      = 1,
 };
index ff618ad80ebdc3770d137fa2fd6ea00887f41ade..3c6076e4c6d2d64045758af667ce8e25d2a4e0d3 100644 (file)
@@ -101,6 +101,9 @@ static struct scsi_host_template pm8001_sht = {
        .eh_target_reset_handler = sas_eh_target_reset_handler,
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl           = sas_ioctl,
+#endif
        .shost_attrs            = pm8001_host_attrs,
        .track_queue_depth      = 1,
 };
index 2dbde119721df4b63982b3dab853ba9ab51ea822..a36bdcb8d9e92b8dbc2aba5fc07a00cc8a2d4d34 100644 (file)
@@ -1109,6 +1109,11 @@ extern void ata_host_init(struct ata_host *, struct device *, struct ata_port_op
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd,
                          void __user *arg);
+#ifdef CONFIG_COMPAT
+#define ATA_SCSI_COMPAT_IOCTL .compat_ioctl = ata_scsi_ioctl,
+#else
+#define ATA_SCSI_COMPAT_IOCTL /* empty */
+#endif
 extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
                            unsigned int cmd, void __user *arg);
@@ -1341,6 +1346,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
        .module                 = THIS_MODULE,                  \
        .name                   = drv_name,                     \
        .ioctl                  = ata_scsi_ioctl,               \
+       ATA_SCSI_COMPAT_IOCTL                                   \
        .queuecommand           = ata_scsi_queuecmd,            \
        .can_queue              = ATA_DEF_QUEUE,                \
        .tag_alloc_policy       = BLK_TAG_ALLOC_RR,             \