scsi: sd: improve TUR handling in sd_check_events
authorChristoph Hellwig <hch@lst.de>
Tue, 14 Feb 2017 19:15:56 +0000 (20:15 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 23 Feb 2017 00:34:17 +0000 (19:34 -0500)
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>
drivers/scsi/sd.c

index 8e4f4f72ea64479555bc4381d2bdb47a75f67a05..be535d4215c4032188bbf9f18383d8475efe1ebb 100644 (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 @@ out:
         *      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);