Commit 75c0b0e1 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

compat_ioctl: scsi: handle HDIO commands from drivers



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: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 64cbfa96
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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:
+3 −0
Original line number Diff line number Diff line
@@ -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,
};

+3 −0
Original line number Diff line number Diff line
@@ -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,
};
+3 −0
Original line number Diff line number Diff line
@@ -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,
};
+3 −0
Original line number Diff line number Diff line
@@ -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,
Loading