Skip to content

Commit

Permalink
[libata] get-identity ioctl: Fix use of invalid memory pointer
Browse files Browse the repository at this point in the history
for SAS drivers.

Caught by Ke Wei (and team?) at Marvell.

Also, move the ata_scsi_ioctl export to libata-scsi.c, as that seems to be the
general trend.

Acked-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Jeff Garzik authored and Jeff Garzik committed Jan 16, 2009
1 parent 5393f78 commit 94be9a5
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 7 deletions.
1 change: 0 additions & 1 deletion drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -6638,7 +6638,6 @@ EXPORT_SYMBOL_GPL(ata_dev_pair);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_wait_register);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
Expand Down
17 changes: 13 additions & 4 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,9 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
* RETURNS:
* Zero on success, negative errno on error.
*/
static int ata_get_identity(struct scsi_device *sdev, void __user *arg)
static int ata_get_identity(struct ata_port *ap, struct scsi_device *sdev,
void __user *arg)
{
struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
u16 __user *dst = arg;
char buf[40];
Expand Down Expand Up @@ -645,7 +645,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
return rc;
}

int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
int cmd, void __user *arg)
{
int val = -EINVAL, rc = -EINVAL;

Expand All @@ -663,7 +664,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return 0;

case HDIO_GET_IDENTITY:
return ata_get_identity(scsidev, arg);
return ata_get_identity(ap, scsidev, arg);

case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
Expand All @@ -682,6 +683,14 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)

return rc;
}
EXPORT_SYMBOL_GPL(ata_sas_scsi_ioctl);

int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
{
return ata_sas_scsi_ioctl(ata_shost_to_port(scsidev->host),
scsidev, cmd, arg);
}
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);

/**
* ata_scsi_qc_new - acquire new ata_queued_cmd reference
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/ipr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4912,7 +4912,7 @@ static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
if (res && ipr_is_gata(res)) {
if (cmd == HDIO_GET_IDENTITY)
return -ENOTTY;
return ata_scsi_ioctl(sdev, cmd, arg);
return ata_sas_scsi_ioctl(res->sata_port->ap, sdev, cmd, arg);
}

return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/libsas/sas_scsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
struct domain_device *dev = sdev_to_domain_dev(sdev);

if (dev_is_sata(dev))
return ata_scsi_ioctl(sdev, cmd, arg);
return ata_sas_scsi_ioctl(dev->sata_dev.ap, sdev, cmd, arg);

return -EINVAL;
}
Expand Down
2 changes: 2 additions & 0 deletions include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ extern void ata_host_init(struct ata_host *, struct device *,
extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
int cmd, void __user *arg);
extern void ata_sas_port_destroy(struct ata_port *);
extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
struct ata_port_info *, struct Scsi_Host *);
Expand Down

0 comments on commit 94be9a5

Please sign in to comment.