scsi: sd: improve TUR handling in sd_check_events

Remove bogus evaluations of retval and sshdr when the device is offline,
and fix a possible NULL pointer dereference by allocating the 8 byte
sized sense header on stack.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Christoph Hellwig 2017-02-14 20:15:56 +01:00 committed by Martin K. Petersen
parent 148cff67b4
commit 6fa2b8f9e3

View File

@ -1425,7 +1425,6 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
{
struct scsi_disk *sdkp = scsi_disk_get(disk);
struct scsi_device *sdp;
struct scsi_sense_hdr *sshdr = NULL;
int retval;
if (!sdkp)
@ -1454,22 +1453,21 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
* by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever
* sd_revalidate() is called.
*/
retval = -ENODEV;
if (scsi_block_when_processing_errors(sdp)) {
sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL);
struct scsi_sense_hdr sshdr = { 0, };
retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES,
sshdr);
}
&sshdr);
/* failed to execute TUR, assume media not present */
if (host_byte(retval)) {
set_media_not_present(sdkp);
goto out;
}
/* failed to execute TUR, assume media not present */
if (host_byte(retval)) {
set_media_not_present(sdkp);
goto out;
}
if (media_not_present(sdkp, sshdr))
goto out;
if (media_not_present(sdkp, &sshdr))
goto out;
}
/*
* For removable scsi disk we have to recognise the presence
@ -1485,7 +1483,6 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
* Medium present state has changed in either direction.
* Device has indicated UNIT_ATTENTION.
*/
kfree(sshdr);
retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
sdp->changed = 0;
scsi_disk_put(sdkp);